/**
 * SidebarCalendar TypeScript Definitions v1.0.0
 */

export type CalendarMode = 'day' | 'week' | 'range';

export type CalendarLocale = 'ru-RU' | 'en-US' | string;

export interface CalendarOptions {
  /** Calendar selection mode */
  mode?: CalendarMode;
  
  /** Locale for date formatting */
  locale?: CalendarLocale;
  
  /** Minimum selectable date */
  minDate?: Date;
  
  /** Maximum selectable date */
  maxDate?: Date;
  
  /** Array of disabled dates */
  disabledDates?: Date[];
  
  /** Legacy callback for date selection (deprecated, use .on() instead) */
  onDateSelect?: (data: DateSelectEvent) => void;
  
  /** Legacy callback for week selection (deprecated, use .on() instead) */
  onWeekSelect?: (data: WeekSelectEvent) => void;
  
  /** Legacy callback for range selection (deprecated, use .on() instead) */
  onRangeSelect?: (data: RangeSelectEvent) => void;
}

export interface BaseEvent {
  type: string;
}

export interface DateSelectEvent extends BaseEvent {
  type: 'day';
  date: Date;
  formatted: string;
}

export interface WeekSelectEvent extends BaseEvent {
  type: 'week';
  start: Date;
  end: Date;
  formatted: string;
}

export interface RangeStartEvent extends BaseEvent {
  type: 'rangeStart';
  date: Date;
  formatted: string;
}

export interface RangeSelectEvent extends BaseEvent {
  type: 'range';
  start: Date;
  end: Date;
  formatted: string;
}

export interface ClearEvent extends BaseEvent {
  type: 'clear';
}

export interface NavigateEvent extends BaseEvent {
  type: 'navigate';
  direction: number;
  date: Date;
}

export interface DestroyEvent extends BaseEvent {
  type: 'destroy';
}

export type CalendarEvent = 
  | DateSelectEvent 
  | WeekSelectEvent 
  | RangeStartEvent 
  | RangeSelectEvent 
  | ClearEvent
  | NavigateEvent
  | DestroyEvent;

export type EventCallback<T extends CalendarEvent = CalendarEvent> = (data: T) => void;

export interface WeekRange {
  start: Date;
  end: Date;
}

export interface DateRange {
  start: Date | null;
  end: Date | null;
}

export type SelectedValue = Date | WeekRange | DateRange | null;

export interface SidebarCalendarStatic {
  /** Library version */
  readonly version: string;
  
  /** Constructor */
  new(container: string | HTMLElement, options?: CalendarOptions): SidebarCalendar;
}

export interface SidebarCalendar {
  /** Current calendar mode */
  readonly mode: CalendarMode;
  
  /** Current locale */
  readonly locale: CalendarLocale;
  
  /** Current displayed date */
  readonly currentDate: Date;
  
  /** Minimum selectable date */
  readonly minDate: Date | null;
  
  /** Maximum selectable date */
  readonly maxDate: Date | null;
  
  /** Array of disabled dates */
  disabledDates: Date[];
  
  /**
   * Subscribe to calendar events
   * @param event Event name
   * @param callback Callback function
   * @returns Calendar instance for chaining
   */
  on<T extends CalendarEvent>(event: T['type'], callback: EventCallback<T>): this;
  on(event: 'dateSelect', callback: EventCallback<DateSelectEvent>): this;
  on(event: 'weekSelect', callback: EventCallback<WeekSelectEvent>): this;
  on(event: 'rangeStart', callback: EventCallback<RangeStartEvent>): this;
  on(event: 'rangeSelect', callback: EventCallback<RangeSelectEvent>): this;
  on(event: 'clear', callback: EventCallback<ClearEvent>): this;
  on(event: 'navigate', callback: EventCallback<NavigateEvent>): this;
  on(event: 'destroy', callback: EventCallback<DestroyEvent>): this;
  
  /**
   * Unsubscribe from calendar events
   * @param event Event name
   * @param callback Callback function to remove
   * @returns Calendar instance for chaining
   */
  off<T extends CalendarEvent>(event: T['type'], callback: EventCallback<T>): this;
  off(event: 'dateSelect', callback: EventCallback<DateSelectEvent>): this;
  off(event: 'weekSelect', callback: EventCallback<WeekSelectEvent>): this;
  off(event: 'rangeStart', callback: EventCallback<RangeStartEvent>): this;
  off(event: 'rangeSelect', callback: EventCallback<RangeSelectEvent>): this;
  off(event: 'clear', callback: EventCallback<ClearEvent>): this;
  off(event: 'navigate', callback: EventCallback<NavigateEvent>): this;
  off(event: 'destroy', callback: EventCallback<DestroyEvent>): this;
  
  /**
   * Navigate to previous/next month
   * @param direction Direction (-1 for previous, 1 for next)
   */
  navigate(direction: number): void;
  
  /**
   * Get currently selected value
   * @returns Selected date, week range, or date range depending on mode
   */
  getSelected(): SelectedValue;
  
  /**
   * Set selected date (day mode only)
   * @param date Date to select
   */
  setDate(date: Date | string): void;
  
  /**
   * Set selected week (week mode only)
   * @param date Date within the week to select
   */
  setWeek(date: Date | string): void;
  
  /**
   * Set selected range (range mode only)
   * @param start Start date
   * @param end End date
   */
  setRange(start: Date | string, end: Date | string): void;
  
  /**
   * Clear all selections
   */
  clear(): void;
  
  /**
   * Navigate to specific month/year
   * @param date Date to navigate to
   */
  goToDate(date: Date | string): void;
  
  /**
   * Execute quick actions
   * @param action Action name
   */
  quickAction(action: 'today' | 'tomorrow' | 'thisWeek' | 'nextWeek' | 'thisMonth' | 'lastWeek' | 'clear'): void;
  
  /**
   * Re-render the calendar
   */
  render(): void;
  
  /**
   * Destroy the calendar instance
   */
  destroy(): void;
}

declare const SidebarCalendar: SidebarCalendarStatic;

export default SidebarCalendar;

// Global declaration for UMD builds
declare global {
  interface Window {
    SidebarCalendar: SidebarCalendarStatic;
  }
}

// Utility types for advanced usage
export namespace SidebarCalendarTypes {
  export type Mode = CalendarMode;
  export type Locale = CalendarLocale;
  export type Options = CalendarOptions;
  export type Event = CalendarEvent;
  export type Callback<T extends CalendarEvent = CalendarEvent> = EventCallback<T>;
  export type Selected = SelectedValue;
  export type Week = WeekRange;
  export type Range = DateRange;
  
  // Event type guards
  export function isDateSelectEvent(event: CalendarEvent): event is DateSelectEvent;
  export function isWeekSelectEvent(event: CalendarEvent): event is WeekSelectEvent;
  export function isRangeSelectEvent(event: CalendarEvent): event is RangeSelectEvent;
  export function isRangeStartEvent(event: CalendarEvent): event is RangeStartEvent;
  export function isClearEvent(event: CalendarEvent): event is ClearEvent;
  export function isNavigateEvent(event: CalendarEvent): event is NavigateEvent;
  export function isDestroyEvent(event: CalendarEvent): event is DestroyEvent;
}