import PlayzerIcon from '@/assets/playzer-favicon-512-transparent.png';
import { Button } from '@/components/ui/button';
import { DatePicker } from '@/components/ui/date-picker';
import { Input } from '@/components/ui/input';
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet';
import { UserAvatar } from '@/components/user-avatar';
import { apiClient } from '@/lib/api-client';
import { useAuth } from '@/lib/auth';
import { useCurrentComplexStore } from '@/lib/stores/current-complex-store';
import { useTheme } from '@/lib/theme';
import { cn } from '@/lib/utils';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from '@tanstack/react-router';
import {
  CalendarDays,
  Check,
  ChevronLeft,
  ChevronRight,
  CircleDot,
  Download,
  Dumbbell,
  Grid2X2,
  Laptop,
  ListChecks,
  LogOut,
  Moon,
  MoreHorizontal,
  Plus,
  Search,
  Settings,
  Sun,
  User,
  Users,
  Wrench,
} from 'lucide-react';
import type React from 'react';
import { useMemo, useState } from 'react';
import { useBooking } from '../booking-provider';
import type { BookingCourtSchedule, BookingTimelineSegment } from '../booking.types';
import { fromIsoDateLocal, toIsoDateLocal } from '../lib/booking-time';

type MobileTab = 'panel' | 'status' | 'bookings' | 'more';

export function BookingMobile() {
  const { schedules, isLoading, isError, errorMessage } = useBooking();
  const [selectedCourtId, setSelectedCourtId] = useState<string | null>(null);
  const [search, setSearch] = useState('');
  const [activeTab, setActiveTab] = useState<MobileTab>('panel');

  const selectedSchedule = useMemo(() => {
    if (!selectedCourtId) return null;
    return schedules.find((schedule) => schedule.court.id === selectedCourtId) ?? null;
  }, [schedules, selectedCourtId]);
  const filteredSchedules = useMemo(() => {
    const query = search.trim().toLowerCase();
    if (!query) return schedules;

    return schedules.filter((schedule) => {
      return (
        schedule.court.name.toLowerCase().includes(query) ||
        schedule.court.sport.name.toLowerCase().includes(query)
      );
    });
  }, [schedules, search]);

  if (selectedSchedule) {
    return <MobileCourtDay schedule={selectedSchedule} onBack={() => setSelectedCourtId(null)} />;
  }

  return (
    <div className="min-h-dvh pb-24">
      <MobileTopBar />
      <div className="space-y-6 px-3 pt-5">
        {activeTab === 'panel' && (
          <>
            <MobilePanelHeader />
            <MobileFilters />
            <MobileSummary />

            <section className="space-y-4">
              <h2 className="text-xl font-semibold tracking-normal">Canchas</h2>
              <div className="relative">
                <Search className="pointer-events-none absolute left-3 top-1/2 size-5 -translate-y-1/2 text-muted-foreground" />
                <Input
                  className="h-12 rounded-lg border-border/70 bg-card/75 pl-11 text-sm shadow-sm"
                  placeholder="Buscar cancha..."
                  value={search}
                  onChange={(event) => setSearch(event.target.value)}
                />
              </div>

              {isLoading && (
                <div className="rounded-lg border bg-card/75 px-4 py-8 text-sm text-muted-foreground">
                  Cargando reservas...
                </div>
              )}

              {isError && !isLoading && (
                <div className="rounded-lg border bg-card/75 px-4 py-8 text-sm text-destructive">
                  {errorMessage}
                </div>
              )}

              {!isLoading && !isError && filteredSchedules.length === 0 && (
                <div className="rounded-lg border bg-card/75 px-4 py-8 text-sm text-muted-foreground">
                  No hay canchas para los filtros seleccionados.
                </div>
              )}

              {!isLoading &&
                !isError &&
                filteredSchedules.map((schedule) => (
                  <MobileCourtCard
                    key={schedule.court.id}
                    schedule={schedule}
                    onOpen={() => setSelectedCourtId(schedule.court.id)}
                  />
                ))}
            </section>
          </>
        )}

        {activeTab === 'status' && <MobileStatusTab />}
        {activeTab === 'bookings' && <MobileBookingsTab />}
        {activeTab === 'more' && <MobileMoreTab />}
      </div>
      <MobileBottomNav active={activeTab} onSelect={setActiveTab} />
    </div>
  );
}

