import React from 'react';
// import { useArgs } from '@storybook/preview-api';
import type { Meta, StoryObj } from '@storybook/react';
import { ComboboxOptions, default as ComboboxComponent } from './Combobox';
import { EnvironmentBadgeDevIcon, EnvironmentBadgePrdIcon, EnvironmentBadgeStgIcon } from '../../icons/Icons';
import { Tooltip } from '../../overlays/Tooltip/Tooltip';

const meta: Meta<typeof ComboboxComponent> = {
	title: 'Inputs/Combobox',
	component: ComboboxComponent,
	render: (args) => {
		return (
			<div style={{ minHeight: '300px' }}>
				<ComboboxComponent {...args} />
			</div>
		);
	},
};

export default meta;

type Story = StoryObj<typeof ComboboxComponent>;

const mockedRequest = (data: any, timeout: number = 3000): Promise<ComboboxOptions> => {
	return new Promise((resolve) => {
		setTimeout(() => {
			resolve(data);
		}, timeout);
	});
};

const optionsOfStrings = ['one', 'two', 'three'];

export const Minimal: Story = {
	args: {
		id: 'the-code-told-me-to',
		onChange: (e) => console.log(e),
		optionsLoader: undefined, // TODO: If not explicitly set, storybook bombs because it polyfills this as an action. Need to move to arg validation, or something.
		'aria-label': "A Combobox description.",
	},
};

export const MinimalOptionsArrayNoOptions: Story = {
	args: {
		id: 'the-code-told-me-to',
		onChange: (e) => console.log(e),
		options: [], // // TODO: if we don't set options, storybook will set this as an action which gives some odd UX for the default behavoir. On the other hand, explicitly setting options to an empty array makes the combobox disabled.
		optionsLoader: undefined,
		'aria-label': "A Combobox description.",
	},
};

export const MinimalOptionsArray: Story = {
	args: {
		id: 'the-code-told-me-to',
		onChange: (e) => console.log(e),
		optionsLoader: undefined,
		options: optionsOfStrings,
		'aria-label': "A Combobox description.",
	},
};

export const MinimalOptionsDisabled: Story = {
	args: {
		id: 'minimal-options-disabled',
		options: optionsOfStrings,
		onChange: () => console.log('onChange'),
		disabled: true,
		placeholder: 'Select an option...',
		optionsLoader: undefined,
		'aria-label': "A Combobox description.",
	},
};

export const MinimalOptionsDisabledWithTooltip: Story = {
	args: {
		id: 'DisabledWithTooltip',
		container: { element: <Tooltip content={<>This combobox is disabled</>} showDelay={300} /> },
		options: optionsOfStrings,
		onChange: () => console.log('onChange'),
		disabled: true,
		placeholder: 'Select an option...',
		optionsLoader: undefined,
		'aria-label': "A Combobox description.",
	},
};

export const MinimalOptionsInvalid: Story = {
	args: {
		id: 'minimal-options-invalid',
		invalid: true,
		options: optionsOfStrings,
		onChange: (e) => console.log(e),
		placeholder: 'Select an option...',
		invalidMessage: 'Sample error message',
		optionsLoader: undefined,
		'aria-label': "A Combobox description.",
	},
};

export const ObjectOptionsBasic: Story = {
	args: {
		id: 'object-options-basic',
		onChange: (option) => console.log(option),
		options: {
			a: 'Example A',
			b: 'Example B',
		},
		// setting the value to a key in the options object uses the object's value
		value: 'b',
		optionsLoader: undefined,
		'aria-label': "A Combobox description.",
	},
};

export const OptionGroups: Story = {
	args: {
		id: 'OptionGroupsStriped',
		optionGroups: {
			separate: {
				label: 'Separate Items',
			},
			active: {
				label: 'Active Items',
				linkText: 'Learn More',
				href: ' ',
			},
			inactive: {
				label: 'Inactive Items',
			},
		},
		options: {
			a: {
				label: 'Item A',
				optionGroup: 'active',
			},
			b: {
				disabled: true,
				label: 'Item B',
				optionGroup: 'inactive',
				secondaryText: '(deactivated)',
			},
			c: {
				label: 'Item C',
				optionGroup: 'active',
			},
			d: {
				label: 'Item D',
				optionGroup: 'active',
			},
			e: {
				label: 'Item E',
				optionGroup: 'active',
			},
			f: {
				label: 'Item F',
				optionGroup: 'separate',
			},
			g: {
				label: 'Item G',
				optionGroup: 'separate',
			},
			h: {
				label: 'Item H',
				optionGroup: 'separate',
			},
		},
		onChange: () => console.log('onChange'),
		placeholder: 'Select Something!',
		striped: true,
		optionsLoader: undefined,
		'aria-label': "A Combobox description.",
	},
};

export const BasicLoaderWithOptions: Story = {
	args: {
		id: 'the-code-told-me-to',
		onChange: (e) => console.log(e),
		optionsLoader: () => mockedRequest(optionsOfStrings),
		'aria-label': "A Combobox description.",
	},
};

const EnableEnvLink = ({ label, url }: { label: string; url: string }) => {
	const handleOnClick = (e: any) => {
		e.stopPropagation();
	};
	return (
		<a href={url} onClick={handleOnClick}>
			{label}
		</a>
	);
};

const optionsWpeEnvironments: ComboboxOptions = {
	production: {
		icon: <EnvironmentBadgePrdIcon id="wpe-env-select-production-icon" width={44} height={24} />,
		label: 'Production',
	},
	staging: {
		disabled: true,
		icon: <EnvironmentBadgeStgIcon id="wpe-env-select-staging-icon" width={44} height={24} />,
		label: 'Staging',
		secondaryText: <EnableEnvLink url="https://example.com" label="Enable Staging" />,
	},
	development: {
		icon: <EnvironmentBadgeDevIcon id="wpe-env-select-development-icon" width={44} height={24} />,
		label: 'Development',
	},
};

export const BasicLoaderWpeEnvironments: Story = {
	args: {
		id: 'the-code-told-me-to',
		onChange: (e) => console.log(e),
		optionsLoader: () => mockedRequest(optionsWpeEnvironments),
		// TODO: I would have thought that loadingOptionsPlaceholder would be replaced once optionsLoader resolved, but it didn't. Need to figure out the right way of doing this.
		loadingOptionsPlaceholder: 'Loading environments...',
		// showOptionIconWhenSelected: true,
		emptyPlaceholder: 'No environments available',
		placeholder: 'Select environment',
		striped: true,
		'aria-label': "A Combobox description.",
	},
};
