import { useState, useEffect, useMemo } from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { queryClient } from "@/client/rpc-client";

// Feature flag for multi-treatments availability API compatibility
const USE_MULTI_TREATMENTS_AVAILABILITY = true;

export function BookingForm() {
  const [selectedTreatments, setSelectedTreatments] = useState<Array<{id: string, name: string, duration: number, price: number}>>([]);
  const [customerName, setCustomerName] = useState("");
  const [customerEmail, setCustomerEmail] = useState("");
  const [customerPhone, setCustomerPhone] = useState("");
  const [appointmentDate, setAppointmentDate] = useState("");
  const [selectedTime, setSelectedTime] = useState("");
  const [notes, setNotes] = useState("");
  const [agbAccepted, setAgbAccepted] = useState(false);
  const [ageConfirmed, setAgeConfirmed] = useState(false);
  const [inspirationPhoto, setInspirationPhoto] = useState<string>("");
  const [photoPreview, setPhotoPreview] = useState<string>("");
  const [errorMessage, setErrorMessage] = useState<string>("");
  const [isInitialized, setIsInitialized] = useState(false);

  // Load saved customer data from localStorage on mount
  useEffect(() => {
    const savedName = localStorage.getItem("bookingForm_customerName");
    const savedEmail = localStorage.getItem("bookingForm_customerEmail");
    const savedPhone = localStorage.getItem("bookingForm_customerPhone");
    
    if (savedName) setCustomerName(savedName);
    if (savedEmail) setCustomerEmail(savedEmail);
    if (savedPhone) setCustomerPhone(savedPhone);
    
    setIsInitialized(true);
  }, []);

  // Save customer data to localStorage when it changes (after initial load)
  useEffect(() => {
    if (!isInitialized) return;
    if (customerName) {
      localStorage.setItem("bookingForm_customerName", customerName);
    } else {
      localStorage.removeItem("bookingForm_customerName");
    }
  }, [customerName, isInitialized]);

  useEffect(() => {
    if (!isInitialized) return;
    if (customerEmail) {
      localStorage.setItem("bookingForm_customerEmail", customerEmail);
    } else {
      localStorage.removeItem("bookingForm_customerEmail");
    }
  }, [customerEmail, isInitialized]);

  useEffect(() => {
    if (!isInitialized) return;
    if (customerPhone) {
      localStorage.setItem("bookingForm_customerPhone", customerPhone);
    } else {
      localStorage.removeItem("bookingForm_customerPhone");
    }
  }, [customerPhone, isInitialized]);

  const { data: treatments } = useQuery(
    queryClient.treatments.live.list.experimental_liveOptions()
  );

  // Comment 3: Compute total duration and price once per render
  const totalDuration = useMemo(
    () => selectedTreatments.reduce((sum, t) => sum + t.duration, 0),
    [selectedTreatments]
  );
  
  const totalPrice = useMemo(
    () => selectedTreatments.reduce((sum, t) => sum + t.price, 0),
    [selectedTreatments]
  );

  // Comment 1: Dynamische Verfügbarkeitsabfrage mit Kompatibilitäts-Fallback
  const availabilityQueryInput = USE_MULTI_TREATMENTS_AVAILABILITY
    ? { date: appointmentDate, treatmentIds: selectedTreatments.map(t => t.id) }
    : { date: appointmentDate, treatmentId: selectedTreatments[0]?.id ?? "" };

  const availabilityQueryEnabled = USE_MULTI_TREATMENTS_AVAILABILITY
    ? !!appointmentDate && selectedTreatments.length > 0
    : !!appointmentDate && selectedTreatments.length > 0;

  const { data: availableTimes, isLoading, isFetching, error } = useQuery({
    ...queryClient.recurringAvailability.getAvailableTimes.queryOptions({ 
      input: availabilityQueryInput as any
    }),
    enabled: availabilityQueryEnabled
  });

  const { mutate: createBooking, isPending } = useMutation(
    queryClient.bookings.create.mutationOptions()
  );

  // Comment 2: Handle treatment checkbox toggle with functional state updates
  const handleTreatmentToggle = (treatment: {id: string, name: string, duration: number, price: number}) => {
    setSelectedTreatments((prev) => {
      const isSelected = prev.some(t => t.id === treatment.id);
      
      if (isSelected) {
        // Remove from selection
        return prev.filter(t => t.id !== treatment.id);
      } else if (prev.length < 3) {
        // Add to selection (only if limit not reached)
        return [...prev, {
          id: treatment.id,
          name: treatment.name,
          duration: treatment.duration,
          price: treatment.price
        }];
      }
      
      // Return unchanged if limit reached
      return prev;
    });
    
    // Clear selected time when treatments change
    setSelectedTime("");
  };

  // Comment 4: Reconcile selectedTreatments when treatments list changes
  useEffect(() => {
    if (!treatments) return;
    
    setSelectedTreatments((prev) => {
      const validTreatments = prev.filter((selected) =>
        treatments.some((t) => t.id === selected.id)
      );
      
      // Only update state if something changed to avoid unnecessary re-renders
      if (validTreatments.length !== prev.length) {
        return validTreatments;
      }
      return prev;
    });
  }, [treatments]);

  // Clear selectedTime when it becomes invalid
  useEffect(() => {
    if (selectedTime && availableTimes && !availableTimes.includes(selectedTime)) {
      setSelectedTime("");
    }
  }, [availableTimes, selectedTime]);

  // Helper function for local date in YYYY-MM-DD format
  const getLocalYmd = () => {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
  };

  const handlePhotoUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    
    // Check file size (max 2MB for better performance)
    if (file.size > 2 * 1024 * 1024) {
      alert("Das Foto ist zu groß. Bitte wähle ein Bild unter 2MB.");
      return;
    }

    // Check file type
    if (!file.type.startsWith('image/')) {
      alert("Bitte wähle nur Bilddateien aus.");
      return;
    }

    // Compress the image before converting to base64
    const compressImage = (file: File, maxWidth: number = 800, quality: number = 0.8): Promise<string> => {
      return new Promise((resolve, reject) => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        const img = new Image();
        
        img.onload = () => {
          // Calculate new dimensions
          let { width, height } = img;
          if (width > maxWidth) {
            height = (height * maxWidth) / width;
            width = maxWidth;
          }
          
          canvas.width = width;
          canvas.height = height;
          
          // Draw and compress
          ctx?.drawImage(img, 0, 0, width, height);
          const compressedDataUrl = canvas.toDataURL('image/jpeg', quality);
          resolve(compressedDataUrl);
        };
        
        img.onerror = reject;
        img.src = URL.createObjectURL(file);
      });
    };

    try {
      const compressedDataUrl = await compressImage(file);
      setInspirationPhoto(compressedDataUrl);
      setPhotoPreview(compressedDataUrl);
      // console.log(`Photo compressed: ${file.size} bytes → ${compressedDataUrl.length} chars`);
    } catch (error) {
      console.error('Photo compression failed:', error);
      alert('Fehler beim Verarbeiten des Bildes. Bitte versuche es mit einem anderen Bild.');
      return;
    }

  };

  const removePhoto = () => {
    setInspirationPhoto("");
    setPhotoPreview("");
    // Reset file input
    const fileInput = document.getElementById('photo-upload') as HTMLInputElement;
    if (fileInput) fileInput.value = '';
  };


  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setErrorMessage(""); // Clear any previous error messages
    
    // console.log("Form submitted with data:", {
    //   selectedTreatments,
    //   customerName,
    //   customerEmail,
    //   customerPhone,
    //   appointmentDate,
    //   selectedSlotId,
    //   agbAccepted
    // });
    
    if (selectedTreatments.length === 0 || !customerName || !customerEmail || !customerPhone || !appointmentDate || !selectedTime) {
      if (selectedTreatments.length === 0) {
        setErrorMessage("Bitte wähle mindestens eine Behandlung aus.");
      } else {
        setErrorMessage("Bitte fülle alle erforderlichen Felder aus.");
      }
      return;
    }
    if (!agbAccepted) {
      setErrorMessage("Bitte bestätige die Kenntnisnahme der Allgemeinen Geschäftsbedingungen.");
      return;
    }
    if (!ageConfirmed) {
      setErrorMessage("Bitte bestätige, dass du mindestens 16 Jahre alt bist.");
      return;
    }

    // Email validation now handled in backend before booking creation
    const appointmentTime = selectedTime;
    // console.log("Creating booking with data:", {
    //   treatments: selectedTreatments,
    //   customerName,
    //   customerEmail,
    //   customerPhone,
    //   appointmentDate,
    //   appointmentTime,
    //   notes,
    //   inspirationPhoto
    // });
    createBooking(
      {
        treatments: selectedTreatments,
        customerName,
        customerEmail,
        customerPhone,
        appointmentDate,
        appointmentTime,
        notes,
        inspirationPhoto,
      },
      {
        onSuccess: () => {
          setSelectedTreatments([]);
          setCustomerName("");
          setCustomerEmail("");
          setCustomerPhone("");
          setAppointmentDate("");
          setSelectedTime("");
          setNotes("");
          setAgbAccepted(false);
          setAgeConfirmed(false);
          setInspirationPhoto("");
          setPhotoPreview("");
          setErrorMessage("");
          // Reset file input
          const fileInput = document.getElementById('photo-upload') as HTMLInputElement;
          if (fileInput) fileInput.value = '';
          alert("Buchung erfolgreich erstellt! Wir werden dich kontaktieren, um deinen Termin zu bestätigen.");
        },
        onError: (error: any) => {
          console.error("Booking error:", error);
          
          // Simple error handling for oRPC errors
          let errorText = "Ein unbekannter Fehler ist aufgetreten.";
          
          if (error?.cause?.message) {
            errorText = error.cause.message;
          } else if (error?.message && error.message !== "Internal server error") {
            errorText = error.message;
          }
          
          setErrorMessage(errorText);
        },
      }
    );
  };

  // Dynamische Zeitauswahl: Kunde wählt beliebiges zukünftiges Datum,
  // System berechnet verfügbare Zeiten in 15-Minuten-Intervallen basierend auf wiederkehrenden Regeln

  return (
    <div className="max-w-2xl mx-auto bg-white rounded-lg shadow-lg p-6">
      <h2 className="text-2xl font-bold text-gray-900 mb-6">Buche deine Nagelbehandlung</h2>
      
      <form onSubmit={handleSubmit} className="space-y-6">
        {/* Treatment Selection */}
        <div>
          <div className="flex justify-between items-center mb-2">
            <label className="block text-sm font-medium text-gray-700">
              Behandlungen auswählen (1-3) *
            </label>
            <span className="text-sm text-gray-600">
              {selectedTreatments.length} von 3 ausgewählt
            </span>
          </div>
          
          {/* Checkbox List Container */}
          <div className="max-h-96 overflow-y-auto border border-gray-300 rounded-md p-3 space-y-2" aria-label="Wähle bis zu 3 Behandlungen">
            {treatments?.map((treatment) => {
              const isSelected = selectedTreatments.some(t => t.id === treatment.id);
              const isDisabled = selectedTreatments.length >= 3 && !isSelected;
              
              return (
                <div key={treatment.id} className="flex items-start space-x-3">
                  <input
                    type="checkbox"
                    id={`treatment-${treatment.id}`}
                    checked={isSelected}
                    disabled={isDisabled}
                    onChange={() => handleTreatmentToggle({
                      id: treatment.id,
                      name: treatment.name,
                      duration: treatment.duration,
                      price: treatment.price
                    })}
                    className="h-4 w-4 text-pink-600 border-gray-300 rounded flex-shrink-0 mt-1"
                  />
                  <label htmlFor={`treatment-${treatment.id}`} className={`flex-1 text-sm cursor-pointer ${isDisabled ? 'text-gray-400' : 'text-gray-700'}`}>
                    {treatment.name} - {treatment.duration} Min - {(treatment.price / 100).toFixed(2)} €
                  </label>
                </div>
              );
            })}
          </div>
          
          {/* Treatment Descriptions */}
          {selectedTreatments.length > 0 && (
            <div className="mt-3 space-y-2">
              {selectedTreatments.map((selectedTreatment) => {
                const fullTreatment = treatments?.find(t => t.id === selectedTreatment.id);
                return fullTreatment ? (
                  <p key={selectedTreatment.id} className="text-sm text-gray-600">
                    <span className="font-medium">{fullTreatment.name}:</span> {fullTreatment.description}
                  </p>
                ) : null;
              })}
            </div>
          )}
          
          {/* Live Calculation Display */}
          {selectedTreatments.length > 0 && (
            <div className="mt-3 bg-pink-50 border border-pink-200 rounded-lg p-4">
              <p className="font-semibold text-pink-700">
                📊 Gesamt: {totalDuration} Min | {(totalPrice / 100).toFixed(2)} €
              </p>
            </div>
          )}
        </div>

        {/* Customer Information */}
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-2">
              Vollständiger Name *
            </label>
            <input
              type="text"
              value={customerName}
              onChange={(e) => setCustomerName(e.target.value)}
              className="w-full p-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-pink-500 focus:border-pink-500"
              required
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-2">
              E-Mail *
            </label>
            <input
              type="email"
              value={customerEmail}
              onChange={(e) => setCustomerEmail(e.target.value)}
              className="w-full p-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-pink-500 focus:border-pink-500"
              required
            />
          </div>
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-2">
            Telefonnummer *
          </label>
          <input
            type="tel"
            value={customerPhone}
            onChange={(e) => setCustomerPhone(e.target.value)}
            className="w-full p-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-pink-500 focus:border-pink-500"
            required
          />
        </div>

        {/* Date and Time Selection */}
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-2">
              Wunschdatum *
            </label>
            <input
              type="date"
              value={appointmentDate}
              onChange={(e) => { setAppointmentDate(e.target.value); setSelectedTime(""); }}
              min={getLocalYmd()}
              className="w-full p-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-pink-500 focus:border-pink-500"
              required
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-2">
              Verfügbare Uhrzeit (15-Min-Raster) *
            </label>
            <select
              value={selectedTime}
              onChange={(e) => setSelectedTime(e.target.value)}
              className="w-full p-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-pink-500 focus:border-pink-500"
              disabled={!appointmentDate || selectedTreatments.length === 0 || isLoading || isFetching}
              required
            >
              <option value="">Zeit auswählen</option>
              {availableTimes?.map((time) => (
                <option key={time} value={time}>
                  {time}
                </option>
              ))}
            </select>
            {appointmentDate && selectedTreatments.length > 0 && isLoading && (
              <p className="mt-2 text-sm text-gray-500">
                Lade verfügbare Zeiten...
              </p>
            )}
            {appointmentDate && selectedTreatments.length > 0 && error && (
              <p className="mt-2 text-sm text-red-500">
                Fehler beim Laden der verfügbaren Zeiten. Bitte versuche es erneut.
              </p>
            )}
            {appointmentDate && selectedTreatments.length > 0 && !isLoading && !isFetching && !error && (!availableTimes || availableTimes.length === 0) && (
              <p className="mt-2 text-sm text-gray-500">
                Keine verfügbaren Zeiten für dieses Datum. Bitte wähle ein anderes Datum.
              </p>
            )}
            {selectedTreatments.length > 0 && (
              <p className="mt-1 text-xs text-gray-500">Gesamtdauer: {totalDuration} Minuten</p>
            )}
          </div>
        </div>

        {/* Notes */}
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-2">
            Zusätzliche Notizen
          </label>
          <textarea
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
            rows={3}
            className="w-full p-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-pink-500 focus:border-pink-500"
            placeholder="Besondere Wünsche oder Informationen, Allergien, etc..."
          />
        </div>

        {/* Inspiration Photo Upload */}
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-2">
            Inspiration/Beispiel-Foto (optional)
          </label>
          <div className="space-y-3">
            <input
              id="photo-upload"
              type="file"
              accept="image/*"
              onChange={handlePhotoUpload}
              className="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-medium file:bg-pink-50 file:text-pink-700 hover:file:bg-pink-100"
            />
            {photoPreview && (
              <div className="relative inline-block">
                <img
                  src={photoPreview}
                  alt="Inspiration Preview"
                  className="w-32 h-32 object-cover rounded-lg border border-gray-200"
                />
                <button
                  type="button"
                  onClick={removePhoto}
                  className="absolute -top-2 -right-2 bg-red-500 text-white rounded-full w-6 h-6 flex items-center justify-center text-sm hover:bg-red-600"
                >
                  ×
                </button>
              </div>
            )}
            <p className="text-xs text-gray-500">
              📸 Lade ein Foto hoch, das als Inspiration für deine Nagelbehandlung dienen soll. Max. 5MB, alle Bildformate erlaubt.
            </p>
          </div>
        </div>

        {/* AGB Acceptance */}
        <div className="bg-gray-50 border border-gray-200 rounded-lg p-4 space-y-4">
          <div className="flex items-start space-x-3">
            <input
              type="checkbox"
              id="agb-acceptance"
              checked={agbAccepted}
              onChange={(e) => setAgbAccepted(e.target.checked)}
              className="mt-1 h-4 w-4 text-pink-600 focus:ring-pink-500 border-gray-300 rounded"
              required
            />
            <div className="flex-1">
              <label htmlFor="agb-acceptance" className="text-sm font-medium text-gray-700 cursor-pointer">
                Ich habe die <a 
                  href="/AGB.pdf" 
                  target="_blank" 
                  rel="noopener noreferrer"
                  className="text-pink-600 hover:text-pink-700 underline font-semibold"
                >
                  Allgemeinen Geschäftsbedingungen (AGB)
                </a> gelesen und akzeptiere diese *
              </label>
              <p className="text-xs text-gray-500 mt-1">
                📋 Die AGB enthalten wichtige Informationen zu Buchungsgebühren, Stornierungsregeln und unseren Serviceleistungen.
              </p>
            </div>
          </div>
          
          <div className="flex items-start space-x-3">
            <input
              type="checkbox"
              id="age-confirmation"
              checked={ageConfirmed}
              onChange={(e) => setAgeConfirmed(e.target.checked)}
              className="mt-1 h-4 w-4 text-pink-600 focus:ring-pink-500 border-gray-300 rounded"
              required
            />
            <div className="flex-1">
              <label htmlFor="age-confirmation" className="text-sm font-medium text-gray-700 cursor-pointer">
                Ich bestätige, dass ich mindestens 16 Jahre alt bin *
              </label>
            </div>
          </div>
        </div>

        {/* Error Message */}
        {errorMessage && (
          <div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-md mb-4">
            <div className="flex items-center">
              <svg className="w-5 h-5 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
                <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
              </svg>
              <span className="font-medium">{errorMessage}</span>
            </div>
          </div>
        )}

        <button
          type="submit"
          disabled={isPending}
          className="w-full bg-pink-600 text-white py-3 px-4 rounded-md hover:bg-pink-700 focus:ring-2 focus:ring-pink-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed font-medium"
        >
          {isPending ? "Wird gebucht..." : "Termin buchen"}
        </button>
      </form>
    </div>
  );
}