/**
 * Calendar Widget (Live)
 * 
 * Date/time picker for scheduling appointments.
 * Shows available time slots for selected dates with a form step for details.
 * Uses the shared Calendar component for parity with preview.
 * Fetches real-time availability from Google Calendar when connected.
 * 
 * @since 1.0.0
 * @updated 1.6.0 - Migrated to shared component
 * @updated 1.9.0 - Added Google Calendar availability sync
 */

import { useCallback, useEffect, useState } from 'react';
import { Calendar } from '@shared/components/widgets/Calendar';
import type { GlobalValues, FieldValue } from '@/utils/resolveAppearance';

interface TimeSlot {
  time: string;
  available: boolean;
}

interface CalendarWidgetSettings {
  container?: {
    background?: FieldValue;
    borderRadius?: FieldValue;
    shadow?: FieldValue;
    padding?: FieldValue;
  };
  stepHeader?: {
    background?: FieldValue;
    textColor?: FieldValue;
    inactiveBackground?: FieldValue;
    inactiveTextColor?: FieldValue;
    padding?: FieldValue;
    borderRadius?: FieldValue;
    typography?: Record<string, FieldValue | undefined>;
    icon?: {
      color?: FieldValue;
      size?: FieldValue;
      gap?: FieldValue;
    };
    badge?: {
      size?: FieldValue;
      background?: FieldValue;
      textColor?: FieldValue;
      typography?: Record<string, FieldValue | undefined>;
      iconColor?: FieldValue;
      iconSize?: FieldValue;
    };
  };
  navigation?: {
    arrowColor?: FieldValue;
    arrowHoverBackground?: FieldValue;
    arrowSize?: FieldValue;
    arrowHoverColor?: FieldValue;
    monthYearColor?: FieldValue;
    typography?: Record<string, FieldValue | undefined>;
  };
  grid?: {
    dayHeaderColor?: FieldValue;
    dayHeaderBackground?: FieldValue;
    gap?: FieldValue;
    dayColor?: FieldValue;
    dayHoverBackground?: FieldValue;
    todayBackground?: FieldValue;
    todayColor?: FieldValue;
    selectedBackground?: FieldValue;
    selectedColor?: FieldValue;
    disabledColor?: FieldValue;
    dayBorder?: FieldValue;
    dayBorderRadius?: FieldValue;
    daySize?: FieldValue;
    typography?: Record<string, FieldValue | undefined>;
  };
  timeSlots?: {
    columns?: string;
    gap?: FieldValue;
    slotBackground?: FieldValue;
    slotBorder?: FieldValue;
    borderRadius?: FieldValue;
    padding?: FieldValue;
    slotColor?: FieldValue;
    slotHoverBackground?: FieldValue;
    selectedBackground?: FieldValue;
    selectedColor?: FieldValue;
    unavailableBackground?: FieldValue;
    typography?: Record<string, FieldValue | undefined>;
  };
  form?: {
    fieldGap?: FieldValue;
    labelGap?: FieldValue;
    labelColor?: FieldValue;
    labelTypography?: Record<string, FieldValue | undefined>;
    requiredAsteriskColor?: FieldValue;
    inputBackground?: FieldValue;
    inputTextColor?: FieldValue;
    inputPlaceholderColor?: FieldValue;
    inputBorderColor?: FieldValue;
    inputBorderColorError?: FieldValue;
    inputBorderRadius?: FieldValue;
    inputPadding?: FieldValue;
    inputTypography?: Record<string, FieldValue | undefined>;
    iconColor?: FieldValue;
    iconSize?: FieldValue;
    iconInset?: FieldValue;
    errorColor?: FieldValue;
    errorTypography?: Record<string, FieldValue | undefined>;
  };
  confirmation?: {
    background?: FieldValue;
    borderColor?: FieldValue;
    borderRadius?: FieldValue;
    padding?: FieldValue;
    titleColor?: FieldValue;
    detailsColor?: FieldValue;
    iconBackground?: FieldValue;
    iconColor?: FieldValue;
    iconSize?: FieldValue;
    buttonBackground?: FieldValue;
    buttonColor?: FieldValue;
    typography?: Record<string, FieldValue | undefined>;
    sentToLabelColor?: FieldValue;
    sentToLabelTypography?: Record<string, FieldValue | undefined>;
  };
}

interface MeetingTypeConfig {
  id: string;
  label: string;
  icon?: string;
  description?: string;
  require_name?: boolean;
  require_phone?: boolean;
  require_email?: boolean;
  extra_info?: string;
}

