import { BackgroundColorsTokenType } from '../../types/design-token.type';
import { CalendarEvent } from '../../helpers/calendar/calendar-event';
import { DropdownSourceGroup, DropdownSourceItem } from '../vega-dropdown/types';

/**
 * Available view modes for the calendar component.
 */
export type VegaCalendarViewModeType = 'month' | 'week' | 'day';

/**
 * Simple representation of a calendar date.
 */
export type VegaCalendarDateType = {
	/**
	 * Day of the month.
	 */
	date: number;
	/**
	 * Month number (0‑indexed?).
	 */
	month: number;
	/**
	 * Full year number.
	 */
	year: number;
};

/**
 * Payload for events emitted when the calendar's view period changes.
 */
export type VegaCalendarChangeEventType = {
	/**
	 * The newly visible period on the calendar.
	 */
	currentPeriod: VegaCalendarCurrentPeriodType;
	/**
	 * The active calendar view mode.
	 */
	viewMode: VegaCalendarViewModeType;
};

/**
 * Describes the currently visible period on the calendar.
 */
export type VegaCalendarCurrentPeriodType = {
	/**
	 * The year of the current period.
	 */
	year: number;
	/**
	 * The month of the current period.
	 */
	month: number;
	/**
	 * The first date included in the period.
	 */
	startDate: VegaCalendarDateType;
	/**
	 * The last date included in the period.
	 */
	endDate: VegaCalendarDateType;
};

/**
 * Frequency options for repeating calendar events.
 */
export type VegaCalendarEventRepeatType = 'daily' | 'weekly' | 'monthly' | 'yearly';

/**
 * Variant styles that can be applied to calendar events.
 */
export type VegaCalendarEventVariantType = 'primary' | 'secondary' | 'tertiary';

export interface VegaCalendarRawEvent {
	/**
	 * Unique identifier for the event.
	 */
	key: string;
	/**
	 * Title displayed for the event.
	 */
	title: string;
	/**
	 * Visual variant applied to the event.
	 */
	variant?: VegaCalendarEventVariantType;
	/**
	 * Start date or date-time for the event.
	 */
	startDate: string | Date;
	/**
	 * Optional end date or date-time for the event.
	 */
	endDate?: string | Date;
	/**
	 * Optional start time string.
	 */
	startTime?: string;
	/**
	 * Optional end time string.
	 */
	endTime?: string;
	/**
	 * Whether the event spans the full day.
	 */
	isAllDay?: boolean;
	/**
	 * This color also supports {@link BackgroundColorsTokenType} expect string
	 */
	color?: string | BackgroundColorsTokenType;
	/**
	 * Whether the event is disabled.
	 */
	disabled?: boolean;
	/**
	 * Repeat configuration for the event.
	 */
	repeatOptions?: VegaCalendarEventRepeatOptions;
}

/**
 * Information provided when a calendar event is clicked.
 */
export type VegaCalendarEventClickInfo = {
	/**
	 * The raw event data that was clicked.
	 */
	rawEvent: VegaCalendarRawEvent;
};

/**
 * Information provided when a calendar event is edited.
 */
export type VegaCalendarEventEditInfo = {
	/**
	 * The raw event data that was edited.
	 */
	rawEvent: VegaCalendarRawEvent;
	/**
	 * The date associated with the event being edited.
	 */
	date: VegaCalendarDateType;
};

/**
 * Click info when a calendar date cell is clicked, including time.
 */
export type VegaCalendarDateClickInfo = VegaCalendarDateType & {
	/**
	 * Hour value for the clicked time slot.
	 */
	hour: number;
	/**
	 * Minimal mouse event information.
	 */
	mouseEventInfo: VegaMouseEventInfo;
};

/**
 * CSS style object used for positioning calendar event elements.
 */
export type VegaCalendarEventStyle = {
	/**
	 * CSS position type for the event element.
	 */
	position: 'absolute';
	/**
	 * Left offset value.
	 */
	left: string;
	/**
	 * Top offset value.
	 */
	top: string;
	/**
	 * Width of the event element.
	 */
	width: string;
	/**
	 * Optional height of the event element.
	 */
	height?: string;
	/**
	 * Optional z-index value.
	 */
	zIndex?: string;
	/**
	 * Optional opacity value.
	 */
	opacity?: string;
};

/**
 * Layout information for rendering a full-day calendar event.
 */
export type VegaCalendarFullDayEventView = {
	/**
	 * The event associated with the view.
	 */
	event: CalendarEvent;
	/**
	 * Start index or position within the full-day layout.
	 */
	start: number;
	/**
	 * End index or position within the full-day layout.
	 */
	end: number;
};

/**
 * Abbreviated weekday names used by the calendar.
 */
export type VegaCalendarWeekDayType = 'Sun' | 'Mon' | 'Tue' | 'Wed' | 'Thu' | 'Fri' | 'Sat';

/**
 * Detailed repeat configuration for calendar events.
 */
export type VegaCalendarEventRepeatOptions = {
	/**
	 * Base repeat frequency for the event.
	 */
	frequency: VegaCalendarEventRepeatType;
	/**
	 * Optional interval multiplier for the frequency.
	 */
	interval?: number;
	/**
	 * Optional maximum occurrence count.
	 */
	count?: number;
	/**
	 * Optional end date for repeating.
	 */
	until?: string | Date;
	/**
	 * Specific weekdays for repeating events.
	 */
	byWeekDay?: VegaCalendarWeekDayType[];
};

/**
 * Dropdown configuration used by calendar components.
 */
export type DropdownPropsForCalendar = {
	/**
	 * Whether the dropdown should match container height.
	 */
	matchContainerHeight?: boolean;
	/**
	 * Whether the dropdown should match the trigger width.
	 */
	matchTargetWidth?: boolean;
	/**
	 * Maximum dropdown height in pixels.
	 */
	maxHeight?: number;
	/**
	 * Element selector or reference for positioning.
	 */
	positionRelativeTo?: string;
	/**
	 * Interaction that opens the dropdown.
	 */
	trigger?: 'hover' | 'click';
	/**
	 * Dropdown items used as the source.
	 */
	source: (DropdownSourceGroup | DropdownSourceItem)[];
};

/**
 * Minimal mouse event coordinates used throughout the calendar.
 */
export type VegaMouseEventInfo = {
	/**
	 * Mouse client X coordinate.
	 */
	clientX: number;
	/**
	 * Mouse client Y coordinate.
	 */
	clientY: number;
};

/**
 * Predicate used to disable certain calendar dates.
 */
export type DisabledDate = (date: Date) => boolean;

/**
 * Structure representing hour and minute components of a time.
 */
export type CalendarTimeHourMinutes = {
	/**
	 * Hour component of the time.
	 */
	timeHours: number;
	/**
	 * Minute component of the time.
	 */
	timeMinutes: number;
};

/**
 * Actions that can be performed on a calendar event, such as showing an edit button.
 */
export type CalendarEventActions = {
	/**
	 * Whether to show an edit button in the event preview popover.
	 */
	showEditButton?: boolean;
};

/**
 * Callback type for generating actions related to a calendar event, such as determining whether to show an edit button in the event preview popover.
 */
export type CalendarEventActionsCallback = (
	event: VegaCalendarRawEvent,
	date: VegaCalendarDateType,
) => CalendarEventActions;