function MobileTopBar() {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const { user, isAuthenticated, displayName, avatarUrl, signOut } = useAuth();
  const { currentComplexSlug, setCurrentComplex } = useCurrentComplexStore();
  const { theme, setTheme } = useTheme();
  const { openCreateBooking } = useBooking();
  const [open, setOpen] = useState(false);

  const myComplexesQuery = useQuery({
    queryKey: ['my-complexes'],
    enabled: isAuthenticated,
    queryFn: () => apiClient.complexes.listMine(),
  });

  const complexSlug = currentComplexSlug || myComplexesQuery.data?.[0]?.complexSlug;
  const currentComplexName = useMemo(() => {
    const complexes = myComplexesQuery.data ?? [];
    if (complexes.length === 0) return 'Mi complejo';

    const selected = complexes.find((complex) => complex.complexSlug === complexSlug);
    return selected?.complexName ?? complexes[0]?.complexName ?? 'Mi complejo';
  }, [complexSlug, myComplexesQuery.data]);

  const handleSelectComplex = async (complexId: string, nextSlug: string) => {
    await apiClient.complexes.select({ complexId });
    setCurrentComplex(nextSlug);
    await queryClient.invalidateQueries({ queryKey: ['current-complex'] });
    await queryClient.invalidateQueries({ queryKey: ['admin-bookings'] });
  };

  const handleSignOut = async () => {
    setOpen(false);
    await signOut();
    await navigate({ to: '/login' });
  };

  return (
    <header className="sticky top-0 z-30 border-b border-border/70 bg-background/85 px-3 py-4 backdrop-blur-xl">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2.5">
          <img src={PlayzerIcon} alt="Playzer" className="size-9" />
          <span className="text-xl font-bold text-primary">Playzer</span>
        </div>
        <Sheet open={open} onOpenChange={setOpen}>
          <SheetTrigger asChild>
            <button
              type="button"
              className="rounded-full ring-2 ring-transparent transition hover:ring-primary/30 focus:outline-none focus-visible:ring-primary/60"
              aria-label="Abrir menú de usuario"
            >
              <UserAvatar
                src={avatarUrl}
                alt={displayName}
                fallbackText={displayName}
                className="size-10 border border-primary/30"
              />
            </button>
          </SheetTrigger>
          <SheetContent
            side="right"
            className="w-[88vw] border-border/70 bg-background/95 p-5 backdrop-blur-xl sm:max-w-sm"
          >
            <div className="mt-6 flex flex-col gap-6">
              <div className="rounded-lg border border-border/70 bg-card/70 p-4 shadow-xl shadow-black/10">
                <div className="flex items-center gap-3">
                  <UserAvatar
                    src={avatarUrl}
                    alt={displayName}
                    fallbackText={displayName}
                    className="size-11"
                  />
                  <div className="min-w-0">
                    <p className="truncate text-sm font-medium">{displayName}</p>
                    <p className="truncate text-xs text-muted-foreground">{user?.email}</p>
                    <p className="truncate text-xs text-muted-foreground">{currentComplexName}</p>
                  </div>
                </div>
              </div>

              <Button
                className="rounded-lg shadow-lg shadow-primary/20"
                onClick={() => {
                  setOpen(false);
                  openCreateBooking();
                }}
              >
                <CalendarDays className="mr-2 size-4" />
                Reservar ahora
              </Button>

              <div className="border-t border-border/70 pt-4">
                <div className="mb-2 px-2">
                  <p className="text-xs font-medium uppercase tracking-wider text-muted-foreground">
                    Cuenta
                  </p>
                </div>

                <nav className="flex flex-col gap-1">
                  <div className="py-1">
                    <p className="px-3 py-1 text-xs text-muted-foreground">Apariencia</p>
                    {[
                      { value: 'light', label: 'Light', icon: Sun },
                      { value: 'dark', label: 'Dark', icon: Moon },
                      { value: 'system', label: 'System', icon: Laptop },
                    ].map((item) => {
                      const Icon = item.icon;

                      return (
                        <Button
                          key={item.value}
                          variant="ghost"
                          className="w-full justify-start rounded-lg"
                          onClick={() => setTheme(item.value as 'light' | 'dark' | 'system')}
                        >
                          <span className="mr-2 flex size-4 items-center justify-center">
                            {theme === item.value ? (
                              <Check className="size-4" />
                            ) : (
                              <Icon className="size-4" />
                            )}
                          </span>
                          {item.label}
                        </Button>
                      );
                    })}
                  </div>

                  {myComplexesQuery.data && myComplexesQuery.data.length > 1 && (
                    <div className="py-1">
                      <p className="px-3 py-1 text-xs text-muted-foreground">Cambiar complejo</p>
                      {myComplexesQuery.data.map((complex) => (
                        <Button
                          key={complex.id}
                          variant="ghost"
                          className="w-full justify-start rounded-lg"
                          onClick={() => {
                            setOpen(false);
                            void handleSelectComplex(complex.id, complex.complexSlug);
                          }}
                        >
                          <span className="mr-2 flex size-4 items-center justify-center">
                            {complex.complexSlug === complexSlug && <Check className="size-4" />}
                          </span>
                          {complex.complexName}
                        </Button>
                      ))}
                    </div>
                  )}

                  <Button
                    variant="ghost"
                    className="justify-start rounded-lg"
                    onClick={() => {
                      setOpen(false);
                      void navigate({ to: '/profile' });
                    }}
                  >
                    <User className="mr-2 size-4" />
                    Mi Perfil
                  </Button>

                  {currentComplexSlug && (
                    <Button
                      variant="ghost"
                      className="justify-start rounded-lg"
                      onClick={() => {
                        setOpen(false);
                        void navigate({
                          to: '/complex/$slug/edit',
                          params: { slug: currentComplexSlug },
                        });
                      }}
                    >
                      <Settings className="mr-2 size-4" />
                      Configuración
                    </Button>
                  )}

                  <Button
                    variant="ghost"
                    className="justify-start rounded-lg text-destructive hover:bg-destructive/10 hover:text-destructive"
                    onClick={() => {
                      void handleSignOut();
                    }}
                  >
                    <LogOut className="mr-2 size-4" />
                    Cerrar sesión
                  </Button>
                </nav>
              </div>
            </div>
          </SheetContent>
        </Sheet>
      </div>
    </header>
  );
}

