/**
 * Mawidi Demo Scheduler - TypeScript Type Definitions
 * Complete type system for the scheduling component
 */

// ============================================================================
// CORE SCHEDULING TYPES
// ============================================================================

/**
 * Time slot representation with availability status
 */
export interface TimeSlot {
  /** Time in HH:mm format (24-hour) */
  time: string;
  /** ISO 8601 datetime string */
  dateTime: string;
  /** Whether this slot is currently available */
  available: boolean;
  /** Optional reason for unavailability */
  unavailableReason?: "past" | "booked" | "outside-hours" | "too-soon";
}

/**
 * Available booking date with metadata
 */
export interface BookingDate {
  /** JavaScript Date object */
  date: Date;
  /** ISO 8601 date string (YYYY-MM-DD) */
  dateString: string;
  /** Number of available slots on this date */
  availableSlots: number;
  /** Day of week (0 = Sunday) */
  dayOfWeek: number;
  /** Whether this date is within booking window */
  bookable: boolean;
}

/**
 * User contact information from booking form
 */
export interface UserInfo {
  /** Full name */
  name: string;
  /** Email address (RFC 5322 compliant) */
  email: string;
  /** Optional phone number (international format) */
  phone?: string;
  /** Additional message or notes */
  message: string;
  /** User's timezone (IANA timezone identifier) */
  timezone: string;
}

/**
 * Complete booking data combining all selection steps
 */
export interface BookingData {
  /** Selected meeting duration in minutes */
  meetingDuration: 30 | 60;
  /** Selected date */
  selectedDate: Date;
  /** Selected time in HH:mm format */
  selectedTime: string;
  /** Timezone for the booking */
  timezone: string;
  /** User contact information */
  userInfo: UserInfo;
  /** Combined datetime in ISO 8601 format */
  selectedDateTime?: string;
  /** Unique booking identifier */
  bookingId?: string;
  /** Timestamp when booking was created */
  createdAt?: string;
}

// ============================================================================
// STATE MANAGEMENT
// ============================================================================

/**
 * Main scheduler state
 */
export interface SchedulerState {
  /** Current step in the booking flow (1-6) */
  currentStep: number;
  /** Selected meeting duration */
  selectedDuration: 30 | 60 | null;
  /** Selected booking date */
  selectedDate: Date | null;
  /** Selected time slot */
  selectedTime: string | null;
  /** User contact information */
  userInfo: UserInfo | null;
  /** Available time slots for selected date */
  availableSlots: TimeSlot[];
  /** Loading state indicator */
  loading: boolean;
  /** Error message if any */
  error: string | null;
  /** Success state after booking */
  success: boolean;
  /** Booking confirmation data */
  confirmation: BookingData | null;
}

/**
 * Persisted form state for localStorage
 */
export interface PersistedFormState {
  /** State data */
  state: Partial<SchedulerState>;
  /** Timestamp when saved */
  timestamp: number;
  /** Schema version for migration */
  version: string;
}

// ============================================================================
// CONFIGURATION TYPES
// ============================================================================

/**
 * Working hours configuration for a single day
 */
export interface WorkingHours {
  /** Start time in HH:mm format */
  start: string;
  /** End time in HH:mm format */
  end: string;
  /** Timezone identifier */
  timezone: string;
}

/**
 * Weekly working hours schedule
 */
export interface WeeklySchedule {
  sunday: WorkingHours;
  monday: WorkingHours;
  tuesday: WorkingHours;
  wednesday: WorkingHours;
  thursday: WorkingHours;
  friday: WorkingHours;
  saturday: WorkingHours;
}

/**
 * Complete scheduler configuration
 */
export interface SchedulerConfig {
  /** Working hours by day of week */
  workingHours: WeeklySchedule;
  /** Available meeting durations in minutes */
  meetingDurations: Array<30 | 60>;
  /** Minimum hours in advance for booking */
  minAdvanceBookingHours: number;
  /** Maximum days in advance for booking */
  maxAdvanceBookingDays: number;
  /** n8n webhook URL */
  n8nWebhookUrl: string;
  /** Demo mode flag */
  demoMode: boolean;
  /** Default timezone */
  timezone: string;
  /** Business hours configuration (alias for workingHours) */
  businessHours: WeeklySchedule;
  /** Time slot interval in minutes */
  slotInterval: number;
}

// ============================================================================
// N8N INTEGRATION TYPES
// ============================================================================

/**
 * Metadata sent with booking
 */
