import { AvailableSvgs } from '@noventi/svgs';
import { AtomImageProps } from '@src/elements/atoms/a-image/a-image.types';
import { AtomBadgeProps } from '@src/elements/atoms/a-badge/a-badge.types';

export enum ContainerBorder {
	BOTTOM = 'c-container--border-bottom',
	TOP = 'c-container--border-top',
}

export enum ContainerTheme {
	DARK = 'theme-dark',
	LIGHT = 'theme-light',
}

export enum ContainerBgColor {
	DEFAULT = 'b-container--style-default',
	ACCENT = 'b-container--style-accent',
	PRIMARY_CONTAINER = 'b-container--style-primary-container',
	SECONDARY_CONTAINER = 'b-container--style-secondary-container',
	GRADIENT_PDTT = 'b-container--style-gradient-pdtt',
}

export enum ContainerVariants {
	DEFAULT = 'b-container--default',
	OFFSET = 'b-container--offset',
	LARGE = 'b-container--large',
	FULL_WIDTH = 'b-container--full-width',
	BOXED = 'b-container--boxed',
	BOXED_SMALL = 'b-container--boxed-small',
	D_DEFAULT_M_FULL_WIDTH = 'b-container--d-default-m-full-width',
}

export enum ContainerSpacingTop {
	SMALLER = 'b-container--spacing-smaller-top',
	SMALL = 'b-container--spacing-small-top',
	MEDIUM = 'b-container--spacing-medium-top',
	LARGE = 'b-container--spacing-large-top',
}

export enum ContainerSpacingBottom {
	SMALLER = 'b-container--spacing-smaller-bottom',
	SMALL = 'b-container--spacing-small-bottom',
	MEDIUM = 'b-container--spacing-medium-bottom',
	LARGE = 'b-container--spacing-large-bottom',
}

/** Component container, it defines how to render bricks/components in the dom */
export type BrickContainerProps = {
	variant?: ContainerVariants;
	theme?: ContainerTheme;
	spacingTop?: ContainerSpacingTop;
	spacingBottom?: ContainerSpacingBottom;
	bgImage?: AtomImageProps;
	bgColor?: string;
	border?: ContainerBorder;
};

/**
 * This is the base structure for all atoms, molecules, organisms, pages and templates.
 * Also see: `src/base/models/base.twig`
 */
export type Component<T = unknown> = T & {
	config?: {
		[K in string]: string | number | boolean;
	};
	/**
	 * A list of modifiers that a component can have
	 */
	modifiers?: string[];
	/**
	 * A list of classes that a component can have
	 */
	componentClassNames?: Record<string, string[] | string>;
	/**
	 * Atrributes, like
	 * attributes = {
	 *    someval: 'myvalue',
	 *    someother: ['class combo one', 'class block two'],
	 * }
	 */
	attributes?: {
		[K in string]: string | number | boolean;
	};
	/**
	 * Data atrributes on the element, like
	 * dataAttributes = {
	 *    myname: 'myvalue',
	 *    myname2: 'myvalue2',
	 * }
	 */
	dataAttributes?: {
		[K in string]: string | number | boolean;
	};
};

/** Button Link Base Props */

export type ButtonLinkBaseProps<T> = Component<T> & {
	/**
	 * The hierarchy of the button
	 * @default primary
	 */
	hierarchy?: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error';
	/**
	 * The variant of the button
	 * @default filled
	 */
	variant?: 'filled' | 'tonal' | 'outlined' | 'ghost' | 'text' | 'anchor' | 'unstyled';
	/**
	 * The size of the button
	 * @default md
	 */
	size?: 'sm' | 'md' | 'lg';
	/**
	 * Add an icon inside the button
	 */
	icon?: {
		/** icon name */
		name: AvailableSvgs;
		/** icon position */
		position?: 'left' | 'right';
	};
	/**
	 * Add a badge anchored to the button
	 * @default primary - sm
	 * */
	badge?: AtomBadgeProps;
};

/**
 * Base interface of all bricks
 */
export type Brick<T = unknown> = Component<T> & {
	/**
	 * Component Container, it defines how to render bricks/components in the dom
	 * @twigComponentProps
	 */
	brickContainer?: BrickContainerProps;
	/**
	 * Used to set anchor tags for jumpmarks
	 */
	jumpmarkAnchorId?: string;
};

export enum ResponsiveGaps {
	SM = 'r-gap-sm',
	MD = 'r-gap-md',
	LG = 'r-gap-lg',
}

/**
 * The instance of the component when implementing component docs
 * Use like this:
 *
 *	export const Button: ComponentElement<AtomButtonProps> = (props: AtomButtonProps) => template({ ...props })}
 *	Button.sourceCode = templateSource;
 *	Button.defaultData = defaultAtomButtonProps;
 */
export type ComponentDocs<T> = {
	/** Support Lit/Twig Render */
	(args: T): Element | string;
	sourceCode: (variables?: any | unknown) => string;
	/** (Optional) Example data which is passed through to use on the story default */
	defaultData: T;
};

/** The component event type for components emitting events for other listening components */
export type ComponentEvents = Record<string, string>;

// ####################################################
// Abstract Interfaces to help with Pimcore integration
// ####################################################

export type AspectRatio = '1/1' | '4/3' | '16/9' | '21/9' | '9/16' | '9/21';

/**
 * An anchor type
 */
export type Anchor = {
	href: string;
	text?: string;
	title?: string;
	target?: string;
	download?: string | boolean;
	name?: string;
};

/**
 * A select type
 */
type SelectStoreValue = string | number | boolean | null;

export type Select = {
	/** The form control name */
	name: string;
	/** The list of select options */
	store: Record<string, SelectStoreValue>[];
	/** A class or classes to be applied to the select */
	class?: string;
	/** Default selected value */
	defaultValue?: string;
	/** Currently selected value */
	selectedValue?: string;
};