interface CalendarWidgetProps {
  config: {
    title?: string;
    available_dates?: string[];
    available_times?: TimeSlot[];
    min_date?: string;
    max_date?: string;
    is_rtl?: boolean;
    require_form?: boolean;
    require_name?: boolean;
    require_phone?: boolean;
    require_email?: boolean;
    form_fields?: Array<{ type: 'name' | 'phone' | 'email'; required: boolean; label?: string }>;
    widget_id?: number;
    bot_id?: number;
    meeting_types?: MeetingTypeConfig[];
    show_meeting_type_selection?: boolean;
    duration_options?: number[];
  };
  widgetSettings?: CalendarWidgetSettings;
  globalValues?: GlobalValues;
  language?: string;
  onSelect: (date: string, time: string, formData?: Record<string, string>) => void | Promise<void>;
  __debugInitialStep?: 'date' | 'time' | 'form' | 'confirmation';
  __debugSelectedDate?: string;
  __debugSelectedTime?: string;
  __debugFormData?: Record<string, string>;
  __debugToday?: string;
  __debugCurrentMonth?: string;
}

export function CalendarWidget({
  config,
  widgetSettings,
  globalValues = {},
  language,
  onSelect,
  __debugInitialStep,
}: CalendarWidgetProps) {
  const { 
    title, 
    available_times,
    is_rtl,
    require_name = true,
    require_phone = true,
    require_email = false,
    meeting_types,
    show_meeting_type_selection,
    duration_options,
  } = config;

  // Legacy fallback: if duration_options is still set in widget config, use it as a hint
  // for the availability API. Per-contact durations on the backend take priority.
  const duration = duration_options?.[0] ?? 30;

  // Fetch available days of the week, server timezone, and effective min date from the backend
  const [availableDaysOfWeek, setAvailableDaysOfWeek] = useState<number[] | undefined>(undefined);
  const [serverTimezone, setServerTimezone] = useState<string | undefined>(undefined);
  const [effectiveMinDate, setEffectiveMinDate] = useState<string | undefined>(undefined);

  useEffect(() => {
    if (!config.widget_id) return;
    const baseUrl = (window as any).boostbot_config?.rest_url || '/wp-json/boostbot/v1/';
    const nonce = (window as any).boostbot_config?.nonce || '';
    const headers: Record<string, string> = { 'Content-Type': 'application/json' };
    if (nonce) headers['X-WP-Nonce'] = nonce;

    fetch(`${baseUrl}meetings/available-days?widget_id=${config.widget_id}`, { headers })
      .then(res => res.ok ? res.json() : null)
      .then(json => {
        if (json?.data?.available_days_of_week) {
          setAvailableDaysOfWeek(json.data.available_days_of_week);
        }
        if (json?.data?.timezone) {
          setServerTimezone(json.data.timezone);
        }
        if (json?.data?.effective_min_date) {
          setEffectiveMinDate(json.data.effective_min_date);
        }
      })
      .catch(() => { /* ignore — calendar falls back to default */ });
  }, [config.widget_id]);

  /**
   * Fetch real-time availability from the server.
   * The backend aggregates per-contact schedules and returns accurate slots.
   * Duration is sent as a fallback hint for widgets without per-contact availability.
   */
  const handleDateChange = useCallback(async (date: string, durationParam?: number) => {
    try {
      const baseUrl = (window as any).boostbot_config?.rest_url || '/wp-json/boostbot/v1/';
      const nonce = (window as any).boostbot_config?.nonce || '';
      
      const params = new URLSearchParams({ date });
      if (config.widget_id) {
        params.set('widget_id', String(config.widget_id));
      }
      // Duration is a fallback hint — backend uses per-contact duration when available
      params.set('duration', String(durationParam || duration));
      
      const headers: Record<string, string> = {
        'Content-Type': 'application/json',
      };
      if (nonce) {
        headers['X-WP-Nonce'] = nonce;
      }
      
      const res = await fetch(`${baseUrl}meetings/availability?${params.toString()}`, { headers });
      
      if (!res.ok) return null;
      
      const json = await res.json();
      
      if (json.data?.slots && Array.isArray(json.data.slots)) {
        return json.data.slots as { time: string; available: boolean }[];
      }
      
      return null;
    } catch {
      return null;
    }
  }, [config.widget_id, duration]);

  return (
    <Calendar
      globalValues={globalValues as any}
      widgetSettings={widgetSettings as any}
      context="live"
      language={language}
      isRTL={is_rtl}
      initialStep={__debugInitialStep || 'date'}
      config={{
        title,
        available_dates: config.available_dates,
        available_times,
        min_date: effectiveMinDate || config.min_date,
        max_date: config.max_date,
        require_name,
        require_phone,
        require_email,
        meeting_types,
        show_meeting_type_selection,
        duration,
        available_days_of_week: availableDaysOfWeek,
        server_timezone: serverTimezone,
      }}
      onSelect={onSelect}
      onDateChange={handleDateChange}
    />
  );
}

export default CalendarWidget;