export interface BookingMetadata {
  /** Browser user agent string */
  userAgent: string;
  /** Client IP address (if available) */
  ipAddress?: string;
  /** Selected language */
  language: "en" | "ar";
  /** Screen resolution */
  screenResolution?: string;
  /** Referrer URL */
  referrer?: string;
}

/**
 * Complete payload sent to n8n webhook
 */
export interface N8NPayload {
  /** Unique booking identifier */
  bookingId: string;
  /** User's full name */
  name: string;
  /** User's email address */
  email: string;
  /** User's phone number (optional) */
  phone?: string;
  /** User's message or notes */
  message: string;
  /** Meeting duration in minutes */
  meetingDuration: 30 | 60;
  /** Selected date in YYYY-MM-DD format */
  selectedDate: string;
  /** Selected time in HH:mm format */
  selectedTime: string;
  /** Complete datetime in ISO 8601 format */
  selectedDateTime: string;
  /** User's timezone */
  timezone: string;
  /** Creation timestamp in ISO 8601 format */
  createdAt: string;
  /** Additional metadata */
  metadata: BookingMetadata;
}

/**
 * Response from n8n webhook
 */
export interface N8NResponse {
  /** Whether the booking was successful */
  success: boolean;
  /** Booking identifier (if successful) */
  bookingId?: string;
  /** Meeting link (e.g., Zoom, Teams) */
  meetingLink?: string;
  /** Error message (if failed) */
  error?: string;
  /** HTTP status code */
  statusCode?: number;
}

// ============================================================================
// COMPONENT PROPS
// ============================================================================

/**
 * Common props for all scheduler components
 */
export interface BaseComponentProps {
  /** Current language */
  language: "en" | "ar";
  /** Optional CSS class name */
  className?: string;
}

/**
 * Props for DemoScheduler main component
 */
export interface DemoSchedulerProps extends BaseComponentProps {
  /** n8n webhook URL (can override config) */
  webhookUrl?: string;
  /** Initial step to start from */
  initialStep?: number;
  /** Callback when booking is complete */
  onComplete?: (booking: BookingData) => void;
  /** Callback when user cancels */
  onCancel?: () => void;
}

/**
 * Props for StepIndicator component
 */
export interface StepIndicatorProps extends BaseComponentProps {
  /** Current step number (1-6) */
  currentStep: number;
  /** Total number of steps */
  totalSteps: number;
  /** Array of step labels */
  stepLabels: string[];
}

/**
 * Props for DurationSelector component
 */
export interface DurationSelectorProps extends BaseComponentProps {
  /** Currently selected duration */
  selectedDuration: 30 | 60 | null;
  /** Available durations */
  availableDurations: Array<30 | 60>;
  /** Callback when duration is selected */
  onSelect: (duration: 30 | 60) => void;
}

/**
 * Props for CalendarView component
 */
export interface CalendarViewProps extends BaseComponentProps {
  /** Currently selected date */
  selectedDate: Date | null;
  /** Array of available dates */
  availableDates: BookingDate[];
  /** Callback when date is selected */
  onDateSelect: (date: Date) => void;
  /** Currently selected duration (affects availability) */
  selectedDuration: 30 | 60;
}

/**
 * Props for TimeSlotPicker component
 */
export interface TimeSlotPickerProps extends BaseComponentProps {
  /** Selected date */
  date: Date;
  /** Meeting duration */
  duration: 30 | 60;
  /** Available time slots */
  timeSlots: TimeSlot[];
  /** Currently selected time */
  selectedTime: string | null;
  /** Callback when time slot is selected */
  onSelect: (time: string) => void;
  /** Loading state */
  loading?: boolean;
}

/**
 * Props for BookingForm component
 */
export interface BookingFormProps extends BaseComponentProps {
  /** Initial form values */
  initialValues?: Partial<UserInfo>;
  /** Callback when form is submitted */
  onSubmit: (userInfo: UserInfo) => void;
  /** Callback to go back */
  onBack: () => void;
  /** Loading state during submission */
  loading?: boolean;
  /** Error message */
  error?: string | null;
}

/**
 * Props for ConfirmationStep component
 */
export interface ConfirmationStepProps extends BaseComponentProps {
  /** Complete booking data to confirm */
  bookingData: Omit<BookingData, "bookingId" | "createdAt">;
  /** Callback to confirm and submit */
  onConfirm: () => void;
  /** Callback to go back and edit */
  onEdit: () => void;
  /** Loading state during submission */
  loading?: boolean;
}

/**
 * Props for SuccessMessage component
 */