function MobilePanelHeader() {
  const { complex, openCreateBooking } = useBooking();

  return (
    <section className="flex items-start justify-between gap-4">
      <div className="min-w-0">
        <h1 className="text-2xl font-semibold tracking-normal">Panel de Reservas</h1>
        <p className="mt-1 text-sm text-muted-foreground">
          Gestiona las canchas de {complex.complexName}
        </p>
      </div>
      <Button
        type="button"
        className="h-11 shrink-0 rounded-lg px-3 shadow-lg shadow-primary/20"
        onClick={() => openCreateBooking()}
      >
        <CalendarDays className="size-4" />
        Nueva Reserva
      </Button>
    </section>
  );
}

function MobileFilters() {
  const { selectedDate, setSelectedDate } = useBooking();

  return (
    <div>
      <DatePicker
        value={fromIsoDateLocal(selectedDate)}
        onChange={(date) =>
          setSelectedDate(date ? toIsoDateLocal(date) : toIsoDateLocal(new Date()))
        }
        className="h-12 w-full justify-center rounded-lg border-border/70 bg-card/75 px-4 text-sm font-medium"
        placeholder="Fecha"
      />
    </div>
  );
}

function MobileSummary() {
  const { summary } = useBooking();

  return (
    <section className="rounded-lg border border-border/70 bg-card/70 p-4 shadow-sm">
      <h2 className="text-lg font-medium">Resumen del día</h2>
      <div className="mt-3 grid grid-cols-3 gap-2">
        <SummaryPill
          value={summary.freeSlots}
          label="Libres"
          className="bg-primary/15 text-primary"
        />
        <SummaryPill
          value={summary.reservedSlots}
          label="Reservados"
          className="bg-reserved/15 text-reserved"
        />
        <SummaryPill
          value={summary.maintenanceSlots}
          label="Mantenim."
          className="bg-maintenance/15 text-maintenance"
        />
      </div>
    </section>
  );
}

