import { Button } from '@/components/ui/button';
import {
  ResponsiveDialog,
  ResponsiveDialogClose,
  ResponsiveDialogContent,
  ResponsiveDialogDescription,
  ResponsiveDialogFooter,
  ResponsiveDialogHeader,
  ResponsiveDialogTitle,
} from '@/components/ui/responsive-dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import type { AdminBooking } from '@repo/api-contract';
import { CalendarSync } from 'lucide-react';
import { useMemo, useState } from 'react';
import { useBooking } from '../booking-provider';
import {
  getDayOfWeek,
  getNowTime,
  isTodayIso,
  minutesToTime,
  timeToMinutes,
} from '../lib/booking-time';

interface BookingRescheduleDialogProps {
  booking: AdminBooking;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

export function BookingRescheduleDialog({
  booking,
  open,
  onOpenChange,
}: BookingRescheduleDialogProps) {
  const { courts, bookings, rescheduleBooking } = useBooking();

  const [courtId, setCourtId] = useState(booking.courtId);
  const [startTime, setStartTime] = useState(booking.startTime);

  const sportId = booking.sport.id;
  const filteredCourts = useMemo(
    () => courts.filter((c) => c.sportId === sportId),
    [courts, sportId]
  );

  const selectedCourt = filteredCourts.find((c) => c.id === courtId);
  const dayOfWeek = getDayOfWeek(booking.date);

  const availableStartTimes = useMemo(() => {
    if (!selectedCourt) return [];

    const times: string[] = [];
    const dayAvailability = selectedCourt.availability
      .filter((range) => range.dayOfWeek === dayOfWeek)
      .sort((a, b) => timeToMinutes(a.startTime) - timeToMinutes(b.startTime));

    const courtBookings = bookings.filter(
      (b) =>
        b.date === booking.date &&
        b.courtId === selectedCourt.id &&
        b.id !== booking.id &&
        b.status !== 'CANCELLED'
    );

    for (const range of dayAvailability) {
      const start = timeToMinutes(range.startTime);
      const end = timeToMinutes(range.endTime);

      for (
        let minute = start;
        minute + selectedCourt.slotDurationMinutes <= end;
        minute += selectedCourt.slotDurationMinutes
      ) {
        const slotEnd = minute + selectedCourt.slotDurationMinutes;

        if (isTodayIso(booking.date) && minute <= timeToMinutes(getNowTime())) continue;

        const isBooked = courtBookings.some((b) => {
          const bookingStart = timeToMinutes(b.startTime);
          const bookingEnd = timeToMinutes(b.endTime);
          return minute < bookingEnd && slotEnd > bookingStart;
        });

        if (!isBooked) {
          times.push(minutesToTime(minute));
        }
      }
    }

    return times;
  }, [bookings, booking.date, booking.id, dayOfWeek, selectedCourt]);

  const hasChanges = courtId !== booking.courtId || startTime !== booking.startTime;

  const handleConfirm = () => {
    if (!hasChanges) return;

    const payload: Record<string, string> = {};
    if (courtId !== booking.courtId) payload.courtId = courtId;
    if (startTime !== booking.startTime) payload.startTime = startTime;

    rescheduleBooking(booking.id, payload);
    onOpenChange(false);
  };

  const handleOpenChange = (newOpen: boolean) => {
    if (newOpen) {
      setCourtId(booking.courtId);
      setStartTime(booking.startTime);
    }
    onOpenChange(newOpen);
  };

  return (
    <ResponsiveDialog open={open} onOpenChange={handleOpenChange}>
      <ResponsiveDialogContent>
        <ResponsiveDialogHeader>
          <ResponsiveDialogTitle>Reprogramar reserva</ResponsiveDialogTitle>
          <ResponsiveDialogDescription>
            Cambiá la cancha y/o el horario de la reserva para el mismo día.
          </ResponsiveDialogDescription>
        </ResponsiveDialogHeader>

        <div className="space-y-4">
          <div className="rounded-lg border bg-card p-3 text-sm text-muted-foreground">
            Reserva <strong>{booking.bookingCode}</strong> &mdash; {booking.customerName}
          </div>

          <div className="space-y-2">
            <p className="text-sm font-medium">Cancha</p>
            <Select value={courtId} onValueChange={setCourtId}>
              <SelectTrigger>
                <SelectValue placeholder="Seleccionar cancha" />
              </SelectTrigger>
              <SelectContent>
                {filteredCourts.map((court) => (
                  <SelectItem key={court.id} value={court.id} disabled={court.isUnderMaintenance}>
                    <span className="flex items-center gap-2">
                      {court.name} &mdash; {court.sport.name}
                      {court.isUnderMaintenance && (
                        <span className="ml-auto text-xs text-muted-foreground">
                          (En mantenimiento)
                        </span>
                      )}
                    </span>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-2">
            <p className="text-sm font-medium">Horario</p>
            <Select
              value={startTime}
              onValueChange={setStartTime}
              disabled={!selectedCourt || availableStartTimes.length === 0}
            >
              <SelectTrigger>
                <SelectValue
                  placeholder={
                    selectedCourt
                      ? availableStartTimes.length === 0
                        ? 'Sin horarios disponibles'
                        : 'Seleccionar horario'
                      : 'Seleccioná una cancha primero'
                  }
                />
              </SelectTrigger>
              <SelectContent>
                {availableStartTimes.map((time) => {
                  const slotMinutes = timeToMinutes(time);
                  const endMinutes = slotMinutes + (selectedCourt?.slotDurationMinutes ?? 0);
                  return (
                    <SelectItem key={time} value={time}>
                      {time} &mdash; {minutesToTime(endMinutes)}
                    </SelectItem>
                  );
                })}
              </SelectContent>
            </Select>
          </div>
        </div>

        <ResponsiveDialogFooter>
          <ResponsiveDialogClose asChild>
            <Button variant="outline">Cancelar</Button>
          </ResponsiveDialogClose>
          <Button onClick={handleConfirm} disabled={!hasChanges || !startTime || !courtId}>
            <CalendarSync className="mr-2 h-4 w-4" />
            Confirmar reprogramación
          </Button>
        </ResponsiveDialogFooter>
      </ResponsiveDialogContent>
    </ResponsiveDialog>
  );
}
