
"use client";

import React, { useState, useMemo, useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { format } from "date-fns";
import { es } from 'date-fns/locale';
import { Calendar as CalendarIcon, Clock, Film, User, DollarSign } from "lucide-react";

import { movies } from "@/lib/data";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { useToast } from "@/hooks/use-toast";
import { useAutenticacion } from "@/proveedores/autenticacion";
import { useRouter } from "next/navigation";
import { Input } from "../ui/input";
import { Separator } from "../ui/separator";
import { apiClient } from "@/servicios/api-client";

const bookingSchema = z.object({
  movieId: z.string({ required_error: "Por favor selecciona una película." }),
  customMovieTitle: z.string().optional(),
  customerName: z.string().optional(), // For admin manual entry
  date: z.date({ required_error: "Por favor selecciona una fecha." }),
  time: z.string({ required_error: "Por favor selecciona una hora." }),
  // Admin fields
  roomPrice: z.number().optional(),
  menuConsumption: z.number().optional(),
  otherCharges: z.number().optional(),
  totalPrice: z.number().optional(),
}).refine(data => {
    if (data.movieId === 'custom') {
        return !!data.customMovieTitle && data.customMovieTitle.length > 0;
    }
    return true;
}, {
    message: "Por favor, escribe el nombre de la película.",
    path: ["customMovieTitle"],
});

type Reservation = {
    id: string;
    movieId: string;
    customMovieTitle?: string;
    customerName?: string;
    startTime: Date;
};

const getReservationDuration = (movieDuration: number | null): number => {
  if (movieDuration === null) return 120; // Default to 2 hours
  if (movieDuration < 120) return 120; // 2 hours
  if (movieDuration > 150) return 180; // 3 hours
  if (movieDuration > 120) return 150; // 2.5 hours
  return movieDuration; // Exact duration
};

const getBookingDurationText = (durationMinutes: number) => {
    const hours = Math.floor(durationMinutes / 60);
    const minutes = durationMinutes % 60;
    if (minutes === 0) return `${hours} horas`;
    return `${hours}h ${minutes}min`;
};

interface BookingFormProps {
    movieId?: string | null;
    isAdminBooking?: boolean;
    onBookingCreated?: () => void;
    isEditing?: boolean;
    reservation?: Reservation | null;
}

export function BookingForm({ movieId: movieIdFromQuery, isAdminBooking = false, onBookingCreated, isEditing = false, reservation = null }: BookingFormProps) {
  const { toast } = useToast();
  const { usuario, cargando } = useAutenticacion();
  const router = useRouter();
  
  const [isCalendarOpen, setIsCalendarOpen] = useState(false);
  const [bookedSlots, setBookedSlots] = useState<string[]>([]);

  const form = useForm<z.infer<typeof bookingSchema>>({
    resolver: zodResolver(bookingSchema),
    defaultValues: isEditing && reservation ? {
      movieId: reservation.customMovieTitle ? 'custom' : reservation.movieId,
      customMovieTitle: reservation.customMovieTitle || '',
      customerName: reservation.customerName || '',
      date: reservation.startTime.toDate(),
      time: format(reservation.startTime.toDate(), 'HH:mm'),
    } : {
      movieId: movieIdFromQuery || undefined,
      customMovieTitle: '',
      customerName: '',
      date: undefined,
      time: undefined,
      roomPrice: 0,
      menuConsumption: 0,
      otherCharges: 0,
      totalPrice: 0,
    }
  });
  
  const selectedMovieId = form.watch("movieId");
  const selectedTime = form.watch("time");
  const selectedDate = form.watch("date");
  const roomPrice = form.watch("roomPrice") || 0;
  const menuConsumption = form.watch("menuConsumption") || 0;
  const otherCharges = form.watch("otherCharges") || 0;

  useEffect(() => {
    const total = (roomPrice) + (menuConsumption) + (otherCharges);
    form.setValue("totalPrice", total);
  }, [roomPrice, menuConsumption, otherCharges, form]);

  useEffect(() => {
    if (selectedDate) {
      const fetchBookedSlots = async () => {
        try {
          const dateStr = format(selectedDate, 'yyyy-MM-dd');
          const response = await apiClient.get(`/api/reservaciones/slots-ocupados?fecha=${dateStr}`);
          
          let slots: string[] = [];
          if (response && Array.isArray(response.data)) {
            slots = response.data;
          } else if (response && response.slots && Array.isArray(response.slots)) {
            slots = response.slots;
          }
          
          // Exclude current reservation when editing
          if (isEditing && reservation?.id) {
            slots = slots.filter(slot => slot !== format(reservation.startTime, 'HH:mm'));
          }
          
          setBookedSlots(slots);
        } catch (error) {
          // If endpoint doesn't exist yet, set empty slots
          console.log("Could not fetch booked slots:", error);
          setBookedSlots([]);
        }
      };

      fetchBookedSlots();
    } else {
      setBookedSlots([]);
    }
  }, [selectedDate, isEditing, reservation?.id]);

  const selectedMovie = useMemo(() => {
    if (!selectedMovieId || selectedMovieId === 'custom') return null;
    return movies.find(m => m.id.toString() === selectedMovieId) || null;
  }, [selectedMovieId]);

  const reservationDuration = useMemo(() => {
    // For custom movies, default to 2 hours
    if (selectedMovieId === 'custom') return 120;
    return getReservationDuration(selectedMovie?.duration ?? null);
  }, [selectedMovie, selectedMovieId]);

  const timeSlots = useMemo(() => {
      const slots: string[] = [];
      const startTime = 15 * 60; // 3:00 PM
      const endTime = 22 * 60; // 10:00 PM
      
      let currentTime = startTime;
      while(currentTime <= endTime) {
        const hours = Math.floor(currentTime / 60);
        const minutes = currentTime % 60;
        slots.push(`${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`);
        currentTime += 30; // generate slots every 30 mins
      }
      
      if (!selectedMovieId) return slots;

      // Filter slots that are too late for the movie duration
      return slots.filter(slot => {
        const [hours, minutes] = slot.split(':').map(Number);
        const slotTimeInMinutes = hours * 60 + minutes;
        return slotTimeInMinutes + reservationDuration <= (24 * 60); // Assuming closing time is midnight for this logic
      });

  }, [reservationDuration, selectedMovieId]);

  useEffect(() => {
    if (selectedTime && !timeSlots.includes(selectedTime)) {
        form.resetField("time");
    }
  }, [selectedMovieId, selectedTime, timeSlots, form]);


  function onSubmit(values: z.infer<typeof bookingSchema>) {
    if (!isAdminBooking && !isEditing) {
        if (cargando) {
            toast({ title: "Por favor espera", description: "Verificando autenticación..." });
            return;
        }
        
        if (!usuario) {
            toast({ title: "Acción requerida", description: "Inicia sesión para reservar." });
            router.push('/login');
            return;
        }
    }

    const [hours, minutes] = values.time.split(':').map(Number);
    const startTime = new Date(values.date);
    startTime.setHours(hours, minutes, 0, 0);

    const endTime = new Date(startTime.getTime() + reservationDuration * 60000);

    const isCustomMovie = values.movieId === 'custom';

    const reservationData: any = {
      usuario_id: isAdminBooking ? null : (reservation?.usuario_id || usuario?.id),
      pelicula_id: isCustomMovie ? null : values.movieId,
      titulo_pelicula: isCustomMovie ? null : movies.find(m => m.id.toString() === values.movieId)?.title,
      titulo_personalizado: isCustomMovie ? values.customMovieTitle : null,
      fecha_inicio: startTime.toISOString(),
      fecha_fin: endTime.toISOString(),
      estado: isCustomMovie ? 'pending' : 'confirmed',
    };

    if (isAdminBooking || (isEditing && isAdminBooking)) {
        reservationData.nombre_cliente = values.customerName || '';
        reservationData.precio_sala = values.roomPrice || 0;
        reservationData.consumo_menu = values.menuConsumption || 0;
        reservationData.otros_cargos = values.otherCharges || 0;
        reservationData.precio_total = values.totalPrice || 0;
    }

    // TODO: Conectar con API del backend para guardar reservación
    toast({
        title: isCustomMovie ? "¡Solicitud Enviada!" : "¡Reserva Confirmada!",
        description: isCustomMovie
            ? `Tu solicitud para "${values.customMovieTitle}" ha sido enviada para aprobación.`
            : `Has reservado para el ${format(values.date, "PPP", { locale: es })} a las ${values.time}.`,
        variant: "default",
    });
    
    if (onBookingCreated) {
        onBookingCreated();
    } else {
        form.reset({ movieId: movieIdFromQuery || undefined, date: undefined, time: undefined });
    }
  }
  
  const formRef = React.useRef<HTMLFormElement>(null);


  return (
      <Card className="w-full max-w-2xl shadow-none border-none bg-transparent">
        <CardHeader className="text-center">
          <CardTitle className="text-3xl font-headline">
             {isEditing ? 'Modificar Reserva' : (isAdminBooking ? 'Añadir Cuenta/Boleta Manual' : 'Reserva tu Sala de Videos')}
          </CardTitle>
          <CardDescription>
            {isEditing ? 'Ajusta los detalles de tu reserva.' : (isAdminBooking ? 'Registra una cuenta para un cliente para las estadísticas.' : 'Completa el formulario para asegurar tu experiencia.')}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <Form {...form}>
            <form ref={formRef} onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
              <FormField
                control={form.control}
                name="movieId"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel className="flex items-center gap-2"><Film /> Película / Evento</FormLabel>
                    <Select onValueChange={field.onChange} value={field.value}>
                      <FormControl>
                        <SelectTrigger>
                          <SelectValue placeholder="Selecciona una película o evento..." />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        {movies.map((movie) => (
                          <SelectItem key={movie.id} value={movie.id.toString()}>
                            {movie.title}
                          </SelectItem>
                        ))}
                        <SelectItem value="custom">Otra (Escribir manualmente)</SelectItem>
                      </SelectContent>
                    </Select>
                    <FormMessage />
                  </FormItem>
                )}
              />
              
              {selectedMovieId === 'custom' && (
                 <FormField
                    control={form.control}
                    name="customMovieTitle"
                    render={({ field }) => (
                    <FormItem>
                        <FormLabel>Nombre de la Película / Evento Solicitado</FormLabel>
                        <FormControl>
                            <Input placeholder="Ej: El Padrino, Cumpleaños, etc." {...field} />
                        </FormControl>
                        <FormMessage />
                    </FormItem>
                    )}
                />
              )}
              
              {isAdminBooking && (
                <FormField
                    control={form.control}
                    name="customerName"
                    render={({ field }) => (
                    <FormItem>
                        <FormLabel className="flex items-center gap-2"><User /> Nombre del Cliente</FormLabel>
                        <FormControl>
                            <Input placeholder="Ej: Juan Pérez" {...field} />
                        </FormControl>
                        <FormMessage />
                    </FormItem>
                    )}
                />
              )}


              <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
                <FormField
                  control={form.control}
                  name="date"
                  render={({ field }) => (
                    <FormItem className="flex flex-col">
                      <FormLabel className="flex items-center gap-2"><CalendarIcon /> Fecha</FormLabel>
                      <Popover open={isCalendarOpen} onOpenChange={setIsCalendarOpen}>
                        <PopoverTrigger asChild>
                          <FormControl>
                            <Button
                              variant={"outline"}
                              className={cn("w-full justify-start text-left font-normal", !field.value && "text-muted-foreground")}
                            >
                              <CalendarIcon className="mr-2 h-4 w-4" />
                              {field.value ? format(field.value, "PPP", { locale: es }) : <span>Elige una fecha</span>}
                            </Button>
                          </FormControl>
                        </PopoverTrigger>
                        <PopoverContent className="w-auto p-0" align="start">
                          <Calendar
                            mode="single"
                            selected={field.value}
                            onSelect={(date) => {
                                field.onChange(date);
                                setIsCalendarOpen(false);
                            }}
                            disabled={(date) => date < new Date(new Date().setHours(0,0,0,0))}
                            initialFocus
                            locale={es}
                          />
                        </PopoverContent>
                      </Popover>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name="time"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel className="flex items-center gap-2"><Clock /> Hora</FormLabel>
                      <Select onValueChange={field.onChange} value={field.value}>
                        <FormControl>
                          <SelectTrigger>
                             <SelectValue placeholder={"Selecciona una hora..."} />
                          </SelectTrigger>
                        </FormControl>
                        <SelectContent className="max-h-60">
                          {timeSlots.map((slot) => (
                            <SelectItem key={slot} value={slot} disabled={bookedSlots.includes(slot)}>{slot}</SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </div>

                {isAdminBooking && (
                    <div className="space-y-6 rounded-lg border border-dashed p-4">
                        <h3 className="text-lg font-medium text-center text-muted-foreground">Detalles de la Boleta</h3>
                        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                             <FormField
                                control={form.control}
                                name="roomPrice"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Precio de Sala (S/)</FormLabel>
                                        <FormControl>
                                            <Input type="number" placeholder="30.00" {...field} onChange={e => field.onChange(parseFloat(e.target.value) || 0)} />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />
                            <FormField
                                control={form.control}
                                name="menuConsumption"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Consumo del Menú (S/)</FormLabel>
                                        <FormControl>
                                            <Input type="number" placeholder="15.50" {...field} onChange={e => field.onChange(parseFloat(e.target.value) || 0)} />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />
                            <FormField
                                control={form.control}
                                name="otherCharges"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Cargos Adicionales (S/)</FormLabel>
                                        <FormControl>
                                            <Input type="number" placeholder="5.00" {...field} onChange={e => field.onChange(parseFloat(e.target.value) || 0)} />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />
                        </div>
                        <Separator />
                        <FormField
                            control={form.control}
                            name="totalPrice"
                            render={({ field }) => (
                                <FormItem>
                                    <div className="flex justify-between items-center">
                                        <FormLabel className="text-lg font-semibold">Precio Total (S/)</FormLabel>
                                        <FormControl>
                                            <Input type="number" {...field} readOnly className="w-auto text-lg font-bold border-none bg-transparent text-right" />
                                        </FormControl>
                                    </div>
                                     <FormMessage />
                                </FormItem>
                            )}
                        />
                    </div>
                )}


                <Button
                    type="submit"
                    className="w-full text-lg font-bold py-6 group transition-all duration-300 ease-in-out transform hover:scale-105"
                    disabled={cargando}
                >
                    {cargando ? 'Cargando...' : (isEditing ? 'Guardar Cambios' : (selectedMovieId === 'custom' ? 'Enviar Solicitud' : 'Confirmar Reserva'))}
                </Button>
            </form>
          </Form>
        </CardContent>
      </Card>
  );
}

    