function MobileStatusTab() {
  const {
    courts,
    selectedSportId,
    selectedStatus,
    visibleTimeRange,
    setSelectedSportId,
    setSelectedStatus,
    setVisibleTimeRange,
  } = useBooking();
  const sports = [...new Map(courts.map((court) => [court.sport.id, court.sport])).values()];
  const activeRangeValue = `${visibleTimeRange.start}-${visibleTimeRange.end}`;
  const statusOptions = [
    { value: 'all', label: 'Todos' },
    { value: 'free', label: 'Libres' },
    { value: 'reserved', label: 'Reservados' },
    { value: 'maintenance', label: 'Mantenimiento' },
  ] as const;
  const timeRangeOptions = [
    { label: '08:00 - 22:00', start: '08:00', end: '22:00' },
    { label: '06:00 - 00:00', start: '06:00', end: '23:59' },
    { label: '08:00 - 14:00', start: '08:00', end: '14:00' },
    { label: '14:00 - 22:00', start: '14:00', end: '22:00' },
  ];

  return (
    <>
      <section>
        <h1 className="text-2xl font-semibold tracking-normal">Estado</h1>
        <p className="mt-1 text-sm text-muted-foreground">Filtra disponibilidad por cancha.</p>
      </section>

      <MobileFilters />
      <MobileSummary />

      <section className="space-y-3 rounded-lg border border-border/70 bg-card/70 p-4">
        <div className="space-y-2">
          <p className="text-sm font-medium">Estado</p>
          <div className="grid grid-cols-2 gap-2">
            {statusOptions.map((option) => (
              <MobileFilterChip
                key={option.value}
                active={selectedStatus === option.value}
                label={option.label}
                onClick={() => setSelectedStatus(option.value)}
              />
            ))}
          </div>
        </div>

        <div className="space-y-2">
          <p className="text-sm font-medium">Deporte</p>
          <div className="flex gap-2 overflow-x-auto pb-1">
            <MobileFilterChip
              active={selectedSportId === 'all'}
              label="Todos"
              onClick={() => setSelectedSportId('all')}
            />
            {sports.map((sport) => (
              <MobileFilterChip
                key={sport.id}
                active={selectedSportId === sport.id}
                label={sport.name}
                onClick={() => setSelectedSportId(sport.id)}
              />
            ))}
          </div>
        </div>

        <div className="space-y-2">
          <p className="text-sm font-medium">Horario visible</p>
          <div className="grid grid-cols-2 gap-2">
            {timeRangeOptions.map((option) => (
              <MobileFilterChip
                key={`${option.start}-${option.end}`}
                active={activeRangeValue === `${option.start}-${option.end}`}
                label={option.label}
                onClick={() => setVisibleTimeRange({ start: option.start, end: option.end })}
              />
            ))}
          </div>
        </div>
      </section>

      <section className="rounded-lg border border-border/70 bg-card/70 p-4">
        <StatusLegend />
      </section>
    </>
  );
}

function MobileFilterChip({
  active,
  label,
  onClick,
}: {
  active: boolean;
  label: string;
  onClick: () => void;
}) {
  return (
    <Button
      type="button"
      variant={active ? 'default' : 'outline'}
      className={cn(
        'h-11 shrink-0 rounded-lg px-4 text-sm',
        !active && 'border-border/70 bg-secondary/45 text-muted-foreground'
      )}
      onClick={onClick}
    >
      {label}
    </Button>
  );
}