export interface SuccessMessageProps extends BaseComponentProps {
  /** Complete booking confirmation data */
  booking: BookingData;
  /** Optional meeting link from n8n */
  meetingLink?: string;
  /** Callback to book another meeting */
  onBookAnother: () => void;
}

/**
 * Props for LoadingSpinner component
 */
export interface LoadingSpinnerProps {
  /** Size variant */
  size?: "sm" | "md" | "lg";
  /** Optional loading message */
  message?: string;
}

// ============================================================================
// UTILITY TYPES
// ============================================================================

/**
 * Validation result for form fields
 */
export interface ValidationResult {
  /** Whether validation passed */
  valid: boolean;
  /** Error message if validation failed */
  error?: string;
}

/**
 * Form field errors
 */
export interface FormErrors {
  name?: string;
  email?: string;
  phone?: string;
  message?: string;
  duration?: string;
  date?: string;
  time?: string;
  submit?: string;
}

/**
 * Date range for availability checking
 */
export interface DateRange {
  /** Start date */
  start: Date;
  /** End date */
  end: Date;
}

/**
 * Timezone information
 */
export interface TimezoneInfo {
  /** IANA timezone identifier */
  identifier: string;
  /** Timezone offset in minutes */
  offset: number;
  /** Timezone abbreviation (e.g., 'EST', 'PST') */
  abbreviation: string;
  /** Whether currently in daylight saving time */
  isDST: boolean;
}

// ============================================================================
// HOOK RETURN TYPES
// ============================================================================

/**
 * Return type for useAvailability hook
 */
export interface UseAvailabilityReturn {
  /** Available dates within booking window */
  availableDates: BookingDate[];
  /** Get time slots for a specific date */
  getTimeSlots: (date: Date, duration: 30 | 60) => TimeSlot[];
  /** Check if a specific slot is available */
  isSlotAvailable: (dateTime: Date, duration: 30 | 60) => boolean;
  /** Loading state */
  loading: boolean;
  /** Error state */
  error: string | null;
}

/**
 * Return type for useBookingForm hook
 */
export interface UseBookingFormReturn {
  /** Current form state */
  state: SchedulerState;
  /** Update selected duration */
  setDuration: (duration: 30 | 60) => void;
  /** Update selected date */
  setDate: (date: Date) => void;
  /** Update selected time */
  setTime: (time: string) => void;
  /** Update user info */
  setUserInfo: (info: UserInfo) => void;
  /** Move to next step */
  nextStep: () => void;
  /** Move to previous step */
  previousStep: () => void;
  /** Go to specific step */
  goToStep: (step: number) => void;
  /** Submit booking */
  submitBooking: () => Promise<N8NResponse>;
  /** Reset form */
  reset: () => void;
  /** Restore saved draft */
  restoreDraft: () => boolean;
}

/**
 * Return type for useTimezone hook
 */
export interface UseTimezoneReturn {
  /** Current timezone info */
  timezone: TimezoneInfo;
  /** Convert date to user's timezone */
  toUserTimezone: (date: Date) => Date;
  /** Convert date to UTC */
  toUTC: (date: Date) => Date;
  /** Format date for display */
  formatDate: (date: Date, format?: string) => string;
  /** Format time for display */
  formatTime: (time: string) => string;
}

// ============================================================================
// ERROR TYPES
// ============================================================================

/**
 * Custom error for booking-related issues
 */
export class BookingError extends Error {
  constructor(
    message: string,
    public code: BookingErrorCode,
    public details?: Record<string, unknown>,
  ) {
    super(message);
    this.name = "BookingError";
  }
}

/**
 * Booking error codes
 */
export type BookingErrorCode =
  | "SLOT_UNAVAILABLE"
  | "VALIDATION_ERROR"
  | "NETWORK_ERROR"
  | "WEBHOOK_ERROR"
  | "TIMEOUT_ERROR"
  | "UNKNOWN_ERROR";

// ============================================================================
// TYPE GUARDS
// ============================================================================

/**
 * Type guard to check if value is valid duration
 */
export function isValidDuration(value: unknown): value is 30 | 60 {
  return value === 30 || value === 60;
}

/**
 * Type guard to check if value is valid language
 */
export function isValidLanguage(value: unknown): value is "en" | "ar" {
  return value === "en" || value === "ar";
}

/**
 * Type guard to check if value is valid step number
 */
export function isValidStep(value: unknown): value is number {
  return typeof value === "number" && value >= 1 && value <= 6;
}
