import React, { useState, useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { ServiceSelection } from '../components/booking/ServiceSelection';
import { DateTimeSelection } from '../components/booking/DateTimeSelection';
import { AuthSection, User } from '../components/booking/AuthSection';
import { PaymentSection } from '../components/booking/PaymentSection';
import { Confirmation } from '../components/booking/Confirmation';
import { Steps } from '../components/booking/Steps';
import { ArrowLeft, ArrowRight } from 'lucide-react';
import { PublicService } from '../hooks/useBooking';

interface BookingState {
  step: number;
  service: PublicService | null;
  date: Date | null;
  timeSlot: string | null;
  user: User | null;
  paymentMethod: string | null;
}

// Storage key for booking state
const BOOKING_STATE_KEY = 'booking_state';

// Load booking state from sessionStorage
const loadBookingState = (): Partial<BookingState> => {
  try {
    const saved = sessionStorage.getItem(BOOKING_STATE_KEY);
    if (saved) {
      const parsed = JSON.parse(saved);
      // Convert date string back to Date object
      if (parsed.date) {
        parsed.date = new Date(parsed.date);
      }
      return parsed;
    }
  } catch (e) {
    console.error('Failed to load booking state:', e);
  }
  return {};
};

// Save booking state to sessionStorage
const saveBookingState = (state: BookingState) => {
  try {
    sessionStorage.setItem(BOOKING_STATE_KEY, JSON.stringify(state));
  } catch (e) {
    console.error('Failed to save booking state:', e);
  }
};

export const BookingFlow: React.FC = () => {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();

  // Get step from URL or default to 1
  const stepFromUrl = parseInt(searchParams.get('step') || '1');

  // Load saved state from sessionStorage
  const savedState = loadBookingState();

  const [bookingState, setBookingState] = useState<BookingState>({
    step: stepFromUrl,
    service: savedState.service || null,
    date: savedState.date || null,
    timeSlot: savedState.timeSlot || null,
    user: savedState.user || null,
    paymentMethod: savedState.paymentMethod || null
  });

  // Update URL when step changes
  useEffect(() => {
    setSearchParams({ step: bookingState.step.toString() });
  }, [bookingState.step, setSearchParams]);

  // Save booking state to sessionStorage whenever it changes
  useEffect(() => {
    saveBookingState(bookingState);
  }, [bookingState]);

  // Redirect to step 1 if on step > 1 but no service selected
  useEffect(() => {
    if (bookingState.step > 1 && !bookingState.service) {
      setBookingState(prev => ({ ...prev, step: 1 }));
    }
  }, [bookingState.step, bookingState.service]);

  const nextStep = () => setBookingState(prev => ({ ...prev, step: prev.step + 1 }));
  const prevStep = () => {
    if (bookingState.step === 1) {
      navigate(-1); // Go back to previous page
    } else {
      setBookingState(prev => ({ ...prev, step: prev.step - 1 }));
    }
  };

  // Handlers
  const handleServiceSelect = (service: PublicService) => {
    setBookingState(prev => ({ ...prev, service }));
    setTimeout(nextStep, 300);
  };

  const handleDateChange = (date: Date) => {
    setBookingState(prev => ({ ...prev, date }));
  };

  const handleTimeChange = (timeSlot: string) => {
    setBookingState(prev => ({ ...prev, timeSlot }));
  };

  const handleLogin = (user: User) => {
    setBookingState(prev => ({ ...prev, user }));
    nextStep();
  };

  const handlePaymentComplete = () => {
    nextStep();
  };

  // Reusable navigation footer component
  const StepNavigation: React.FC<{
    showBack?: boolean;
    showContinue?: boolean;
    continueDisabled?: boolean;
    continueLabel?: string;
    onContinue?: () => void;
  }> = ({ showBack = true, showContinue = false, continueDisabled = false, continueLabel = 'Continue', onContinue }) => (
    <div className={`flex ${showBack && showContinue ? 'justify-between' : showBack ? 'justify-start' : 'justify-end'} pt-6 mt-6 border-t border-gray-200 dark:border-gray-700`}>
      {showBack && (
        <button
          onClick={prevStep}
          className="flex items-center px-5 py-2.5 text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg font-medium hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
        >
          <ArrowLeft className="w-4 h-4 mr-2" />
          Back
        </button>
      )}
      {showContinue && (
        <button
          onClick={onContinue}
          disabled={continueDisabled}
          className="flex items-center px-6 py-2.5 bg-indigo-600 dark:bg-indigo-500 text-white rounded-lg font-medium hover:bg-indigo-700 dark:hover:bg-indigo-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
        >
          {continueLabel}
          <ArrowRight className="w-4 h-4 ml-2" />
        </button>
      )}
    </div>
  );

  const renderStep = () => {
    switch (bookingState.step) {
      case 1:
        return (
          <div>
            <ServiceSelection selectedService={bookingState.service} onSelect={handleServiceSelect} />
            <StepNavigation showBack={true} showContinue={false} />
          </div>
        );
      case 2:
        return (
          <div>
            <DateTimeSelection
              serviceId={bookingState.service?.id}
              selectedDate={bookingState.date}
              selectedTimeSlot={bookingState.timeSlot}
              onDateChange={handleDateChange}
              onTimeChange={handleTimeChange}
            />
            <StepNavigation
              showBack={true}
              showContinue={true}
              continueDisabled={!bookingState.date || !bookingState.timeSlot}
              onContinue={nextStep}
            />
          </div>
        );
      case 3:
        return (
          <div>
            <AuthSection onLogin={handleLogin} />
            <StepNavigation showBack={true} showContinue={false} />
          </div>
        );
      case 4:
        return bookingState.service ? (
          <div>
            <PaymentSection service={bookingState.service} onPaymentComplete={handlePaymentComplete} />
            <StepNavigation showBack={true} showContinue={false} />
          </div>
        ) : null;
      case 5:
        return <Confirmation booking={bookingState} />;
      default:
        return null;
    }
  };

  return (
    <div className="min-h-screen bg-gray-50 dark:bg-gray-900">
      {/* Header */}
      <header className="bg-white dark:bg-gray-800 shadow-sm border-b border-gray-200 dark:border-gray-700 sticky top-0 z-40">
        <div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
          <div className="flex items-center gap-3">
            <button
              onClick={prevStep}
              className="text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white transition-colors"
            >
              <ArrowLeft className="w-5 h-5" />
            </button>
            <div className="text-sm text-gray-600 dark:text-gray-300">
              {bookingState.step < 5 ? 'Book an Appointment' : 'Booking Complete'}
            </div>
          </div>
          {bookingState.user && bookingState.step < 5 && (
            <div className="text-sm text-gray-600 dark:text-gray-300">
              Hi, <span className="font-medium text-gray-900 dark:text-white">{bookingState.user.name}</span>
            </div>
          )}
        </div>
      </header>

      <main className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
        {/* Progress Stepper */}
        {bookingState.step < 5 && (
          <div className="mb-12">
            <Steps currentStep={bookingState.step} />
          </div>
        )}

        {/* Booking Summary (steps 2-4) */}
        {bookingState.step > 1 && bookingState.step < 5 && (
          <div className="mb-8 p-4 bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-sm flex flex-wrap items-center gap-4 text-sm text-gray-600 dark:text-gray-300">
            {bookingState.service && (
              <div className="flex items-center">
                <span className="font-medium text-gray-900 dark:text-white mr-2">Service:</span>
                {bookingState.service.name} (${(bookingState.service.price_cents / 100).toFixed(2)})
              </div>
            )}
            {bookingState.date && bookingState.timeSlot && (
              <>
                <div className="w-1 h-1 bg-gray-300 dark:bg-gray-600 rounded-full"></div>
                <div className="flex items-center">
                  <span className="font-medium text-gray-900 dark:text-white mr-2">Time:</span>
                  {bookingState.date.toLocaleDateString()} at {bookingState.timeSlot}
                </div>
              </>
            )}
          </div>
        )}

        {/* Main Content */}
        <div className="animate-in fade-in slide-in-from-bottom-4 duration-500">
          {renderStep()}
        </div>
      </main>
    </div>
  );
};

export default BookingFlow;