function MobileBookingsTab() {
  const { selectedDate, schedules, openBookingTools, openCreateBooking } = useBooking();
  const reservedSegments = schedules
    .flatMap((schedule) =>
      schedule.segments
        .filter((segment) => segment.booking)
        .map((segment) => ({ schedule, segment }))
    )
    .sort((a, b) => a.segment.startMinutes - b.segment.startMinutes);

  return (
    <>
      <section className="flex items-start justify-between gap-4">
        <div>
          <h1 className="text-2xl font-semibold tracking-normal">Reservas</h1>
          <p className="mt-1 text-sm text-muted-foreground">{formatMobileDate(selectedDate)}</p>
        </div>
        <Button
          type="button"
          className="h-11 shrink-0 rounded-lg px-3 shadow-lg shadow-primary/20"
          onClick={() => openCreateBooking()}
        >
          <Plus className="size-4" />
          Nueva
        </Button>
      </section>

      <MobileFilters />

      <section className="space-y-3">
        {reservedSegments.length === 0 ? (
          <div className="rounded-lg border border-border/70 bg-card/75 px-4 py-8 text-sm text-muted-foreground">
            No hay reservas para este día.
          </div>
        ) : (
          reservedSegments.map(({ schedule, segment }) => (
            <button
              key={segment.id}
              type="button"
              className="grid w-full grid-cols-[1fr_auto] items-center gap-3 rounded-lg border border-border/70 bg-card/75 p-4 text-left shadow-sm"
              onClick={() => openBookingTools(segment)}
            >
              <div className="min-w-0">
                <p className="truncate text-base font-semibold">{segment.booking?.customerName}</p>
                <p className="mt-1 text-sm text-muted-foreground">
                  {schedule.court.name} · {schedule.court.sport.name}
                </p>
              </div>
              <div className="text-right">
                <p className="text-sm font-medium">
                  {segment.startTime} - {segment.endTime}
                </p>
                <p className="mt-1 text-xs text-reserved">Reservado</p>
              </div>
            </button>
          ))
        )}
      </section>
    </>
  );
}

function MobileMoreTab() {
  const navigate = useNavigate();
  const { currentComplexSlug } = useCurrentComplexStore();
  const { openCreateBooking, exportDayReport } = useBooking();

  return (
    <>
      <section>
        <h1 className="text-2xl font-semibold tracking-normal">Más</h1>
        <p className="mt-1 text-sm text-muted-foreground">Accesos rápidos del panel.</p>
      </section>

      <section className="overflow-hidden rounded-lg border border-border/70 bg-card/75">
        <MobileMenuAction
          icon={<CalendarDays className="size-5" />}
          label="Nueva reserva"
          onClick={() => openCreateBooking()}
        />
        <MobileMenuAction
          icon={<Download className="size-5" />}
          label="Exportar reservas del día"
          onClick={exportDayReport}
        />
        <MobileMenuAction
          icon={<User className="size-5" />}
          label="Mi perfil"
          onClick={() => {
            void navigate({ to: '/profile' });
          }}
        />
        {currentComplexSlug && (
          <MobileMenuAction
            icon={<Settings className="size-5" />}
            label="Configuración del complejo"
            onClick={() => {
              void navigate({
                to: '/complex/$slug/edit',
                params: { slug: currentComplexSlug },
              });
            }}
          />
        )}
      </section>
    </>
  );
}

function MobileMenuAction({
  icon,
  label,
  onClick,
}: {
  icon: React.ReactNode;
  label: string;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      className="flex min-h-14 w-full items-center justify-between gap-3 border-b border-border/70 px-4 py-3 text-left last:border-b-0"
      onClick={onClick}
    >
      <span className="inline-flex items-center gap-3 font-medium">
        <span className="text-muted-foreground">{icon}</span>
        {label}
      </span>
      <ChevronRight className="size-5 text-muted-foreground" />
    </button>
  );
}

