/**
 * Mawidi Demo Scheduler - Main Component
 * Complete booking flow with 4 steps: Duration → Date → Time → Info → Confirm → Success
 */

"use client";

import React, { useState, useEffect } from "react";
import type { BookingData } from "./types/scheduler.types";

// Hooks
import { useAvailability } from "./hooks/useAvailability";
import { useBookingForm } from "./hooks/useBookingForm";
import { useTimezone } from "./hooks/useTimezone";

// Components
import StepIndicator from "./components/StepIndicator";
import DurationSelector from "./components/DurationSelector";
import CalendarView from "./components/CalendarView";
import TimeSlotPicker from "./components/TimeSlotPicker";
import BookingForm from "./components/BookingForm";
import ConfirmationStep from "./components/ConfirmationStep";
import SuccessMessage from "./components/SuccessMessage";

export interface DemoSchedulerProps {
  /** Language for the scheduler */
  language?: "en" | "ar";
  /** Custom className for styling */
  className?: string;
  /** n8n webhook URL for booking submission */
  webhookUrl?: string;
  /** Callback when booking is successfully completed */
  onBookingComplete?: (bookingData: BookingData, reference: string) => void;
  /** Callback when user cancels/goes back */
  onCancel?: () => void;
}

const stepLabels = {
  en: ["Duration", "Date & Time", "Your Info", "Confirm"],
  ar: ["المدة", "التاريخ والوقت", "معلوماتك", "تأكيد"],
};

const navigationLabels = {
  en: {
    next: "Next",
    back: "Back",
    confirm: "Confirm Booking",
    submitting: "Submitting...",
  },
  ar: {
    next: "التالي",
    back: "رجوع",
    confirm: "تأكيد الحجز",
    submitting: "جاري الإرسال...",
  },
};

/**
 * DemoScheduler Component
 *
 * Complete Calendly-like booking system with:
 * - 4-step booking flow
 * - Working hours enforcement (Sun-Thu 2-7PM, Fri-Sat 7AM-5PM UTC+3)
 * - 12-hour minimum advance booking
 * - 21-day booking window
 * - Bilingual support (English/Arabic)
 * - Form validation and sanitization
 * - n8n webhook integration
 * - Local storage persistence
 *
 * @example
 * ```tsx
 * <DemoScheduler
 *   language="en"
 *   webhookUrl={process.env.NEXT_PUBLIC_N8N_WEBHOOK_URL}
 *   onBookingComplete={(data, ref) => console.log('Booked!', ref)}
 * />
 * ```
 */
