import { MaskConfig } from '../../helpers/formatter/string-formatter/string-mask-strategy';
import { NumberMaskConfig } from '../../helpers/formatter/string-formatter/number-mask-strategy';
import { StringFormatStrategy } from '../../helpers/formatter/string-formatter/string-format-strategy.abstract';

/**
 * TODO: Need depercated this type instead of format strategy to handle user deference requirement. More info refer to https://gethired.atlassian.net/browse/VD-8523
 */
/**
 * Configuration for input masking strategies.
 */
export type MaskConfigType = {
	/**
	 * Masking strategy identifier.
	 *
	 * - 'phone': Formats input as a phone number.
	 * - 'zipcode': Formats input as a postal code.
	 * - 'taxId': Formats input as a tax identification number.
	 * - 'custom': Uses a custom formatter function provided via the `formatter` property.
	 * - 'thousand-comma': Formats numbers with thousand separators.
	 * - 'number': Formats input as a number, allowing for decimal points and negative signs.
	 * - 'custom-formatter': Uses a custom strategy provided via the `strategy` property, which should return an instance of `StringFormatStrategy`.
	 */
	type: 'phone' | 'zipcode' | 'taxId' | 'custom' | 'thousand-comma' | 'number' | 'custom-formatter';
	/**
	 * Options used by the selected mask strategy.
	 * It only work while type is 'custom' or 'number',
	 * 	for 'custom' type, options should be MaskConfig,
	 *  for 'number' type, options should be NumberMaskConfig,
	 *  for other types, options will be ignored even if it's provided.
	 */
	options?: MaskConfig | NumberMaskConfig;

	/**
	 * Whether to override the component value on blur when using 'blur' trigger.
	 * If set to true, the component value will be updated with the formatted value on blur.
	 * If false or not set, the component value will not be updated on blur, but the formatted value will still be applied to the native input.
	 */
	overrideValue?: boolean;

	/**
	 * Trigger types for maskConfig, indicating when the mask should be applied to the input field.
	 *
	 * - 'blur': The mask is applied when the input field blurs (loses focus), and it just apply the formatted value to the native input, but the component value is not updated,
	 *    if you also want to update the component value on blur, you can set `overrideValue` in options to true, then the component value will also be updated on blur.
	 * - 'input': The mask is applied on every input event (as the user types), and the value of vega-input is updated accordingly.
	 */
	trigger?: 'blur' | 'input';
	/**
	 * Optional value formatter callback.
	 * It only works when the `type` is set to 'custom-formatter'. The formatter function takes the input value as a string and returns the formatted value as a string.
	 */
	formatter?: (value: string) => string;
	/**
	 * Whether to reset the caret position after formatting.
	 * It only works when the `type` is set to 'custom-formatter'. If set to true, the caret position will be reset to the end of the input after formatting. If false or not set, the caret position will be calculated based on the changes made by the formatter function.
	 */
	resetCaretPosition?: boolean;
	/**
	 * Custom strategy factory.
	 */
	strategy?: () => StringFormatStrategy;
};

/**
 * Source event that triggered an input's value update.
 */
export type InputValueUpdateTriggeredBy = 'input' | 'change';

/**
 * HTML input types supported by the component.
 */
export type InputType = 'text' | 'email' | 'password' | 'number' | 'hidden';

/**
 * Alias for the browser's DataTransfer interface.
 * From: https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer
 */
export type DataTransferType = DataTransfer;

/**
 * From: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/autocomplete
 */
export type InputAutocompleteTypes =
	| 'on'
	| 'off'
	| 'name'
	| 'honorific-prefix'
	| 'given-name'
	| 'additional-name'
	| 'family-name'
	| 'honorific-suffix'
	| 'nickname'
	| 'email'
	| 'username'
	| 'new-password'
	| 'current-password'
	| 'one-time-code'
	| 'organization-title'
	| 'organization'
	| 'street-address'
	| 'address-line1'
	| 'address-line2'
	| 'address-line3'
	| 'address-level4'
	| 'address-level3'
	| 'address-level2'
	| 'address-level1'
	| 'country'
	| 'country-name'
	| 'postal-code'
	| 'cc-name'
	| 'cc-given-name'
	| 'cc-additional-name'
	| 'cc-family-name'
	| 'cc-family-name'
	| 'cc-number'
	| 'cc-exp'
	| 'cc-exp-month'
	| 'cc-exp-year'
	| 'cc-csc'
	| 'cc-type'
	| 'transaction-currency'
	| 'transaction-amount'
	| 'language'
	| 'bday'
	| 'bday-day'
	| 'bday-month'
	| 'bday-year'
	| 'sex'
	| 'tel'
	| 'tel-country-code'
	| 'tel-national'
	| 'tel-area-code'
	| 'tel-local'
	| 'tel-extension'
	| 'impp'
	| 'url'
	| 'photo';

/**
 * From: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/enterkeyhint
 */
export type InputEnterKeyHintTypes = 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';

/**
 * Dropdown configuration for input suggestions.
 */
export type VegaInputSuggestionsDropdownConfig = Partial<
	Pick<HTMLVegaDropdownElement, 'caseSensitive' | 'itemDisplayRule' | 'isLoading' | 'searchNoResultsText'>
>;