function formatMobileDate(date: string) {
  return new Intl.DateTimeFormat('es-AR', {
    day: 'numeric',
    month: 'long',
    year: 'numeric',
  }).format(new Date(`${date}T00:00:00`));
}

function SummaryPill({
  value,
  label,
  className,
}: {
  value: number;
  label: string;
  className: string;
}) {
  return (
    <div className={cn('rounded-lg px-2 py-2.5', className)}>
      <p className="text-2xl font-semibold leading-none">{value}</p>
      <p className="mt-2 truncate text-xs">{label}</p>
    </div>
  );
}

function MobileCourtCard({
  schedule,
  onOpen,
}: {
  schedule: BookingCourtSchedule;
  onOpen: () => void;
}) {
  const nextSegments = schedule.segments.slice(0, 5);

  return (
    <article className="rounded-lg border border-border/70 bg-card/75 p-4 shadow-sm">
      <div className="flex items-start gap-3">
        <SportIcon sportName={schedule.court.sport.name} />
        <div className="min-w-0 flex-1">
          <div className="flex items-start justify-between gap-3">
            <div>
              <h3 className="text-lg font-semibold">{schedule.court.name}</h3>
              <p className="text-sm text-muted-foreground">{schedule.court.sport.name}</p>
            </div>
            <MetricDots schedule={schedule} />
          </div>
        </div>
      </div>

      <p className="mt-5 text-sm text-muted-foreground">Próximos horarios</p>
      <div className="mt-2 grid grid-cols-5 gap-2">
        {nextSegments.map((segment) => (
          <MiniSlot key={segment.id} schedule={schedule} segment={segment} />
        ))}
      </div>

      <Button
        type="button"
        variant="outline"
        className="mt-5 h-12 w-full justify-between rounded-lg border-border/70 bg-secondary/55 px-4 text-base"
        onClick={onOpen}
      >
        <span className="flex-1 text-center">Ver día completo</span>
        <ChevronRight className="size-5 text-muted-foreground" />
      </Button>
    </article>
  );
}

function MobileCourtDay({
  schedule,
  onBack,
}: { schedule: BookingCourtSchedule; onBack: () => void }) {
  const { selectedDate, moveSelectedDate, setSelectedDate, openCreateBooking } = useBooking();

  return (
    <div className="min-h-dvh pb-24">
      <header className="sticky top-0 z-30 border-b border-border/70 bg-background/90 px-3 py-4 backdrop-blur-xl">
        <div className="flex items-center justify-between gap-3">
          <Button
            type="button"
            variant="ghost"
            size="icon"
            className="rounded-full"
            onClick={onBack}
          >
            <ChevronLeft className="size-6" />
          </Button>
          <div className="min-w-0 flex-1">
            <h1 className="truncate text-xl font-semibold">{schedule.court.name}</h1>
            <p className="text-sm text-muted-foreground">{schedule.court.sport.name}</p>
          </div>
          <Button type="button" variant="ghost" size="icon" className="rounded-full">
            <MoreHorizontal className="size-5" />
          </Button>
        </div>

        <div className="mt-5 grid grid-cols-[52px_1fr_52px] gap-3">
          <Button
            type="button"
            variant="outline"
            className="h-12 rounded-lg"
            onClick={() => moveSelectedDate(-1)}
          >
            <ChevronLeft className="size-5" />
          </Button>
          <DatePicker
            value={fromIsoDateLocal(selectedDate)}
            onChange={(date) =>
              setSelectedDate(date ? toIsoDateLocal(date) : toIsoDateLocal(new Date()))
            }
            className="h-12 rounded-lg border-border/70 bg-card/75 text-sm"
          />
          <Button
            type="button"
            variant="outline"
            className="h-12 rounded-lg"
            onClick={() => moveSelectedDate(1)}
          >
            <ChevronRight className="size-5" />
          </Button>
        </div>
      </header>

      <main className="space-y-4 px-3 pt-4">
        <section className="rounded-lg border border-border/70 bg-card/70 p-4">
          <StatusLegend />
        </section>

        <section className="overflow-hidden rounded-lg border border-border/70 bg-card/75">
          {schedule.segments.map((segment) => (
            <MobileSegmentRow key={segment.id} schedule={schedule} segment={segment} />
          ))}
        </section>
      </main>

      <div className="fixed inset-x-0 bottom-0 z-40 border-t border-border/70 bg-background/90 p-3 backdrop-blur-xl">
        <Button
          type="button"
          className="h-14 w-full rounded-lg text-base shadow-lg shadow-primary/25"
          onClick={() =>
            openCreateBooking({ courtId: schedule.court.id, sportId: schedule.court.sportId })
          }
        >
          <Plus className="size-5" />
          Nueva Reserva
        </Button>
      </div>
    </div>
  );
}

