
import React, { useState, useEffect, useMemo } from 'react';
import { useOutletContext, Link } from 'react-router-dom';
import { User, Business, Service, Location } from '../../types';
import { useServices } from '../../hooks/useServices';
import { useLocations } from '../../hooks/useLocations';
import { Check, ChevronLeft, Calendar, Clock, AlertTriangle, CreditCard, Loader2, MapPin } from 'lucide-react';

const BookingPage: React.FC = () => {
  const { user, business } = useOutletContext<{ user: User, business: Business }>();
  // Fetch services and locations from API - backend filters for current tenant
  const { data: services = [], isLoading: servicesLoading } = useServices();
  const { data: locations = [], isLoading: locationsLoading } = useLocations();

  // Check if we need to show location step (more than 1 active location)
  const hasMultipleLocations = locations.length > 1;

  // Step 0 = Location (if multi-location), Step 1 = Service, Step 2 = Time, etc.
  const [step, setStep] = useState(hasMultipleLocations ? 0 : 1);
  const [selectedLocation, setSelectedLocation] = useState<Location | null>(null);
  const [selectedService, setSelectedService] = useState<Service | null>(null);
  const [selectedTime, setSelectedTime] = useState<Date | null>(null);
  const [bookingConfirmed, setBookingConfirmed] = useState(false);

  // Auto-select location if only one exists
  useEffect(() => {
    if (!locationsLoading && locations.length === 1 && !selectedLocation) {
      setSelectedLocation(locations[0]);
    }
  }, [locations, locationsLoading, selectedLocation]);

  // Update starting step when locations load
  useEffect(() => {
    if (!locationsLoading) {
      if (locations.length <= 1 && step === 0) {
        setStep(1);
      }
    }
  }, [locations, locationsLoading, step]);

  // Filter services by selected location (if service has location restrictions)
  const availableServices = useMemo(() => {
    if (!selectedLocation) return services;
    return services.filter((service: Service) => {
      // If service is global (or is_global is undefined/true), it's available everywhere
      if (service.is_global !== false) return true;
      // If service has specific locations, check if current location is included
      if (service.locations && service.locations.length > 0) {
        return service.locations.includes(selectedLocation.id);
      }
      // Default: available everywhere
      return true;
    });
  }, [services, selectedLocation]);

  // Mock available times
  const availableTimes: Date[] = [
    new Date(new Date().setHours(9, 0, 0, 0)),
    new Date(new Date().setHours(10, 30, 0, 0)),
    new Date(new Date().setHours(14, 0, 0, 0)),
    new Date(new Date().setHours(16, 15, 0, 0)),
  ];

  const handleSelectLocation = (location: Location) => {
    setSelectedLocation(location);
    setStep(1);
  };

  const handleSelectService = (service: Service) => {
    setSelectedService(service);
    setStep(2);
  };

  const handleSelectTime = (time: Date) => {
    setSelectedTime(time);
    setStep(3);
  };

  const handleConfirmBooking = () => {
    // In a real app, this would send a request to the backend.
    setBookingConfirmed(true);
    setStep(4);
  };

  const resetFlow = () => {
    // Reset to location step if multiple locations, otherwise service step
    setStep(hasMultipleLocations ? 0 : 1);
    setSelectedLocation(hasMultipleLocations ? null : (locations.length === 1 ? locations[0] : null));
    setSelectedService(null);
    setSelectedTime(null);
    setBookingConfirmed(false);
  }

  // Get the minimum step (0 if multi-location, 1 otherwise)
  const minStep = hasMultipleLocations ? 0 : 1;

  const renderStepContent = () => {
    switch (step) {
      case 0: // Select Location (only shown when multiple locations exist)
        if (locationsLoading) {
          return (
            <div className="flex items-center justify-center py-12">
              <Loader2 className="w-8 h-8 animate-spin text-brand-500" />
            </div>
          );
        }
        if (locations.length === 0) {
          return (
            <div className="text-center py-8 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
              <div className="flex flex-col items-center gap-3">
                <AlertTriangle className="w-12 h-12 text-amber-500" />
                <p className="text-gray-500 dark:text-gray-400">No active locations available. Please contact support.</p>
              </div>
            </div>
          );
        }
        return (
          <div className="space-y-4">
            {locations.map((location: Location) => (
              <button
                key={location.id}
                onClick={() => handleSelectLocation(location)}
                className="w-full text-left p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm hover:border-brand-500 hover:ring-1 hover:ring-brand-500 transition-all flex items-center gap-4"
              >
                <div className="flex-shrink-0 w-12 h-12 rounded-full bg-brand-100 dark:bg-brand-900/30 flex items-center justify-center">
                  <MapPin className="w-6 h-6 text-brand-600 dark:text-brand-400" />
                </div>
                <div className="flex-1">
                  <h4 className="font-semibold text-gray-900 dark:text-white">
                    {location.name}
                    {location.is_primary && (
                      <span className="ml-2 text-xs px-2 py-0.5 bg-brand-100 text-brand-700 dark:bg-brand-900/50 dark:text-brand-300 rounded-full">
                        Primary
                      </span>
                    )}
                  </h4>
                  {(location.address_line1 || location.city) && (
                    <p className="text-sm text-gray-500 dark:text-gray-400">
                      {[location.address_line1, location.city, location.state].filter(Boolean).join(', ')}
                    </p>
                  )}
                </div>
              </button>
            ))}
          </div>
        );

      case 1: // Select Service
        if (servicesLoading) {
          return (
            <div className="flex items-center justify-center py-12">
              <Loader2 className="w-8 h-8 animate-spin text-brand-500" />
            </div>
          );
        }
        if (availableServices.length === 0) {
          return (
            <div className="text-center py-8 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
              <p className="text-gray-500 dark:text-gray-400">
                {selectedLocation
                  ? `No services available at ${selectedLocation.name}.`
                  : 'No services available for booking at this time.'}
              </p>
            </div>
          );
        }
        return (
          <div className="space-y-4">
            {availableServices.map((service: Service) => (
              <button
                key={service.id}
                onClick={() => handleSelectService(service)}
                className="w-full text-left p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm hover:border-brand-500 hover:ring-1 hover:ring-brand-500 transition-all flex justify-between items-center"
              >
                <div>
                  <h4 className="font-semibold text-gray-900 dark:text-white">{service.name}</h4>
                  <p className="text-sm text-gray-500 dark:text-gray-400">{service.durationMinutes} min • {service.description}</p>
                </div>
                <span className="font-bold text-lg text-gray-900 dark:text-white">${service.price.toFixed(2)}</span>
              </button>
            ))}
          </div>
        );
      case 2: // Select Time
        return (
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            {availableTimes.map(time => (
              <button
                key={time.toISOString()}
                onClick={() => handleSelectTime(time)}
                className="p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm text-center hover:bg-brand-50 dark:hover:bg-brand-900/50 hover:border-brand-500 transition-colors"
              >
                <p className="text-lg font-bold text-gray-900 dark:text-white">{time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</p>
              </button>
            ))}
          </div>
        );
      case 3: // Confirmation
        return (
          <div className="p-8 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm text-center space-y-4">
            <Calendar className="mx-auto text-brand-500" size={40}/>
            <h3 className="text-xl font-bold text-gray-900 dark:text-white">Confirm Your Booking</h3>
            <div className="text-gray-500 dark:text-gray-400 space-y-2">
              <p>
                You are booking <strong className="text-gray-900 dark:text-white">{selectedService?.name}</strong> for{' '}
                <strong className="text-gray-900 dark:text-white">
                  {selectedTime?.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
                </strong>.
              </p>
              {selectedLocation && (
                <p className="flex items-center justify-center gap-1">
                  <MapPin size={16} className="text-brand-500" />
                  <strong className="text-gray-900 dark:text-white">{selectedLocation.name}</strong>
                </p>
              )}
            </div>
            <div className="pt-4">
              <button onClick={handleConfirmBooking} className="w-full max-w-xs py-3 bg-brand-600 text-white font-semibold rounded-lg hover:bg-brand-700">
                Confirm Appointment
              </button>
            </div>
          </div>
        );
      case 4: // Success
        return (
          <div className="p-8 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm text-center space-y-4">
            <Check className="mx-auto text-green-500 bg-green-100 dark:bg-green-900/50 rounded-full p-2" size={48}/>
            <h3 className="text-xl font-bold text-gray-900 dark:text-white">Appointment Booked!</h3>
            <div className="text-gray-500 dark:text-gray-400 space-y-2">
              <p>
                Your appointment for <strong className="text-gray-900 dark:text-white">{selectedService?.name}</strong> at{' '}
                <strong className="text-gray-900 dark:text-white">
                  {selectedTime?.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
                </strong> is confirmed.
              </p>
              {selectedLocation && (
                <p className="flex items-center justify-center gap-1">
                  <MapPin size={16} className="text-brand-500" />
                  <span>{selectedLocation.name}</span>
                </p>
              )}
            </div>
            <div className="pt-4 flex justify-center gap-4">
              <Link to="/" className="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700">Go to Dashboard</Link>
              <button onClick={resetFlow} className="px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700">Book Another</button>
            </div>
          </div>
        )
      default:
        return null;
    }
  };

  // Compute step labels dynamically based on whether location step is shown
  const getStepLabel = (stepNum: number): { title: string; subtitle: string } => {
    if (hasMultipleLocations) {
      // With location step: 0=Location, 1=Service, 2=Time, 3=Confirm, 4=Done
      switch (stepNum) {
        case 0: return { title: 'Step 1: Select a Location', subtitle: 'Choose your preferred location.' };
        case 1: return { title: 'Step 2: Select a Service', subtitle: selectedLocation ? `Services at ${selectedLocation.name}` : 'Pick from our list of available services.' };
        case 2: return { title: 'Step 3: Choose a Time', subtitle: `Available times for ${new Date().toLocaleDateString()}` };
        case 3: return { title: 'Step 4: Confirm Details', subtitle: 'Please review your appointment details below.' };
        case 4: return { title: 'Booking Confirmed', subtitle: "We've sent a confirmation to your email." };
        default: return { title: '', subtitle: '' };
      }
    } else {
      // Without location step: 1=Service, 2=Time, 3=Confirm, 4=Done
      switch (stepNum) {
        case 1: return { title: 'Step 1: Select a Service', subtitle: 'Pick from our list of available services.' };
        case 2: return { title: 'Step 2: Choose a Time', subtitle: `Available times for ${new Date().toLocaleDateString()}` };
        case 3: return { title: 'Step 3: Confirm Details', subtitle: 'Please review your appointment details below.' };
        case 4: return { title: 'Booking Confirmed', subtitle: "We've sent a confirmation to your email." };
        default: return { title: '', subtitle: '' };
      }
    }
  };

  const { title: stepTitle, subtitle: stepSubtitle } = getStepLabel(step);

  return (
    <div className="max-w-3xl mx-auto">
      <div className="flex items-center gap-4 mb-6">
        {step > minStep && step < 4 && (
          <button onClick={() => setStep(s => s - 1)} className="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700">
            <ChevronLeft size={20} />
          </button>
        )}
        <div>
          <h2 className="text-2xl font-bold text-gray-900 dark:text-white">
            {stepTitle}
          </h2>
          <p className="text-gray-500 dark:text-gray-400">
            {stepSubtitle}
          </p>
        </div>
      </div>

      {/* Selected location indicator (shown after location is selected) */}
      {selectedLocation && step > 0 && step < 4 && (
        <div className="mb-4 px-3 py-2 bg-brand-50 dark:bg-brand-900/20 border border-brand-200 dark:border-brand-800 rounded-lg inline-flex items-center gap-2 text-sm text-brand-700 dark:text-brand-300">
          <MapPin size={16} />
          <span>{selectedLocation.name}</span>
          {hasMultipleLocations && (
            <button
              onClick={() => setStep(0)}
              className="ml-2 text-brand-600 dark:text-brand-400 hover:underline"
            >
              Change
            </button>
          )}
        </div>
      )}

      {renderStepContent()}
    </div>
  );
};

export default BookingPage;