export default function DemoScheduler({
  language = "en",
  className = "",
  webhookUrl,
  onBookingComplete,
  onCancel,
}: DemoSchedulerProps) {
  const dir = language === "ar" ? "rtl" : "ltr";
  const labels = navigationLabels[language];

  // State
  const [currentStep, setCurrentStep] = useState(1);
  const [showSuccess, setShowSuccess] = useState(false);

  // Custom hooks
  const {
    bookingData,
    errors,
    submitting,
    bookingReference,
    meetingLink,
    updateBookingData,
    updateUserInfo,
    validateForm,
    setErrors,
    submitBooking,
    resetForm,
    saveToStorage,
  } = useBookingForm({
    webhookUrl,
    onSuccess: (data, reference) => {
      setShowSuccess(true);
      onBookingComplete?.(data, reference);
    },
  });

  const { hasTimezoneMismatch, userTimezone, schedulerTimezone } = useTimezone({
    autoDetect: true,
  });

  const {
    availableDates,
    getTimeSlotsForDate,
    fetchBookingsForDate,
    loading: availabilityLoading,
    loadingTimeSlots,
  } = useAvailability({
    duration: bookingData.meetingDuration || 30,
  });

  // Auto-save to storage when booking data changes
  useEffect(() => {
    if (bookingData.meetingDuration || bookingData.selectedDate) {
      saveToStorage();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [bookingData]); // Intentionally exclude saveToStorage to prevent unnecessary re-runs

  // Set timezone in booking data (only once on mount or when timezone changes)
  useEffect(() => {
    updateBookingData({ timezone: schedulerTimezone });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [schedulerTimezone]); // Intentionally exclude updateBookingData to prevent infinite loop

  /**
   * Navigate to next step with validation
   */
  const handleNext = () => {
    // Validate current step before proceeding
    let canProceed = false;

    switch (currentStep) {
      case 1: // Duration
        canProceed = !!bookingData.meetingDuration;
        if (!canProceed) {
          setErrors({ duration: "Please select a duration" });
        }
        break;

      case 2: // Date & Time
        canProceed = !!(bookingData.selectedDate && bookingData.selectedTime);
        if (!canProceed) {
          const newErrors: typeof errors = {};
          if (!bookingData.selectedDate)
            newErrors.date = "Please select a date";
          if (!bookingData.selectedTime)
            newErrors.time = "Please select a time";
          setErrors(newErrors);
        }
        break;

      case 3: // User Info
        canProceed = validateForm();
        break;

      default:
        canProceed = true;
    }

    if (canProceed) {
      setCurrentStep((prev) => Math.min(prev + 1, 4));
    }
  };

  /**
   * Navigate to previous step
   */
  const handleBack = () => {
    if (currentStep === 1) {
      onCancel?.();
    } else {
      setCurrentStep((prev) => Math.max(prev - 1, 1));
    }
  };

  /**
   * Submit booking from confirmation step
   */
  const handleConfirmBooking = async () => {
    try {
      await submitBooking();
    } catch (error) {
      console.error("Booking submission failed:", error);
      // Error handling is done in useBookingForm
    }
  };

  /**
   * Handle "Book Another" action
   */
  const handleBookAnother = () => {
    resetForm();
    setCurrentStep(1);
    setShowSuccess(false);
  };

  /**
   * Generate ICS calendar file for download
   */
  const handleAddToCalendar = () => {
    if (!bookingData.selectedDate || !bookingData.selectedTime) return;

    const startDate = new Date(bookingData.selectedDate);
    const [hours, minutes] = bookingData.selectedTime.split(":").map(Number);
    startDate.setHours(hours, minutes, 0, 0);

    const endDate = new Date(startDate);
    endDate.setMinutes(
      endDate.getMinutes() + (bookingData.meetingDuration || 30),
    );

    const formatICSDate = (date: Date): string => {
      return date.toISOString().replace(/[-:]/g, "").split(".")[0] + "Z";
    };

    const icsContent = [
      "BEGIN:VCALENDAR",
      "VERSION:2.0",
      "PRODID:-//Mawidi//Demo Scheduler//EN",
      "BEGIN:VEVENT",
      `UID:${bookingReference}@mawidi.com`,
      `DTSTAMP:${formatICSDate(new Date())}`,
      `DTSTART:${formatICSDate(startDate)}`,
      `DTEND:${formatICSDate(endDate)}`,
      `SUMMARY:Mawidi Demo Session`,
      `DESCRIPTION:Demo session with Mawidi team\\nBooking Reference: ${bookingReference}`,
      `LOCATION:Online Meeting`,
      "STATUS:CONFIRMED",
      "END:VEVENT",
      "END:VCALENDAR",
    ].join("\r\n");

    const blob = new Blob([icsContent], {
      type: "text/calendar;charset=utf-8",
    });
    const link = document.createElement("a");
    link.href = URL.createObjectURL(blob);
    link.download = `mawidi-demo-${bookingReference}.ics`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  // Show success message after submission
  if (showSuccess && bookingReference) {
    return (
      <div className={`max-w-3xl mx-auto ${className}`} dir={dir}>
        <SuccessMessage
          bookingData={bookingData as BookingData}
          bookingReference={bookingReference}
          meetingLink={meetingLink || undefined}
          onAddToCalendar={handleAddToCalendar}
          onBookAnother={handleBookAnother}
          language={language}
          dir={dir}
        />
      </div>
    );
  }

  return (
    <div className={`max-w-4xl mx-auto ${className}`} dir={dir}>
      {/* Header with step indicator */}
      <div className="mb-8">
        <StepIndicator
          currentStep={currentStep}
          totalSteps={4}
          stepLabels={stepLabels[language]}
          dir={dir}
        />
      </div>

      {/* Timezone warning if mismatch - Editorial style */}
      {hasTimezoneMismatch && (
        <div className="mb-6 flex items-start gap-3 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700">
          <div className="w-1.5 h-1.5 bg-amber-500 mt-2 flex-shrink-0" />
          <div className="text-sm text-amber-800 dark:text-amber-200">
            {language === "ar" ? (
              <>
                <span className="font-semibold">تنبيه المنطقة الزمنية:</span>{" "}
                منطقتك الزمنية ({userTimezone}) تختلف عن منطقتنا (
                {schedulerTimezone}). ستظهر جميع الأوقات بتوقيت{" "}
                {schedulerTimezone}.
              </>
            ) : (
              <>
                <span className="font-semibold">Timezone Notice:</span> Your
                timezone ({userTimezone}) differs from our scheduling timezone (
                {schedulerTimezone}). All times shown are in {schedulerTimezone}
                .
              </>
            )}
          </div>
        </div>
      )}

      {/* Main content area - Editorial style */}
      <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 hover:border-[#10B981]/30 dark:hover:border-[#10B981]/30 transition-colors duration-300 p-6 md:p-8 min-h-[500px]">
        {/* Step 1: Duration Selection */}
        {currentStep === 1 && (
          <DurationSelector
            selectedDuration={bookingData.meetingDuration || null}
            onSelect={(meetingDuration) => {
              updateBookingData({ meetingDuration });
              setErrors({});
            }}
            language={language}
            dir={dir}
          />
        )}

        {/* Step 2: Date & Time Selection */}
        {currentStep === 2 && (
          <div className="space-y-8">
            <CalendarView
              availableDates={availableDates}
              selectedDate={bookingData.selectedDate || null}
              onSelectDate={async (date) => {
                updateBookingData({
                  selectedDate: date,
                  selectedTime: undefined,
                });
                setErrors({});
                // Fetch fresh bookings for the selected date
                await fetchBookingsForDate(date);
              }}
              language={language}
              dir={dir}
              loading={availabilityLoading}
            />

            {bookingData.selectedDate && (
              <TimeSlotPicker
                timeSlots={getTimeSlotsForDate(bookingData.selectedDate)}
                selectedTime={bookingData.selectedTime || null}
                onSelectTime={(time) => {
                  updateBookingData({ selectedTime: time });
                  setErrors({});
                }}
                selectedDate={bookingData.selectedDate}
                duration={bookingData.meetingDuration || 30}
                language={language}
                dir={dir}
                loading={loadingTimeSlots}
              />
            )}
          </div>
        )}

        {/* Step 3: User Information */}
        {currentStep === 3 && (
          <BookingForm
            userInfo={(bookingData as BookingData).userInfo || {}}
            onChange={updateUserInfo}
            errors={errors}
            onErrorsChange={setErrors}
            language={language}
            dir={dir}
          />
        )}

        {/* Step 4: Confirmation */}
        {currentStep === 4 && (
          <>
            <ConfirmationStep
              bookingData={bookingData as BookingData}
              language={language}
              dir={dir}
            />

            {/* Show error message if submission fails - Editorial style */}
            {errors.submit && (
              <div className="mt-6 flex items-start gap-3 p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800">
                <div className="w-1.5 h-1.5 bg-red-500 mt-2 flex-shrink-0" />
                <div className="flex-1">
                  <h4 className="font-semibold text-red-800 dark:text-red-300 mb-1">
                    {language === "ar" ? "فشل الحجز" : "Booking Failed"}
                  </h4>
                  <p className="text-sm text-red-700 dark:text-red-400">
                    {errors.submit}
                  </p>
                  <button
                    onClick={() => setErrors({})}
                    className="mt-2 text-sm text-red-600 dark:text-red-400 hover:underline"
                  >
                    {language === "ar" ? "أغلق" : "Dismiss"}
                  </button>
                </div>
              </div>
            )}
          </>
        )}
      </div>

      {/* Navigation buttons - Editorial style */}
      <div className="mt-8 flex items-center justify-between gap-px bg-slate-200 dark:bg-slate-700">
        {/* Back button */}
        <button
          onClick={handleBack}
          disabled={submitting}
          className="
            group
            relative
            px-8
            py-4
            bg-white
            dark:bg-slate-900
            text-[#1E293B]
            dark:text-white
            font-semibold
            transition-all
            duration-200
            disabled:opacity-50
            disabled:cursor-not-allowed
            hover:bg-[#10B981]/5
            dark:hover:bg-[#10B981]/10
            focus:outline-none
            focus:ring-2
            focus:ring-inset
            focus:ring-[#10B981]
          "
        >
          <span className="flex items-center gap-2">
            <span className="transition-transform duration-200 group-hover:-translate-x-1 rtl:group-hover:translate-x-1">
              ←
            </span>
            {labels.back}
          </span>
        </button>

        {/* Next/Confirm button */}
        {currentStep < 4 ? (
          <button
            onClick={handleNext}
            disabled={submitting}
            className="
              group
              relative
              px-8
              py-4
              bg-[#10B981]
              text-white
              font-semibold
              transition-all
              duration-200
              disabled:opacity-50
              disabled:cursor-not-allowed
              hover:bg-[#059669]
              focus:outline-none
              focus:ring-2
              focus:ring-inset
              focus:ring-[#10B981]
              overflow-hidden
            "
          >
            <span className="relative z-10 flex items-center gap-2">
              {labels.next}
              <span className="transition-transform duration-200 group-hover:translate-x-1 rtl:group-hover:-translate-x-1">
                →
              </span>
            </span>
          </button>
        ) : (
          <button
            onClick={handleConfirmBooking}
            disabled={submitting}
            className="
              group
              relative
              px-8
              py-4
              bg-[#10B981]
              text-white
              font-semibold
              transition-all
              duration-200
              disabled:opacity-50
              disabled:cursor-not-allowed
              hover:bg-[#059669]
              focus:outline-none
              focus:ring-2
              focus:ring-inset
              focus:ring-[#10B981]
              overflow-hidden
            "
          >
            {submitting ? (
              <span className="flex items-center gap-2">
                <div className="w-4 h-4 border-2 border-white/30 border-t-white animate-spin" />
                {labels.submitting}
              </span>
            ) : (
              <span className="relative z-10 flex items-center gap-2">
                {labels.confirm}
                <svg
                  className="w-4 h-4"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M5 13l4 4L19 7"
                  />
                </svg>
              </span>
            )}
          </button>
        )}
      </div>
    </div>
  );
}