function MobileSegmentRow({
  schedule,
  segment,
}: {
  schedule: BookingCourtSchedule;
  segment: BookingTimelineSegment;
}) {
  const { openCreateBooking, openBookingTools } = useBooking();
  const isFree = segment.status === 'free';

  return (
    <button
      type="button"
      className="grid min-h-[104px] w-full grid-cols-[1fr_auto] items-center gap-4 border-b border-border/70 px-5 py-4 text-left last:border-b-0"
      onClick={() => {
        if (isFree) {
          openCreateBooking({
            courtId: schedule.court.id,
            sportId: schedule.court.sportId,
            startTime: segment.startTime,
          });
          return;
        }
        openBookingTools(segment);
      }}
    >
      <div className="min-w-0">
        <p className="text-xl font-medium">
          {segment.startTime} - {segment.endTime}
        </p>
        <SegmentStatusLine segment={segment} />
      </div>

      {isFree ? (
        <span className="rounded-lg border border-primary/70 px-4 py-3 font-medium text-primary">
          Reservar
        </span>
      ) : (
        <div className="max-w-[132px] text-right">
          <p className="truncate text-sm font-medium">
            {segment.booking?.customerName ?? 'Mantenimiento'}
          </p>
          <p className="mt-2 inline-flex items-center gap-1 text-sm text-muted-foreground">
            {segment.status === 'maintenance' ? (
              <Wrench className="size-4" />
            ) : (
              <Users className="size-4" />
            )}
            {segment.booking?.customerPhone ?? 'Personal'}
          </p>
        </div>
      )}
    </button>
  );
}

function SegmentStatusLine({ segment }: { segment: BookingTimelineSegment }) {
  const status = segment.status;
  const label = status === 'free' ? 'Libre' : status === 'reserved' ? 'Reservado' : 'Mantenimiento';

  return (
    <p
      className={cn(
        'mt-2 inline-flex items-center gap-2 text-sm',
        status === 'free' && 'text-primary',
        status === 'reserved' && 'text-reserved',
        status === 'maintenance' && 'text-maintenance'
      )}
    >
      <span
        className={cn(
          'size-3 rounded-full',
          status === 'free' && 'bg-primary',
          status === 'reserved' && 'bg-reserved',
          status === 'maintenance' && 'bg-maintenance'
        )}
      />
      {label}
    </p>
  );
}

function StatusLegend() {
  return (
    <div className="flex items-center justify-between gap-3 text-sm">
      <LegendItem label="Libre" className="bg-primary" />
      <LegendItem label="Reservado" className="bg-reserved" />
      <LegendItem label="Mantenimiento" className="bg-maintenance" />
    </div>
  );
}

function LegendItem({ label, className }: { label: string; className: string }) {
  return (
    <span className="inline-flex items-center gap-2">
      <span className={cn('size-3 rounded-full', className)} />
      {label}
    </span>
  );
}

function MiniSlot({
  schedule,
  segment,
}: {
  schedule: BookingCourtSchedule;
  segment: BookingTimelineSegment;
}) {
  const { openCreateBooking, openBookingTools } = useBooking();
  const label =
    segment.status === 'free' ? 'Libre' : segment.status === 'reserved' ? 'Reservado' : 'Manten.';
  const isActionable = segment.status === 'free' || Boolean(segment.booking);

  return (
    <button
      type="button"
      className={cn(
        'min-w-0 rounded-lg border px-1.5 py-2 text-center transition active:scale-[0.98] disabled:opacity-60',
        segment.status === 'free' && 'border-primary/50 bg-primary/15 text-primary',
        segment.status === 'reserved' && 'border-reserved/50 bg-reserved/15 text-reserved',
        segment.status === 'maintenance' &&
          'border-maintenance/50 bg-maintenance/15 text-maintenance'
      )}
      disabled={!isActionable}
      onClick={() => {
        if (segment.status === 'free') {
          openCreateBooking({
            courtId: schedule.court.id,
            sportId: schedule.court.sportId,
            startTime: segment.startTime,
          });
          return;
        }

        if (segment.booking) {
          openBookingTools(segment);
        }
      }}
    >
      <p className="truncate text-sm font-medium">{segment.startTime}</p>
      <p className="mt-1 truncate text-[11px]">{label}</p>
    </button>
  );
}

function SportIcon({ sportName }: { sportName: string }) {
  const isPadel = sportName.toLowerCase().includes('padel');

  return (
    <div
      className={cn(
        'flex size-14 shrink-0 items-center justify-center rounded-lg border text-white',
        isPadel ? 'border-violet-400/40 bg-violet-500/30' : 'border-primary/40 bg-primary/25'
      )}
    >
      {isPadel ? <CircleDot className="size-7" /> : <Dumbbell className="size-7" />}
    </div>
  );
}

function MetricDots({ schedule }: { schedule: BookingCourtSchedule }) {
  return (
    <div className="flex shrink-0 items-center gap-2 text-sm font-medium">
      <span className="inline-flex items-center gap-1 text-primary">
        <span className="size-3 rounded-full bg-primary" />
        {schedule.metrics.free}
      </span>
      <span className="inline-flex items-center gap-1 text-reserved">
        <span className="size-3 rounded-full bg-reserved" />
        {schedule.metrics.reserved}
      </span>
      <span className="inline-flex items-center gap-1 text-maintenance">
        <span className="size-3 rounded-full bg-maintenance" />
        {schedule.metrics.maintenance}
      </span>
    </div>
  );
}

function MobileBottomNav({
  active,
  onSelect,
}: {
  active: MobileTab;
  onSelect: (tab: MobileTab) => void;
}) {
  return (
    <nav className="fixed inset-x-0 bottom-0 z-40 grid grid-cols-4 border-t border-border/70 bg-background/90 px-2 pb-3 pt-2 backdrop-blur-xl">
      <BottomNavItem
        active={active === 'panel'}
        icon={<Grid2X2 className="size-5" />}
        label="Panel"
        onClick={() => onSelect('panel')}
      />
      <BottomNavItem
        active={active === 'status'}
        icon={<ListChecks className="size-5" />}
        label="Estado"
        onClick={() => onSelect('status')}
      />
      <BottomNavItem
        active={active === 'bookings'}
        icon={<CalendarDays className="size-5" />}
        label="Reservas"
        onClick={() => onSelect('bookings')}
      />
      <BottomNavItem
        active={active === 'more'}
        icon={<MoreHorizontal className="size-5" />}
        label="Más"
        onClick={() => onSelect('more')}
      />
    </nav>
  );
}

function BottomNavItem({
  active,
  icon,
  label,
  onClick,
}: { active: boolean; icon: React.ReactNode; label: string; onClick: () => void }) {
  return (
    <button
      type="button"
      aria-current={active ? 'page' : undefined}
      className={cn(
        'flex flex-col items-center gap-1 rounded-lg px-2 py-1.5 text-xs text-muted-foreground',
        active && 'text-primary'
      )}
      onClick={onClick}
    >
      {icon}
      <span>{label}</span>
    </button>
  );
}
