"use client";

import Link from "next/link";
import { useEffect, useEffectEvent, useRef, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import type { z } from "zod";
import { AuthenticatedWorkspaceNavbar } from "@/components/authenticated-workspace-navbar";
import { Button } from "@/components/ui/button";
import { clubCoachesResponseSchema, clubInviteMutationResponseSchema, clubVenueMutationResponseSchema } from "@/lib/contracts/club-accounts";
import { coachStudentContactMutationResponseSchema } from "@/lib/contracts/coach-students";

type ClubCoachesResponse = z.infer<typeof clubCoachesResponseSchema>;
type ClubProfile = ClubCoachesResponse["club"];
type ClubDashboard = ClubCoachesResponse["dashboard"];
type ClubVenue = ClubCoachesResponse["configuration"]["venues"][number];
type ClubCoach = ClubCoachesResponse["coaches"][number];
type ClubInvite = ClubCoachesResponse["invites"][number];
type ClubManualClassOptions = ClubDashboard["manualClassOptions"];
type ClubPageView = "calendar" | "analytics" | "venues" | "coaches";
type ClubCalendarMode = "availability" | "reservation";
type ManualClassDraft = {
  venueId: string;
  courtId: string;
  coachId: string;
  packageId: string;
  playerId: string;
  playerWhatsappPhone: string;
  date: string;
  time: string;
  durationMinutes: number;
  repeatWeeklyCount: number;
  courtPriceMinor: number;
  coachPriceMinor: number;
  note: string;
};

type ClubStudentCreateDraft = {
  name: string;
  whatsappPhone: string;
  telegramHandle: string;
  gender: "" | "female" | "male" | "other";
  birthYear: string;
  coachCategory: string;
};

const calendarCourtThemes = [
  {
    accent: "bg-[#c4d600]",
    pill: "border-[#c4d600]/35 bg-[#c4d600]/12 text-[#f4ff95] hover:border-[#d7f53b]/60 hover:bg-[#c4d600]/18",
    pillActive: "border-[#d7f53b]/70 bg-[#c4d600]/22 text-white shadow-[0_0_0_1px_rgba(196,214,0,0.22)]",
    cell: "border-[#c4d600]/30 bg-[#c4d600]/12 hover:border-[#d7f53b]/60",
    badge: "border-[#c4d600]/30 bg-[#c4d600]/12 text-[#f4ff95]",
  },
  {
    accent: "bg-sky-400",
    pill: "border-sky-400/30 bg-sky-400/12 text-sky-100 hover:border-sky-300/55 hover:bg-sky-400/18",
    pillActive: "border-sky-300/70 bg-sky-400/20 text-white shadow-[0_0_0_1px_rgba(56,189,248,0.18)]",
    cell: "border-sky-400/30 bg-sky-400/12 hover:border-sky-300/55",
    badge: "border-sky-400/30 bg-sky-400/12 text-sky-100",
  },
  {
    accent: "bg-fuchsia-400",
    pill: "border-fuchsia-400/30 bg-fuchsia-400/12 text-fuchsia-100 hover:border-fuchsia-300/55 hover:bg-fuchsia-400/18",
    pillActive: "border-fuchsia-300/70 bg-fuchsia-400/20 text-white shadow-[0_0_0_1px_rgba(232,121,249,0.18)]",
    cell: "border-fuchsia-400/30 bg-fuchsia-400/12 hover:border-fuchsia-300/55",
    badge: "border-fuchsia-400/30 bg-fuchsia-400/12 text-fuchsia-100",
  },
  {
    accent: "bg-amber-300",
    pill: "border-amber-300/30 bg-amber-300/12 text-amber-100 hover:border-amber-200/55 hover:bg-amber-300/18",
    pillActive: "border-amber-200/70 bg-amber-300/20 text-white shadow-[0_0_0_1px_rgba(252,211,77,0.18)]",
    cell: "border-amber-300/30 bg-amber-300/12 hover:border-amber-200/55",
    badge: "border-amber-300/30 bg-amber-300/12 text-amber-100",
  },
  {
    accent: "bg-emerald-400",
    pill: "border-emerald-400/30 bg-emerald-400/12 text-emerald-100 hover:border-emerald-300/55 hover:bg-emerald-400/18",
    pillActive: "border-emerald-300/70 bg-emerald-400/20 text-white shadow-[0_0_0_1px_rgba(52,211,153,0.18)]",
    cell: "border-emerald-400/30 bg-emerald-400/12 hover:border-emerald-300/55",
    badge: "border-emerald-400/30 bg-emerald-400/12 text-emerald-100",
  },
  {
    accent: "bg-rose-400",
    pill: "border-rose-400/30 bg-rose-400/12 text-rose-100 hover:border-rose-300/55 hover:bg-rose-400/18",
    pillActive: "border-rose-300/70 bg-rose-400/20 text-white shadow-[0_0_0_1px_rgba(251,113,133,0.18)]",
    cell: "border-rose-400/30 bg-rose-400/12 hover:border-rose-300/55",
    badge: "border-rose-400/30 bg-rose-400/12 text-rose-100",
  },
] as const;

const inviteDateFormatter = new Intl.DateTimeFormat("es-UY", {
  day: "2-digit",
  month: "short",
  hour: "2-digit",
  minute: "2-digit",
});

function formatInviteDate(value: string) {
  return inviteDateFormatter.format(new Date(value));
}

function formatRequestDate(value: string | null) {
  if (!value) return "Pendiente";
  return inviteDateFormatter.format(new Date(value));
}

function formatAverageReview(value: number | null) {
  return value === null ? "Sin resenas" : `${value.toFixed(1)} / 5`;
}

function formatOpeningWindow(openingTime: string, closingTime: string) {
  return `${openingTime} a ${closingTime}`;
}

function formatMoney(value: number) {
  return `$ ${value.toLocaleString("es-UY")}`;
}

function getDateDayOfWeek(value: string) {
  return new Date(`${value}T12:00:00`).getDay();
}

function getVenueSlotPrice(
  venue: Pick<ClubVenue, "coachReservationPrice" | "coachPriceOverrides"> | null,
  dayOfWeek: number,
  startTime: string
) {
  if (!venue) return 0;

  const slotStart = parseTimeToMinutes(startTime);
  if (slotStart === null) return venue.coachReservationPrice;

  const override = venue.coachPriceOverrides.find((item) => {
    if (item.dayOfWeek !== dayOfWeek) return false;
    const overrideStart = parseTimeToMinutes(item.startTime);
    const overrideEnd = parseTimeToMinutes(item.endTime);
    if (overrideStart === null || overrideEnd === null) return false;
    return slotStart >= overrideStart && slotStart < overrideEnd;
  });

  return override?.price ?? venue.coachReservationPrice;
}

type ManualCoachOption = ClubManualClassOptions["coaches"][number];
type ManualCoachPackage = ManualCoachOption["packages"][number];

function getActiveCoachPackages(coach: ManualCoachOption | null | undefined) {
  return coach?.packages ?? [];
}

function applyCoachPackageToDraft(draft: ManualClassDraft, salesPackage: ManualCoachPackage | null): ManualClassDraft {
  return {
    ...draft,
    packageId: salesPackage?.id ?? "",
    durationMinutes: salesPackage?.durationMinutes ?? draft.durationMinutes,
    coachPriceMinor: salesPackage?.price ?? 0,
  };
}

function formatWeekDate(value: string) {
  return new Intl.DateTimeFormat("es-UY", {
    weekday: "short",
    day: "2-digit",
    month: "short",
  }).format(new Date(`${value}T12:00:00`));
}

function formatWeekRange(start: string, end: string) {
  return `${formatWeekDate(start)} - ${formatWeekDate(end)}`;
}

function formatCalendarDayLabel(value: string) {
  return new Intl.DateTimeFormat("es-UY", {
    weekday: "long",
    day: "numeric",
    month: "short",
  }).format(new Date(`${value}T12:00:00`));
}

function getCurrentWeekDays(weekStart: string) {
  const start = new Date(`${weekStart}T12:00:00`);

  return Array.from({ length: 7 }, (_, index) => {
    const date = new Date(start);
    date.setDate(start.getDate() + index);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${year}-${month}-${day}`;
  });
}

function parseTimeToMinutes(value: string) {
  const [hour, minute] = value.split(":").map((part) => Number(part));
  if (!Number.isInteger(hour) || !Number.isInteger(minute)) return null;
  return hour * 60 + minute;
}

function formatSlotLabel(value: string) {
  return value.slice(0, 5);
}

function listHalfHourSlots(startTime: string, endTime: string) {
  const startMinutes = parseTimeToMinutes(startTime);
  const endMinutes = parseTimeToMinutes(endTime);
  if (startMinutes === null || endMinutes === null || endMinutes <= startMinutes) return [];

  const slots: string[] = [];
  for (let minutes = startMinutes; minutes < endMinutes; minutes += 30) {
    const hour = String(Math.floor(minutes / 60)).padStart(2, "0");
    const minute = String(minutes % 60).padStart(2, "0");
    slots.push(`${hour}:${minute}`);
  }

  return slots;
}

function buildDaySlots(ranges: Array<{ dayOfWeek: number; startTime: string; endTime: string }>, dayOfWeek: number) {
  const slotSet = new Set<string>();

  for (const range of ranges) {
    if (range.dayOfWeek !== dayOfWeek) continue;
    for (const slot of listHalfHourSlots(range.startTime, range.endTime)) {
      slotSet.add(slot);
    }
  }

  return Array.from(slotSet).sort((left, right) => (parseTimeToMinutes(left) ?? 0) - (parseTimeToMinutes(right) ?? 0));
}

function blockOverlapsSlot(block: { startTime: string; endTime: string }, slot: string) {
  const blockStart = parseTimeToMinutes(block.startTime);
  const blockEnd = parseTimeToMinutes(block.endTime);
  const slotStart = parseTimeToMinutes(slot);
  if (blockStart === null || blockEnd === null || slotStart === null) return false;
  return slotStart >= blockStart && slotStart < blockEnd;
}

function todayDateValue() {
  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}`;
}

function createManualClassDraft(options: ClubManualClassOptions, venues: ClubVenue[]): ManualClassDraft {
  const firstCoach = options.coaches.find((coach) => coach.venueId) ?? options.coaches[0] ?? null;
  const firstCoachWithPackage =
    options.coaches.find((coach) => coach.venueId && getActiveCoachPackages(coach).length > 0) ??
    firstCoach;
  const firstVenue =
    venues.find((venue) => venue.id === firstCoachWithPackage?.venueId) ??
    venues[0] ??
    null;
  const firstCourt = firstVenue?.courts.find((court) => court.coachesEnabled) ?? firstVenue?.courts[0] ?? null;
  const firstPlayer = options.players[0] ?? null;
  const firstPackage = getActiveCoachPackages(firstCoachWithPackage)[0] ?? null;

  return {
    venueId: firstVenue?.id ?? "",
    courtId: firstCourt?.id ?? "",
    coachId: firstCoachWithPackage?.id ?? "",
    packageId: firstPackage?.id ?? "",
    playerId: firstPlayer?.id ?? "",
    playerWhatsappPhone: firstPlayer?.whatsappPhone ?? "",
    date: todayDateValue(),
    time: "09:00",
    durationMinutes: firstPackage?.durationMinutes ?? 60,
    repeatWeeklyCount: 1,
    courtPriceMinor: getVenueSlotPrice(firstVenue, getDateDayOfWeek(todayDateValue()), "09:00"),
    coachPriceMinor: firstPackage?.price ?? 0,
    note: "",
  };
}

function createClubStudentDraft(): ClubStudentCreateDraft {
  return {
    name: "",
    whatsappPhone: "",
    telegramHandle: "",
    gender: "",
    birthYear: "",
    coachCategory: "",
  };
}

export function ClubCoachesPageClient() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [view, setView] = useState<ClubPageView>(() => {
    const nextView = searchParams.get("view");
    if (nextView === "analytics" || nextView === "venues" || nextView === "coaches") return nextView;
    return "calendar";
  });
  const [club, setClub] = useState<ClubProfile | null>(null);
  const [dashboard, setDashboard] = useState<ClubDashboard | null>(null);
  const [venues, setVenues] = useState<ClubVenue[]>([]);
  const [coaches, setCoaches] = useState<ClubCoach[]>([]);
  const [invites, setInvites] = useState<ClubInvite[]>([]);
  const [newVenueName, setNewVenueName] = useState("");
  const [coveredCourtCount, setCoveredCourtCount] = useState(1);
  const [uncoveredCourtCount, setUncoveredCourtCount] = useState(0);
  const [loading, setLoading] = useState(true);
  const [inviteSaving, setInviteSaving] = useState(false);
  const [creatingVenue, setCreatingVenue] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [authRequired, setAuthRequired] = useState(false);
  const [copiedInviteId, setCopiedInviteId] = useState<string | null>(null);
  const [coachVenueFilter, setCoachVenueFilter] = useState("all");
  const [calendarVenueId, setCalendarVenueId] = useState("");
  const [calendarDate, setCalendarDate] = useState("");
  const [calendarCoachFilter, setCalendarCoachFilter] = useState("all");
  const [calendarMode, setCalendarMode] = useState<ClubCalendarMode>("availability");
  const [showManualClassForm, setShowManualClassForm] = useState(false);
  const [showRequestsPanel, setShowRequestsPanel] = useState(false);
  const [manualClassDraft, setManualClassDraft] = useState<ManualClassDraft>({
    venueId: "",
    courtId: "",
    coachId: "",
    packageId: "",
    playerId: "",
    playerWhatsappPhone: "",
    date: todayDateValue(),
    time: "09:00",
    durationMinutes: 60,
    repeatWeeklyCount: 1,
    courtPriceMinor: 0,
    coachPriceMinor: 0,
    note: "",
  });
  const [studentCreateDraft, setStudentCreateDraft] = useState<ClubStudentCreateDraft>(() => createClubStudentDraft());
  const [savingManualClass, setSavingManualClass] = useState(false);
  const [manualClassError, setManualClassError] = useState<string | null>(null);
  const [creatingStudent, setCreatingStudent] = useState(false);
  const [studentCreateError, setStudentCreateError] = useState<string | null>(null);
  const manualClassHeadingRef = useRef<HTMLHeadingElement | null>(null);
  const manualClassVenueRef = useRef<HTMLSelectElement | null>(null);
  const requestsPanelHeadingRef = useRef<HTMLHeadingElement | null>(null);

  useEffect(() => {
    const nextView = searchParams.get("view");
    if (nextView === "analytics" || nextView === "venues" || nextView === "coaches") {
      setView(nextView);
      return;
    }

    setView("calendar");
  }, [searchParams]);

  function handleViewChange(nextView: ClubPageView) {
    setView(nextView);

    const params = new URLSearchParams(searchParams.toString());
    if (nextView === "calendar") {
      params.delete("view");
    } else {
      params.set("view", nextView);
    }

    const nextQuery = params.toString();
    router.replace(nextQuery ? `/clubs/coaches?${nextQuery}` : "/clubs/coaches", { scroll: false });
  }

  async function loadClubPanel() {
    try {
      const response = await fetch("/api/clubs/coaches", { cache: "no-store" });
      const payload = await response.json().catch(() => null);

      if (!response.ok) {
        setClub(null);
        setDashboard(null);
        setVenues([]);
        setCoaches([]);
        setInvites([]);
        setAuthRequired(response.status === 401);
        setError(response.status === 401 ? null : payload?.error === "INVALID_PAYLOAD" ? "El panel del club devolvio datos invalidos." : "No pudimos cargar el panel del club.");
        return;
      }

      setAuthRequired(false);

      const parsed = clubCoachesResponseSchema.parse(payload);
      setClub(parsed.club);
      setDashboard(parsed.dashboard);
      setVenues(parsed.configuration.venues);
      setCalendarVenueId((current) => current || parsed.dashboard.calendar.venues[0]?.id || parsed.configuration.venues[0]?.id || "");
      setShowManualClassForm(false);
      setShowRequestsPanel(false);
      setManualClassDraft(createManualClassDraft(parsed.dashboard.manualClassOptions, parsed.configuration.venues));
      setCoaches(parsed.coaches);
      setInvites(parsed.invites);
      setError(null);
    } catch {
      setClub(null);
      setDashboard(null);
      setVenues([]);
      setShowManualClassForm(false);
      setShowRequestsPanel(false);
      setManualClassDraft({
        venueId: "",
        courtId: "",
        coachId: "",
        packageId: "",
        playerId: "",
        playerWhatsappPhone: "",
        date: todayDateValue(),
        time: "09:00",
        durationMinutes: 60,
        repeatWeeklyCount: 1,
        courtPriceMinor: 0,
        coachPriceMinor: 0,
        note: "",
      });
      setCoaches([]);
      setInvites([]);
      setAuthRequired(false);
      setError("No pudimos cargar el panel del club.");
    } finally {
      setLoading(false);
    }
  }

  const loadClubPanelEffect = useEffectEvent(loadClubPanel);

  useEffect(() => {
    void loadClubPanelEffect();
  }, []);

  useEffect(
    () => () => {
    },
    []
  );

  useEffect(() => {
    if (!dashboard) return;

    const days = getCurrentWeekDays(dashboard.calendar.weekStart);
    setCalendarDate((current) => (days.includes(current) ? current : days[0] ?? ""));
  }, [dashboard]);

  useEffect(() => {
    if (showManualClassForm) {
      window.requestAnimationFrame(() => {
        manualClassHeadingRef.current?.focus();
        manualClassVenueRef.current?.focus();
      });
    }
  }, [showManualClassForm]);

  useEffect(() => {
    if (showRequestsPanel) {
      window.requestAnimationFrame(() => {
        requestsPanelHeadingRef.current?.focus();
      });
    }
  }, [showRequestsPanel]);

  async function handleCreateInvite() {
    setInviteSaving(true);
    setError(null);

    try {
      const response = await fetch("/api/clubs/invites", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({}),
      });

      const payload = await response.json().catch(() => null);
      if (!response.ok) {
        setError(payload?.details?.message ?? "No pudimos generar el link.");
        return;
      }

      const parsed = clubInviteMutationResponseSchema.parse(payload);
      setInvites((current) => [parsed.item, ...current.filter((invite) => invite.id !== parsed.item.id)]);
      setCopiedInviteId(null);
    } catch {
      setError("No pudimos generar el link.");
    } finally {
      setInviteSaving(false);
    }
  }

  async function handleCreateVenue() {
    setCreatingVenue(true);
    setError(null);

    try {
      const response = await fetch("/api/clubs/venues", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: newVenueName,
          coveredCourtCount,
          uncoveredCourtCount,
        }),
      });

      const payload = await response.json().catch(() => null);
      if (!response.ok) {
        setError(payload?.details?.message ?? "No pudimos crear la sede.");
        return;
      }

      const parsed = clubVenueMutationResponseSchema.parse(payload);
      window.location.href = `/clubs/venues/${parsed.item.id}`;
    } catch {
      setError("No pudimos crear la sede.");
    } finally {
      setCreatingVenue(false);
    }
  }

  async function copyInvite(invite: ClubInvite) {
    try {
      await navigator.clipboard.writeText(invite.inviteUrl);
      setCopiedInviteId(invite.id);
      window.setTimeout(() => {
        setCopiedInviteId((current) => (current === invite.id ? null : current));
      }, 1500);
    } catch {
      setError("No pudimos copiar el link.");
    }
  }

  async function handleCreateManualClass() {
    if (!dashboard) return;

    setSavingManualClass(true);
    setManualClassError(null);

    try {
      const startsAt = new Date(`${manualClassDraft.date}T${manualClassDraft.time}:00`);
      const response = await fetch("/api/clubs/manual-classes", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          venueId: manualClassDraft.venueId,
          courtId: manualClassDraft.courtId || null,
          coachId: manualClassDraft.coachId,
          packageId: manualClassDraft.packageId,
          playerId: manualClassDraft.playerId,
          playerWhatsappPhone: manualClassDraft.playerWhatsappPhone || null,
          startsAt: startsAt.toISOString(),
          durationMinutes: manualClassDraft.durationMinutes,
          timezone: Intl.DateTimeFormat().resolvedOptions().timeZone ?? "America/Montevideo",
          courtPriceMinor: manualClassDraft.courtPriceMinor,
          coachPriceMinor: manualClassDraft.coachPriceMinor,
          recurrence:
            manualClassDraft.repeatWeeklyCount > 1
              ? { frequency: "weekly", occurrences: manualClassDraft.repeatWeeklyCount }
              : undefined,
          note: manualClassDraft.note || null,
        }),
      });

      const payload = await response.json().catch(() => null);
      if (!response.ok) {
        setManualClassError(payload?.details?.message ?? "No pudimos cargar la clase manual.");
        return;
      }

      await loadClubPanel();
      setShowManualClassForm(false);
    } catch {
      setManualClassError("No pudimos cargar la clase manual.");
    } finally {
      setSavingManualClass(false);
    }
  }

  async function handleCreateStudent() {
    if (!studentCreateDraft.name.trim()) {
      setStudentCreateError("Ponle al menos un nombre al alumno.");
      return;
    }

    setCreatingStudent(true);
    setStudentCreateError(null);

    try {
      const response = await fetch("/api/clubs/players", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: studentCreateDraft.name.trim(),
          whatsappPhone: studentCreateDraft.whatsappPhone.trim() || null,
          telegramHandle: studentCreateDraft.telegramHandle.trim() || null,
          gender: studentCreateDraft.gender || null,
          birthYear: studentCreateDraft.birthYear ? Number(studentCreateDraft.birthYear) : null,
          coachCategory: studentCreateDraft.coachCategory.trim() || null,
        }),
      });
      const payload = await response.json().catch(() => null);

      if (!response.ok) {
        setStudentCreateError(payload?.details?.message ?? "No pudimos crear el alumno.");
        return;
      }

      const parsed = coachStudentContactMutationResponseSchema.parse(payload);
      await loadClubPanel();
      setManualClassDraft((current) => ({
        ...current,
        playerId: parsed.item.id,
        playerWhatsappPhone: parsed.item.whatsappPhone ?? "",
      }));
      setStudentCreateDraft(createClubStudentDraft());
    } catch {
      setStudentCreateError("No pudimos crear el alumno.");
    } finally {
      setCreatingStudent(false);
    }
  }

  if (loading) {
    return <p className="mt-8 text-sm text-white/70">Cargando panel del club...</p>;
  }

  if (!club || !dashboard) {
    if (authRequired) {
      return (
        <div className="mt-8 max-w-xl rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6 text-white" role="status" aria-live="polite">
          <h2 className="text-2xl font-semibold">Acceso club</h2>
          <p className="mt-2 text-sm text-white/65">
            Entra desde <span className="text-white">/coaches</span> y usa sign in o sign up para clubs.
          </p>
          <Link
            href="/coaches"
            className="mt-5 inline-flex h-11 items-center justify-center rounded-xl bg-[#c4d600] px-5 text-sm font-medium text-[#10150d] transition hover:bg-[#d2e63e]"
          >
            Ir a sign in
          </Link>
        </div>
      );
    }

    return (
      <div className="mt-8 max-w-xl rounded-[1.75rem] border border-red-500/30 bg-[#0f140f]/80 p-6 text-white" role="alert" aria-live="assertive">
        <h2 className="text-2xl font-semibold">No pudimos abrir Entrenadores</h2>
        <p className="mt-2 text-sm text-white/65">{error ?? "El panel del club fallo al cargar."}</p>
        <button
          type="button"
          onClick={() => {
            setLoading(true);
            void loadClubPanel();
          }}
          className="mt-5 inline-flex h-11 items-center justify-center rounded-xl bg-[#c4d600] px-5 text-sm font-medium text-[#10150d] transition hover:bg-[#d2e63e]"
        >
          Reintentar
        </button>
      </div>
    );
  }

  const totalCourts = venues.reduce((total, venue) => total + venue.courtSummary.total, 0);
  const totalCoachHours = venues.reduce((total, venue) => total + venue.coachHours.length, 0);
  const latestInvite = invites[0] ?? null;
  const manualClassOptions = dashboard.manualClassOptions;
  const venueFilterOptions = [
    { id: "all", label: "Todas las sedes" },
    ...venues.map((venue) => ({ id: venue.id, label: venue.name })),
    { id: "unassigned", label: "Sin sede" },
  ];
  const coachVenueById = new Map(dashboard.coachTable.map((coach) => [coach.id, coach.venue]));
  const filteredProfessorRows = dashboard.analytics.professors.filter((professor) => {
    const venue = coachVenueById.get(professor.coachId) ?? null;
    if (coachVenueFilter === "all") return true;
    if (coachVenueFilter === "unassigned") return venue === null;
    return venue?.id === coachVenueFilter;
  });
  const weekDays = getCurrentWeekDays(dashboard.calendar.weekStart);
  const selectedCalendarDate = weekDays.includes(calendarDate) ? calendarDate : weekDays[0] ?? "";
  const selectedCalendarVenue =
    dashboard.calendar.venues.find((venue) => venue.id === calendarVenueId) ?? dashboard.calendar.venues[0] ?? null;
  const selectedCalendarVenueConfig = venues.find((venue) => venue.id === selectedCalendarVenue?.id) ?? null;
  const calendarCoachTagOptions = coaches
    .filter((coach) => coach.affiliation === "club")
    .sort((left, right) => left.name.localeCompare(right.name));
  const effectiveCalendarCoachFilter =
    calendarCoachFilter === "all" || calendarCoachTagOptions.some((coach) => coach.id === calendarCoachFilter)
      ? calendarCoachFilter
      : "all";
  const selectedCalendarCourts = (selectedCalendarVenue?.courts ?? []).filter((court) => court.coachesEnabled);
  const calendarCourtThemesById = new Map(
    selectedCalendarCourts.map((court, index) => [court.id, calendarCourtThemes[index % calendarCourtThemes.length]])
  );
  const filteredCalendarBlocks = dashboard.calendar.blocks.filter((block) => {
    if (!selectedCalendarVenue || block.venueId !== selectedCalendarVenue.id) return false;
    if (block.type !== calendarMode) return false;
    if (effectiveCalendarCoachFilter !== "all" && block.coachId !== effectiveCalendarCoachFilter) return false;
    return true;
  });
  const calendarDays = (() => {
    const blockEntriesByDate = new Map<string, typeof filteredCalendarBlocks>();
    for (const block of filteredCalendarBlocks) {
      const current = blockEntriesByDate.get(block.date) ?? [];
      current.push(block);
      blockEntriesByDate.set(block.date, current);
    }

    return weekDays.map((date, index) => {
      const dayOfWeek = index === 6 ? 0 : index + 1;
      const daySlots = selectedCalendarVenueConfig ? buildDaySlots(selectedCalendarVenueConfig.coachHours, dayOfWeek) : [];
      const dayBlocks = (blockEntriesByDate.get(date) ?? []).sort((left, right) => {
        const leftStart = parseTimeToMinutes(left.startTime) ?? 0;
        const rightStart = parseTimeToMinutes(right.startTime) ?? 0;
        if (leftStart !== rightStart) return leftStart - rightStart;
        return (left.coachName ?? "").localeCompare(right.coachName ?? "");
      });
      const occupancy = new Map<string, (typeof dayBlocks)[number]>();

      const canPlaceBlockOnCourt = (courtId: string, block: (typeof dayBlocks)[number]) =>
        daySlots.filter((slot) => blockOverlapsSlot(block, slot)).every((slot) => !occupancy.has(`${courtId}|${slot}`));

      for (const block of dayBlocks) {
        const preferredCourtId =
          block.courtId && selectedCalendarCourts.some((court) => court.id === block.courtId) ? block.courtId : null;
        const targetCourtId =
          (preferredCourtId && canPlaceBlockOnCourt(preferredCourtId, block) ? preferredCourtId : null) ??
          selectedCalendarCourts.find((court) => canPlaceBlockOnCourt(court.id, block))?.id ??
          null;

        if (!targetCourtId) continue;

        for (const slot of daySlots) {
          if (blockOverlapsSlot(block, slot)) {
            occupancy.set(`${targetCourtId}|${slot}`, block);
          }
        }
      }

      let coveredCells = 0;
      for (const court of selectedCalendarCourts) {
        for (const slot of daySlots) {
          if (occupancy.has(`${court.id}|${slot}`)) coveredCells += 1;
        }
      }

      return {
        date,
        slots: daySlots,
        occupancy,
        blockCount: dayBlocks.length,
        coveredCells,
        totalCells: daySlots.length * selectedCalendarCourts.length,
      };
    });
  })();
  const selectedCalendarDay = calendarDays.find((day) => day.date === selectedCalendarDate) ?? calendarDays[0] ?? null;
  const totalCalendarCells = selectedCalendarDay?.totalCells ?? 0;
  const totalCoveredCalendarCells = selectedCalendarDay?.coveredCells ?? 0;
  const totalBlankCalendarCells = Math.max(0, totalCalendarCells - totalCoveredCalendarCells);
  const calendarWeekSlots = selectedCalendarDay?.slots ?? [];
  const calendarSummaryId = "club-calendar-summary";
  const calendarHelperId = "club-calendar-helper";
  const calendarSelectionSummary = selectedCalendarVenue
    ? [
        `Sede ${selectedCalendarVenue.name}`,
        selectedCalendarDay ? `dia ${formatCalendarDayLabel(selectedCalendarDay.date)}` : null,
        calendarMode === "availability" ? "modo disponibilidad" : "modo reservas",
        effectiveCalendarCoachFilter === "all"
          ? "todos los profesores del club"
          : `profesor ${calendarCoachTagOptions.find((coach) => coach.id === effectiveCalendarCoachFilter)?.name ?? "seleccionado"}`,
      ]
        .filter(Boolean)
        .join(" · ")
    : "Sin sede seleccionada";
  const availableManualCoaches = manualClassOptions.coaches.filter((coach) =>
    manualClassDraft.venueId ? coach.venueId === manualClassDraft.venueId : Boolean(coach.venueId)
  );
  const selectedManualCoach = availableManualCoaches.find((coach) => coach.id === manualClassDraft.coachId) ?? null;
  const availableManualPackages = getActiveCoachPackages(selectedManualCoach);
  const selectedManualVenue = venues.find((venue) => venue.id === manualClassDraft.venueId) ?? null;
  const availableManualCourts = selectedManualVenue?.courts.filter((court) => court.coachesEnabled) ?? [];
  const analyticsReservations = dashboard.analytics.reservations;
  const resolveManualCourtPrice = (venueId: string, coachId: string, date: string, time: string) => {
    const venue = venues.find((item) => item.id === venueId) ?? null;
    const slotPrice = getVenueSlotPrice(venue, getDateDayOfWeek(date), time);
    const coach = coaches.find((item) => item.id === coachId) ?? null;

    if (venue && coach?.affiliation === "club" && coach.venue?.id === venue.id) {
      return Math.max(0, slotPrice - venue.clubCoachReservationDiscount);
    }

    return slotPrice;
  };

  return (
    <section className="space-y-6 text-white">
      <AuthenticatedWorkspaceNavbar
        email={club.contactEmail}
        sections={[
          {
            label: "Calendario",
            active: view === "calendar",
            onClick: () => handleViewChange("calendar"),
          },
          {
            label: "Analiticas",
            active: view === "analytics",
            onClick: () => handleViewChange("analytics"),
          },
          {
            label: "Sedes",
            active: view === "venues",
            onClick: () => handleViewChange("venues"),
          },
          {
            label: "Profesores",
            active: view === "coaches",
            onClick: () => handleViewChange("coaches"),
          },
        ]}
        onSignOut={async () => {
          await fetch("/api/clubs/logout", { method: "POST" });
          window.location.href = "/coaches";
        }}
      />

      {view === "calendar" ? (
        <>
          <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
            <div className="grid gap-4 md:grid-cols-2">
              <div className={`rounded-[1.35rem] border bg-black/20 ${showManualClassForm ? "border-[#c4d600]/45 bg-[#c4d600]/12 shadow-[0_0_0_1px_rgba(196,214,0,0.22)]" : "border-white/10"}`}>
                <button
                  type="button"
                  aria-expanded={showManualClassForm}
                  aria-controls="club-manual-class-panel"
                  onClick={() => {
                    if (showRequestsPanel) {
                      setShowRequestsPanel(false);
                    }
                    setShowManualClassForm((current) => !current);
                  }}
                  className="w-full px-5 py-5 text-left"
                >
                  <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Operacion diaria</p>
                  <div className="mt-3 flex items-center justify-between gap-4">
                    <div>
                      <h3 className="text-2xl font-semibold text-white">Agregar clase</h3>
                      <p className="mt-2 text-sm text-white/60">
                        Carga una reserva manual para una sede, profesor, cancha y alumno.
                      </p>
                    </div>
                    <span className="rounded-full border border-[#c4d600]/30 px-3 py-1 text-xs text-[#ebff7b]">
                      {showManualClassForm ? "Ocultar" : "Abrir"}
                    </span>
                  </div>
                </button>
              </div>

              <div className={`rounded-[1.35rem] border bg-black/20 ${showRequestsPanel ? "border-sky-400/45 bg-sky-400/10 shadow-[0_0_0_1px_rgba(56,189,248,0.18)]" : "border-white/10"}`}>
                <button
                  type="button"
                  aria-expanded={showRequestsPanel}
                  aria-controls="club-requests-panel"
                  onClick={() => {
                    if (showManualClassForm) {
                      setShowManualClassForm(false);
                    }
                    setShowRequestsPanel((current) => !current);
                  }}
                  className="w-full px-5 py-5 text-left"
                >
                  <p className="text-xs uppercase tracking-[0.2em] text-sky-200">Seguimiento</p>
                  <div className="mt-3 flex items-center justify-between gap-4">
                    <div>
                      <h3 className="text-2xl font-semibold text-white">Ver solicitudes</h3>
                      <p className="mt-2 text-sm text-white/60">
                        Revisa pedidos, cambios o problemas pendientes de alumnos y profesores.
                      </p>
                    </div>
                    <span className="rounded-full border border-sky-400/30 px-3 py-1 text-xs text-sky-100">
                      {dashboard.requests.length} items
                    </span>
                  </div>
                </button>
              </div>
            </div>
          </article>

          {showManualClassForm ? (
            <article id="club-manual-class-panel" className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6" aria-labelledby="manual-class-heading">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <div>
                  <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Agregar clase</p>
                  <h3 id="manual-class-heading" ref={manualClassHeadingRef} tabIndex={-1} className="mt-2 text-2xl font-semibold focus:outline-none focus-visible:ring-2 focus-visible:ring-[#c4d600]/70">Carga manual para tu operacion diaria</h3>
                </div>
              </div>

              <form
                className="mt-5"
                onSubmit={(event) => {
                  event.preventDefault();
                  void handleCreateManualClass();
                }}
              >
                <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
                  <div className="rounded-[1rem] border border-white/10 bg-black/20 p-4 md:col-span-2 xl:col-span-4">
                  <div className="flex flex-wrap items-center justify-between gap-3">
                    <div>
                      <p className="text-sm font-medium text-white">Nuevo alumno</p>
                      <p className="mt-1 text-xs text-white/55">Lo creas para el club y despues se lo asignas al profesor que corresponda.</p>
                    </div>
                    <Button
                      type="button"
                      className="h-10 rounded-xl px-4 text-sm font-medium"
                      disabled={creatingStudent}
                      onClick={() => void handleCreateStudent()}
                    >
                      {creatingStudent ? "Creando..." : "Crear alumno"}
                    </Button>
                  </div>

                  <div className="mt-4 grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
                    <label className="block text-sm text-white/70">
                      Nombre
                      <input
                        value={studentCreateDraft.name}
                        onChange={(event) => setStudentCreateDraft((current) => ({ ...current, name: event.target.value }))}
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      />
                    </label>
                    <label className="block text-sm text-white/70">
                      WhatsApp
                      <input
                        value={studentCreateDraft.whatsappPhone}
                        onChange={(event) => setStudentCreateDraft((current) => ({ ...current, whatsappPhone: event.target.value }))}
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      />
                    </label>
                    <label className="block text-sm text-white/70">
                      Telegram
                      <input
                        value={studentCreateDraft.telegramHandle}
                        onChange={(event) => setStudentCreateDraft((current) => ({ ...current, telegramHandle: event.target.value }))}
                        placeholder="@usuario"
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      />
                    </label>
                    <label className="block text-sm text-white/70">
                      Sexo
                      <select
                        value={studentCreateDraft.gender}
                        onChange={(event) =>
                          setStudentCreateDraft((current) => ({
                            ...current,
                            gender: event.target.value as ClubStudentCreateDraft["gender"],
                          }))
                        }
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      >
                        <option value="">Sin dato</option>
                        <option value="female">Mujer</option>
                        <option value="male">Hombre</option>
                        <option value="other">Otro</option>
                      </select>
                    </label>
                    <label className="block text-sm text-white/70">
                      Ano de nacimiento
                      <input
                        type="number"
                        min={1900}
                        max={2100}
                        value={studentCreateDraft.birthYear}
                        onChange={(event) => setStudentCreateDraft((current) => ({ ...current, birthYear: event.target.value }))}
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      />
                    </label>
                    <label className="block text-sm text-white/70">
                      Categoria
                      <select
                        value={studentCreateDraft.coachCategory}
                        onChange={(event) => setStudentCreateDraft((current) => ({ ...current, coachCategory: event.target.value }))}
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      >
                        <option value="">Sin categoria</option>
                        {Array.from({ length: 10 }, (_, index) => String(index + 1)).map((value) => (
                          <option key={value} value={value}>
                            {value}
                          </option>
                        ))}
                      </select>
                    </label>
                  </div>

                  {studentCreateError ? (
                    <p role="alert" aria-live="assertive" className="mt-4 rounded-xl border border-red-500/40 bg-red-500/10 px-4 py-3 text-sm text-red-200">
                      {studentCreateError}
                    </p>
                  ) : null}
                </div>

                <label className="block text-sm text-white/70">
                  Sede
                  <select
                    ref={manualClassVenueRef}
                    value={manualClassDraft.venueId}
                    onChange={(event) => {
                      const nextVenueId = event.target.value;
                      const nextVenue = venues.find((venue) => venue.id === nextVenueId) ?? null;
                      const nextCourt = nextVenue?.courts.find((court) => court.coachesEnabled) ?? nextVenue?.courts[0] ?? null;
                      const nextCoach =
                        manualClassOptions.coaches.find((coach) => coach.venueId === nextVenueId && getActiveCoachPackages(coach).length > 0) ??
                        manualClassOptions.coaches.find((coach) => coach.venueId === nextVenueId) ??
                        null;
                      const nextPackage = getActiveCoachPackages(nextCoach)[0] ?? null;
                      setManualClassDraft((current) => ({
                        ...applyCoachPackageToDraft(
                          {
                            ...current,
                            venueId: nextVenueId,
                            courtId: nextCourt?.id ?? "",
                            coachId: nextCoach?.id ?? "",
                            courtPriceMinor: resolveManualCourtPrice(
                              nextVenueId,
                              nextCoach?.id ?? "",
                              current.date,
                              current.time
                            ),
                          },
                          nextPackage
                        ),
                      }));
                    }}
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  >
                    <option value="">Selecciona sede</option>
                    {manualClassOptions.venues.map((venue) => (
                      <option key={venue.id} value={venue.id}>
                        {venue.name}
                      </option>
                    ))}
                  </select>
                </label>

                <label className="block text-sm text-white/70">
                  Profesor
                  <select
                    value={manualClassDraft.coachId}
                    onChange={(event) => {
                      const nextCoachId = event.target.value;
                      const nextCoach = availableManualCoaches.find((coach) => coach.id === nextCoachId) ?? null;
                      const nextPackage = getActiveCoachPackages(nextCoach)[0] ?? null;
                      setManualClassDraft((current) =>
                        applyCoachPackageToDraft(
                          {
                            ...current,
                            coachId: nextCoachId,
                            courtPriceMinor: resolveManualCourtPrice(current.venueId, nextCoachId, current.date, current.time),
                          },
                          nextPackage
                        )
                      );
                    }}
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  >
                    <option value="">Selecciona profesor</option>
                    {availableManualCoaches.map((coach) => (
                      <option key={coach.id} value={coach.id}>
                        {coach.name}{getActiveCoachPackages(coach).length === 0 ? " (sin paquetes)" : ""}
                      </option>
                    ))}
                  </select>
                </label>

                <label className="block text-sm text-white/70">
                  Paquete del profesor
                  <select
                    value={manualClassDraft.packageId}
                    disabled={!manualClassDraft.coachId || availableManualPackages.length === 0}
                    onChange={(event) => {
                      const nextPackage = availableManualPackages.find((salesPackage) => salesPackage.id === event.target.value) ?? null;
                      setManualClassDraft((current) => applyCoachPackageToDraft(current, nextPackage));
                    }}
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white disabled:cursor-not-allowed disabled:text-white/40"
                  >
                    <option value="">
                      {manualClassDraft.coachId
                        ? availableManualPackages.length === 0
                          ? "Este profesor no tiene paquetes"
                          : "Selecciona paquete"
                        : "Primero selecciona profesor"}
                    </option>
                    {availableManualPackages.map((salesPackage) => (
                      <option key={salesPackage.id} value={salesPackage.id}>
                        {salesPackage.title} · {salesPackage.durationMinutes} min · {formatMoney(salesPackage.price)}
                      </option>
                    ))}
                  </select>
                </label>

                <label className="block text-sm text-white/70">
                  Cancha
                  <select
                    value={manualClassDraft.courtId}
                    onChange={(event) => setManualClassDraft((current) => ({ ...current, courtId: event.target.value }))}
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  >
                    <option value="">Sin asignar</option>
                    {availableManualCourts.map((court) => (
                      <option key={court.id} value={court.id}>
                        {court.name}
                      </option>
                    ))}
                  </select>
                </label>

                <label className="block text-sm text-white/70">
                  Alumno
                  <select
                    value={manualClassDraft.playerId}
                    onChange={(event) => {
                      const nextPlayer = manualClassOptions.players.find((player) => player.id === event.target.value) ?? null;
                      setManualClassDraft((current) => ({
                        ...current,
                        playerId: event.target.value,
                        playerWhatsappPhone: nextPlayer?.whatsappPhone ?? "",
                      }));
                    }}
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  >
                    <option value="">Selecciona alumno</option>
                    {manualClassOptions.players.map((player) => (
                      <option key={player.id} value={player.id}>
                        {player.name}
                      </option>
                    ))}
                  </select>
                </label>

                <label className="block text-sm text-white/70">
                  WhatsApp
                  <input
                    value={manualClassDraft.playerWhatsappPhone}
                    onChange={(event) => setManualClassDraft((current) => ({ ...current, playerWhatsappPhone: event.target.value }))}
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  />
                </label>

                <label className="block text-sm text-white/70">
                  Fecha
                  <input
                    type="date"
                    value={manualClassDraft.date}
                    onChange={(event) =>
                      setManualClassDraft((current) => ({
                        ...current,
                        date: event.target.value,
                        courtPriceMinor: resolveManualCourtPrice(current.venueId, current.coachId, event.target.value, current.time),
                      }))
                    }
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  />
                </label>

                <label className="block text-sm text-white/70">
                  Hora
                  <input
                    type="time"
                    step={1800}
                    value={manualClassDraft.time}
                    onChange={(event) =>
                      setManualClassDraft((current) => ({
                        ...current,
                        time: event.target.value,
                        courtPriceMinor: resolveManualCourtPrice(current.venueId, current.coachId, current.date, event.target.value),
                      }))
                    }
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  />
                </label>

                <label className="block text-sm text-white/70">
                  Duracion
                  <select
                    value={String(manualClassDraft.durationMinutes)}
                    onChange={(event) =>
                      setManualClassDraft((current) => ({ ...current, durationMinutes: Number(event.target.value || 60) }))
                    }
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  >
                    {[60, 90, 120].map((minutes) => (
                      <option key={minutes} value={minutes}>
                        {minutes} min
                      </option>
                    ))}
                  </select>
                </label>

                <label className="block text-sm text-white/70">
                  Repetir semanalmente
                  <select
                    value={String(manualClassDraft.repeatWeeklyCount)}
                    onChange={(event) =>
                      setManualClassDraft((current) => ({ ...current, repeatWeeklyCount: Number(event.target.value || 1) }))
                    }
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  >
                    <option value="1">Solo esta clase</option>
                    <option value="4">4 semanas</option>
                    <option value="8">8 semanas</option>
                    <option value="12">12 semanas</option>
                  </select>
                </label>

                <label className="block text-sm text-white/70">
                  Precio cancha
                  <input
                    type="number"
                    min={0}
                    value={manualClassDraft.courtPriceMinor}
                    onChange={(event) =>
                      setManualClassDraft((current) => ({ ...current, courtPriceMinor: Math.max(0, Number(event.target.value || 0)) }))
                    }
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                  />
                </label>

                <label className="block text-sm text-white/70">
                  Precio coach
                  <input
                    type="number"
                    min={0}
                    readOnly
                    value={manualClassDraft.coachPriceMinor}
                    className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/20 px-3 text-sm text-white/75"
                  />
                </label>
              </div>

              <label className="mt-4 block text-sm text-white/70">
                Nota interna
                <textarea
                  value={manualClassDraft.note}
                  onChange={(event) => setManualClassDraft((current) => ({ ...current, note: event.target.value }))}
                  className="mt-2 min-h-[110px] w-full rounded-[1rem] border border-white/15 bg-black/30 px-3 py-3 text-sm text-white"
                />
              </label>

              {selectedManualVenue ? (
                <p className="mt-4 text-sm text-white/55">
                  Precio actual del horario: {formatMoney(resolveManualCourtPrice(
                    selectedManualVenue.id,
                    manualClassDraft.coachId,
                    manualClassDraft.date,
                    manualClassDraft.time
                  ))}
                  . Base de la sede: {formatMoney(selectedManualVenue.coachReservationPrice)}. Descuento coach del club:{" "}
                  {formatMoney(selectedManualVenue.clubCoachReservationDiscount)}.
                </p>
              ) : null}

              {manualClassDraft.coachId && availableManualPackages.length === 0 ? (
                <p className="mt-4 rounded-xl border border-amber-300/30 bg-amber-300/10 px-4 py-3 text-sm text-amber-100">
                  Este profesor todavia no tiene paquetes activos. Primero tiene que cargar uno para poder armar una clase.
                </p>
              ) : null}

              {manualClassError ? (
                <p role="alert" aria-live="assertive" className="mt-4 rounded-xl border border-red-500/40 bg-red-500/10 px-4 py-3 text-sm text-red-200">{manualClassError}</p>
              ) : null}

              <div className="mt-5 flex flex-wrap items-center gap-3">
                <Button
                  type="submit"
                  className="h-11 rounded-xl px-5 text-sm font-medium"
                  disabled={
                    savingManualClass ||
                    !manualClassDraft.venueId ||
                    !manualClassDraft.coachId ||
                    !manualClassDraft.packageId ||
                    !manualClassDraft.playerId ||
                    !manualClassDraft.date ||
                    !manualClassDraft.time
                  }
                >
                  {savingManualClass ? "Guardando..." : "Guardar clase"}
                </Button>
                <button
                  type="button"
                  onClick={() => setShowManualClassForm(false)}
                  className="text-sm text-white/60 transition hover:text-white"
                >
                  Cancelar
                </button>
              </div>
              </form>
            </article>
          ) : null}

          {showRequestsPanel ? (
            <article id="club-requests-panel" className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6" aria-labelledby="requests-panel-heading">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <div>
                  <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Solicitudes</p>
                  <h3 id="requests-panel-heading" ref={requestsPanelHeadingRef} tabIndex={-1} className="mt-2 text-2xl font-semibold focus:outline-none focus-visible:ring-2 focus-visible:ring-sky-400/70">Pendientes del club</h3>
                </div>
                <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                  {dashboard.requests.length} items
                </span>
              </div>

              <div className="mt-5 space-y-3">
                {dashboard.requests.length === 0 ? (
                  <p className="rounded-[1.25rem] border border-dashed border-white/10 bg-black/10 p-5 text-sm text-white/55">
                    No hay pedidos ni problemas pendientes para revisar ahora.
                  </p>
                ) : null}

                {dashboard.requests.map((request) => (
                  <div key={request.id} className="rounded-[1.25rem] border border-white/10 bg-black/20 p-4">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <div>
                        <p className="text-base font-medium text-white">{request.title}</p>
                        <p className="mt-1 text-sm text-white/60">{request.subtitle}</p>
                      </div>
                      <span className="rounded-full border border-white/10 px-3 py-1 text-xs text-white/60">
                        {request.statusLabel}
                      </span>
                    </div>

                    <div className="mt-3 grid gap-3 text-sm text-white/60 md:grid-cols-3">
                      <p>{request.venue ? `Sede ${request.venue.name}` : "Sin sede"}</p>
                      <p>{request.coach ? `Coach ${request.coach.name}` : "Sin coach"}</p>
                      <p>{formatRequestDate(request.createdAt)}</p>
                    </div>

                    {request.student ? (
                      <div className="mt-3 text-sm text-white/55">
                        {request.student.email}
                        {request.student.whatsappPhone ? ` · ${request.student.whatsappPhone}` : ""}
                      </div>
                    ) : null}
                  </div>
                ))}
              </div>
            </article>
          ) : null}

          <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div>
                <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Calendario</p>
                <h3 className="mt-2 text-2xl font-semibold">Semana actual</h3>
                <p className="mt-2 text-sm text-white/60">{formatWeekRange(dashboard.calendar.weekStart, dashboard.calendar.weekEnd)}</p>
              </div>
              <fieldset className="flex flex-wrap items-center gap-3">
                <legend className="sr-only">Modo de calendario</legend>
                <p className="text-xs text-white/50">Alterna entre cobertura de coaches y reservas cargadas.</p>
                <div className="inline-flex rounded-xl border border-white/10 bg-black/20 p-1">
                  <label className={`rounded-lg px-3 py-2 text-sm transition ${
                    calendarMode === "availability" ? "bg-[#c4d600]/14 text-white" : "text-white/55 hover:text-white"
                  }`}>
                    <input
                      type="radio"
                      name="calendar-mode"
                      value="availability"
                      checked={calendarMode === "availability"}
                      onChange={() => setCalendarMode("availability")}
                      className="sr-only"
                    />
                    Disponibilidad
                  </label>
                  <label className={`rounded-lg px-3 py-2 text-sm transition ${
                    calendarMode === "reservation" ? "bg-sky-400/14 text-white" : "text-white/55 hover:text-white"
                  }`}>
                    <input
                      type="radio"
                      name="calendar-mode"
                      value="reservation"
                      checked={calendarMode === "reservation"}
                      onChange={() => setCalendarMode("reservation")}
                      className="sr-only"
                    />
                    Reservas
                  </label>
                </div>
              </fieldset>
            </div>

            <p id={calendarSummaryId} aria-live="polite" className="mt-5 text-sm text-white/60">
              {calendarSelectionSummary}
            </p>

            <div className="mt-4 space-y-4">
              <fieldset>
                <legend className="text-xs uppercase tracking-[0.16em] text-white/45">Sede</legend>
                <div className="mt-2 flex flex-wrap gap-2">
                  {dashboard.calendar.venues.map((venue) => {
                    const isActive = venue.id === selectedCalendarVenue?.id;

                    return (
                      <label
                        key={venue.id}
                        className={`rounded-full border px-4 py-2 text-sm transition ${
                          isActive
                            ? "border-[#c4d600]/45 bg-[#c4d600]/12 text-white"
                            : "border-white/10 bg-black/20 text-white/65 hover:border-white/20 hover:text-white"
                        }`}
                      >
                        <input
                          type="radio"
                          name="calendar-venue"
                          value={venue.id}
                          checked={isActive}
                          onChange={() => setCalendarVenueId(venue.id)}
                          className="sr-only"
                        />
                        {venue.name}
                      </label>
                    );
                  })}
                </div>
              </fieldset>

              <fieldset>
                <legend className="text-xs uppercase tracking-[0.16em] text-white/45">Profesores del club</legend>
                <div className="mt-2 flex flex-wrap gap-2">
                  <label
                    className={`rounded-full border px-4 py-2 text-sm transition ${
                      effectiveCalendarCoachFilter === "all"
                        ? "border-sky-400/45 bg-sky-400/12 text-white"
                        : "border-white/10 bg-black/20 text-white/65 hover:border-white/20 hover:text-white"
                    }`}
                  >
                    <input
                      type="radio"
                      name="calendar-coach"
                      value="all"
                      checked={effectiveCalendarCoachFilter === "all"}
                      onChange={() => setCalendarCoachFilter("all")}
                      className="sr-only"
                    />
                    Todos
                  </label>
                  {calendarCoachTagOptions.map((coach) => {
                    const isActive = effectiveCalendarCoachFilter === coach.id;

                    return (
                      <label
                        key={coach.id}
                        className={`rounded-full border px-4 py-2 text-sm transition ${
                          isActive
                            ? "border-sky-400/45 bg-sky-400/12 text-white"
                            : "border-white/10 bg-black/20 text-white/65 hover:border-white/20 hover:text-white"
                        }`}
                      >
                        <input
                          type="radio"
                          name="calendar-coach"
                          value={coach.id}
                          checked={isActive}
                          onChange={() => setCalendarCoachFilter(coach.id)}
                          className="sr-only"
                        />
                        {coach.name}
                      </label>
                    );
                  })}
                </div>
              </fieldset>
            </div>

            <div className="mt-5 grid gap-3 md:grid-cols-2 xl:grid-cols-4">
              <div className="rounded-[1.15rem] border border-[#c4d600]/20 bg-[#c4d600]/8 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-[#d9ef31]">
                  {calendarMode === "availability" ? "Cobertura del dia" : "Reservas del dia"}
                </p>
                <p className="mt-2 text-2xl font-semibold">{totalCoveredCalendarCells}</p>
              </div>
              <div className="rounded-[1.15rem] border border-sky-400/20 bg-sky-400/8 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-sky-200">Huecos visibles</p>
                <p className="mt-2 text-2xl font-semibold">{totalBlankCalendarCells}</p>
              </div>
              <div className="rounded-[1.15rem] border border-white/10 bg-black/20 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-white/45">Dia seleccionado</p>
                <p className="mt-2 text-2xl font-semibold capitalize">{selectedCalendarDay ? formatCalendarDayLabel(selectedCalendarDay.date) : "Sin dia"}</p>
              </div>
              <div className="rounded-[1.15rem] border border-white/10 bg-black/20 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-white/45">Canchas</p>
                <p className="mt-2 text-2xl font-semibold">
                  {selectedCalendarCourts.length}
                </p>
              </div>
            </div>

            {!selectedCalendarVenue || !selectedCalendarVenueConfig ? (
              <div className="mt-5 rounded-[1.15rem] border border-dashed border-white/10 bg-black/10 p-5 text-sm text-white/55">
                No hay sedes disponibles para mostrar en el calendario.
              </div>
            ) : selectedCalendarCourts.length === 0 ? (
              <div className="mt-5 rounded-[1.15rem] border border-dashed border-white/10 bg-black/10 p-5 text-sm text-white/55">
                Esta sede no tiene canchas habilitadas para coaches.
              </div>
            ) : (
              <div className="mt-5 space-y-4">
                <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-4">
                  <div className="flex flex-wrap items-center justify-between gap-3">
                    <div>
                      <p className="text-sm font-medium text-white">Selecciona el dia</p>
                      <p className="mt-1 text-xs text-white/50">Despues ves todas las canchas de la sede como columnas.</p>
                    </div>
                    <p id={calendarHelperId} className="text-xs text-white/50">
                      Cada bloque abre la carga manual con sede, cancha, fecha y hora ya completas.
                    </p>
                    <span className="rounded-full border border-white/10 px-3 py-1 text-xs text-white/55">
                      {selectedCalendarCourts.length} canchas
                    </span>
                  </div>

                  <fieldset className="mt-4 grid gap-2 sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-7">
                    <legend className="sr-only">Dia del calendario</legend>
                    {calendarDays.map((day) => {
                      const isActive = day.date === selectedCalendarDate;

                      return (
                        <label
                          key={day.date}
                          className={`rounded-2xl border px-4 py-3 text-left capitalize transition ${
                            isActive
                              ? "border-[#c4d600]/55 bg-[#c4d600]/15 text-white shadow-[0_0_0_1px_rgba(196,214,0,0.18)]"
                              : "border-white/10 bg-black/20 text-white/65 hover:border-white/20 hover:text-white"
                          }`}
                        >
                          <input
                            type="radio"
                            name="calendar-day"
                            value={day.date}
                            checked={isActive}
                            onChange={() => setCalendarDate(day.date)}
                            className="sr-only"
                          />
                          <p className="text-sm font-medium">{formatCalendarDayLabel(day.date)}</p>
                          <p className="mt-1 text-xs text-white/45">
                            {day.coveredCells} ocupados · {Math.max(0, day.totalCells - day.coveredCells)} huecos
                          </p>
                        </label>
                      );
                    })}
                  </fieldset>
                </div>

                {calendarWeekSlots.length === 0 ? (
                  <div className="rounded-[1.25rem] border border-dashed border-white/10 bg-black/10 p-4 text-sm text-white/55">
                    Esta sede no tiene horario coach habilitado para este dia.
                  </div>
                ) : (
                  <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-4">
                    <div className="flex flex-wrap items-center justify-between gap-3">
                      <div>
                        <p className="text-sm font-medium capitalize text-white">{selectedCalendarDay ? formatCalendarDayLabel(selectedCalendarDay.date) : "Dia"}</p>
                        <p className="mt-1 text-xs text-white/50">
                          {calendarMode === "availability" ? "Cobertura de coaches por cancha" : "Reservas tomadas por cancha"}
                        </p>
                      </div>
                      <span className="rounded-full border border-emerald-400/25 bg-emerald-400/10 px-3 py-1 text-xs text-emerald-100">
                        {totalCoveredCalendarCells} bloques ocupados
                      </span>
                    </div>

                    <div className="mt-4 overflow-x-auto">
                      <div
                        role="grid"
                        aria-label={`Calendario de ${calendarMode === "availability" ? "disponibilidad" : "reservas"} para ${selectedCalendarVenue.name} el ${selectedCalendarDay ? formatCalendarDayLabel(selectedCalendarDay.date) : "dia seleccionado"}`}
                        aria-describedby={calendarHelperId}
                        className="grid min-w-[1120px] gap-2"
                        style={{ gridTemplateColumns: `96px repeat(${selectedCalendarCourts.length}, minmax(160px, 1fr))` }}
                      >
                        <div role="columnheader" className="sticky left-0 z-20 rounded-xl border border-white/10 bg-[#101410] px-3 py-3 text-[11px] uppercase tracking-[0.12em] text-white/45">
                          Hora
                        </div>
                        {selectedCalendarCourts.map((court) => {
                          const theme = calendarCourtThemesById.get(court.id) ?? calendarCourtThemes[0];

                          return (
                          <div role="columnheader" key={court.id} className="rounded-xl border border-white/10 bg-[#101410] px-3 py-3">
                            <div className={`mb-2 h-2 rounded-full ${theme.accent}`} />
                            <p className="text-sm font-medium text-white">{court.name}</p>
                            <p className="mt-1 text-[11px] text-white/45">{court.covered ? "Techada" : "Descubierta"}</p>
                          </div>
                          );
                        })}

                        {calendarWeekSlots.map((slot) => (
                          <div key={`row-${slot}`} className="contents">
                            <div
                              role="rowheader"
                              className="sticky left-0 z-10 rounded-xl border border-white/10 bg-[#101410] px-3 py-4 text-sm font-medium text-white"
                            >
                              {formatSlotLabel(slot)}
                            </div>
                            {selectedCalendarCourts.map((court) => {
                              const theme = calendarCourtThemesById.get(court.id) ?? calendarCourtThemes[0];
                              const block = selectedCalendarDay?.occupancy.get(`${court.id}|${slot}`) ?? null;
                              const slotEnabled = selectedCalendarDay?.slots.includes(slot) ?? false;
                              const activeDate = selectedCalendarDay?.date ?? selectedCalendarDate;
                              const slotPriceMinor = getVenueSlotPrice(selectedCalendarVenueConfig, getDateDayOfWeek(activeDate), slot);
                              const visibleSlotPriceMinor =
                                calendarMode === "reservation" ? (block?.courtPriceMinor ?? slotPriceMinor) : slotPriceMinor;

                              return (
                                <button
                                  key={`${court.id}-${slot}`}
                                  type="button"
                                  role="gridcell"
                                  disabled={!slotEnabled}
                                  aria-describedby={calendarHelperId}
                                  aria-label={`${court.name}, ${formatSlotLabel(slot)}, ${
                                    !slotEnabled
                                      ? "cerrado para coaches"
                                      : block
                                        ? calendarMode === "availability"
                                          ? `cubierta por ${block.coachName ?? "profesor"}`
                                          : `reserva cargada${block.playerName ? ` para ${block.playerName}` : ""}`
                                        : calendarMode === "availability"
                                          ? "sin coach cubriendo"
                                          : "sin reserva cargada"
                                  }. ${slotEnabled ? "Abrir formulario de carga manual" : "Horario no disponible"}`}
                                  onClick={() => {
                                    if (!slotEnabled) return;
                                    setManualClassDraft((current) => ({
                                      ...(() => {
                                        const fallbackCoach =
                                          manualClassOptions.coaches.find(
                                            (coach) => coach.venueId === selectedCalendarVenue.id && getActiveCoachPackages(coach).length > 0
                                          ) ??
                                          manualClassOptions.coaches.find((coach) => coach.venueId === selectedCalendarVenue.id) ??
                                          null;
                                        const currentCoachFitsVenue = manualClassOptions.coaches.some(
                                          (coach) => coach.id === current.coachId && coach.venueId === selectedCalendarVenue.id
                                        );
                                        const nextCoachId = block?.coachId ?? (currentCoachFitsVenue ? current.coachId : fallbackCoach?.id ?? "");
                                        const nextCoach = manualClassOptions.coaches.find((coach) => coach.id === nextCoachId) ?? null;
                                        const nextPackage =
                                          current.packageId && getActiveCoachPackages(nextCoach).some((salesPackage) => salesPackage.id === current.packageId)
                                            ? getActiveCoachPackages(nextCoach).find((salesPackage) => salesPackage.id === current.packageId) ?? null
                                            : getActiveCoachPackages(nextCoach)[0] ?? null;
                                        return {
                                          ...applyCoachPackageToDraft(
                                            {
                                              ...current,
                                              venueId: selectedCalendarVenue.id,
                                              courtId: court.id,
                                              coachId: nextCoachId,
                                              date: activeDate,
                                              time: slot,
                                              courtPriceMinor: resolveManualCourtPrice(
                                                selectedCalendarVenue.id,
                                                nextCoachId,
                                                activeDate,
                                                slot
                                              ),
                                            },
                                            nextPackage
                                          ),
                                        };
                                      })(),
                                    }));
                                    setShowManualClassForm(true);
                                  }}
                                  className={`min-h-[88px] rounded-xl border px-3 py-3 text-left transition ${
                                    !slotEnabled
                                      ? "cursor-not-allowed border-transparent bg-[#160909] text-white/25"
                                      : block
                                        ? theme.cell
                                        : "border-dashed border-white/10 bg-[#0c100c] hover:border-white/20 hover:bg-white/[0.03]"
                                  }`}
                                >
                                  {!slotEnabled ? (
                                    <>
                                      <p className="text-[11px] uppercase tracking-[0.12em] text-white/25">Cerrado para coaches</p>
                                      <p className="mt-2 text-[11px] text-white/25">Sin accion disponible.</p>
                                    </>
                                  ) : block ? (
                                    <>
                                      <p className="text-[10px] uppercase tracking-[0.12em] text-white/75">
                                        {calendarMode === "availability" ? "Cubierta" : "Reserva cargada"}
                                      </p>
                                      <p className="mt-2 text-xs text-white/80">
                                        {calendarMode === "availability"
                                          ? block.coachName ?? "Profesor asignado"
                                          : block.playerName ?? "Alumno sin nombre visible"}
                                      </p>
                                      <p className="mt-2 text-[11px] font-medium text-white">{formatMoney(visibleSlotPriceMinor)}</p>
                                      <p className="mt-2 text-[10px] text-white/55">
                                        {block.startTime} - {block.endTime}
                                      </p>
                                      <p className="mt-2 text-[10px] text-white/65">Abrir carga manual en este horario.</p>
                                    </>
                                  ) : (
                                    <>
                                      <p className="text-[10px] uppercase tracking-[0.12em] text-white/32">Hueco</p>
                                      <p className="mt-2 text-[11px] text-white/45">
                                        {calendarMode === "availability" ? "Sin coach cubriendo" : "Sin reserva cargada"}
                                      </p>
                                      <p className="mt-2 text-[11px] font-medium text-white/75">{formatMoney(visibleSlotPriceMinor)}</p>
                                      <p className="mt-2 text-[10px] text-white/65">Abrir carga manual en este horario.</p>
                                    </>
                                  )}
                                </button>
                              );
                            })}
                          </div>
                        ))}
                      </div>
                    </div>
                  </div>
                )}
              </div>
            )}
          </article>
        </>
      ) : view === "analytics" ? (
        <>
          <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div>
                <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Profesores</p>
                <h3 className="mt-2 text-2xl font-semibold">Analytics por profesor</h3>
              </div>
              <div className="flex flex-wrap items-center gap-3">
                <select
                  value={coachVenueFilter}
                  onChange={(event) => setCoachVenueFilter(event.target.value)}
                  className="h-10 rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                >
                  {venueFilterOptions.map((option) => (
                    <option key={option.id} value={option.id}>
                      {option.label}
                    </option>
                  ))}
                </select>
                <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                  {filteredProfessorRows.length} profes
                </span>
              </div>
            </div>

            <div className="mt-5 grid gap-3 md:grid-cols-2 xl:grid-cols-4">
              <div className="rounded-[1.15rem] border border-white/10 bg-black/20 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-white/45">Reservas</p>
                <p className="mt-2 text-2xl font-semibold">{dashboard.analytics.summary.reservationCount}</p>
              </div>
              <div className="rounded-[1.15rem] border border-white/10 bg-black/20 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-white/45">Para club</p>
                <p className="mt-2 text-2xl font-semibold">{formatMoney(dashboard.analytics.summary.clubRevenueMinor)}</p>
              </div>
              <div className="rounded-[1.15rem] border border-white/10 bg-black/20 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-white/45">Para coaches</p>
                <p className="mt-2 text-2xl font-semibold">{formatMoney(dashboard.analytics.summary.coachRevenueMinor)}</p>
              </div>
              <div className="rounded-[1.15rem] border border-white/10 bg-black/20 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-white/45">Reviews</p>
                <p className="mt-2 text-2xl font-semibold">{formatAverageReview(dashboard.analytics.summary.averageReview)}</p>
              </div>
            </div>

            <div className="mt-5 overflow-x-auto rounded-[1.25rem] border border-white/10 bg-black/20">
              <table className="min-w-full text-left text-sm text-white/75">
                <caption className="sr-only">Resumen de ingresos y resenas por profesor para la sede seleccionada.</caption>
                <thead className="border-b border-white/10 bg-black/20 text-xs uppercase tracking-[0.16em] text-white/45">
                  <tr>
                    <th scope="col" className="px-4 py-3 font-medium">Profesor</th>
                    <th scope="col" className="px-4 py-3 font-medium">Sede</th>
                    <th scope="col" className="px-4 py-3 font-medium">Reservas</th>
                    <th scope="col" className="px-4 py-3 font-medium">Alumnos</th>
                    <th scope="col" className="px-4 py-3 font-medium">Resenas</th>
                    <th scope="col" className="px-4 py-3 font-medium">Para coach</th>
                    <th scope="col" className="px-4 py-3 font-medium">Para club</th>
                  </tr>
                </thead>
                <tbody>
                  {filteredProfessorRows.length === 0 ? (
                    <tr>
                      <td colSpan={7} className="px-4 py-6 text-center text-sm text-white/50">
                        No hay profesores para ese filtro.
                      </td>
                    </tr>
                  ) : null}

                  {filteredProfessorRows.map((professor) => (
                    <tr key={professor.coachId} className="border-b border-white/5 last:border-b-0">
                      <td className="px-4 py-4">
                        <p className="font-medium text-white">{professor.coachName}</p>
                        <p className="mt-1 text-xs text-white/50">{professor.studentCount} alumnos activos</p>
                      </td>
                      <td className="px-4 py-4 text-white/70">{professor.venueName ?? "Sin sede"}</td>
                      <td className="px-4 py-4 text-white/70">{professor.reservationCount}</td>
                      <td className="px-4 py-4 text-white/70">{professor.studentCount}</td>
                      <td className="px-4 py-4 text-white/70">{formatAverageReview(professor.averageReview)}</td>
                      <td className="px-4 py-4 text-white/70">{formatMoney(professor.coachRevenueMinor)}</td>
                      <td className="px-4 py-4 text-white/70">{formatMoney(professor.clubRevenueMinor)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </article>
          <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div>
                <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Reservas</p>
                <h3 className="mt-2 text-2xl font-semibold">Detalle de reservas</h3>
              </div>
              <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                {analyticsReservations.length} reservas
              </span>
            </div>

            <div className="mt-5 overflow-x-auto rounded-[1.25rem] border border-white/10 bg-black/20">
              <table className="min-w-full text-left text-sm text-white/75">
                <caption className="sr-only">Detalle de reservas por fecha, profesor, alumno, sede y reparto.</caption>
                <thead className="border-b border-white/10 bg-black/20 text-xs uppercase tracking-[0.16em] text-white/45">
                  <tr>
                    <th scope="col" className="px-4 py-3 font-medium">Fecha</th>
                    <th scope="col" className="px-4 py-3 font-medium">Profesor</th>
                    <th scope="col" className="px-4 py-3 font-medium">Alumno</th>
                    <th scope="col" className="px-4 py-3 font-medium">Sede / cancha</th>
                    <th scope="col" className="px-4 py-3 font-medium">Club</th>
                    <th scope="col" className="px-4 py-3 font-medium">Coach</th>
                  </tr>
                </thead>
                <tbody>
                  {analyticsReservations.length === 0 ? (
                    <tr>
                      <td colSpan={6} className="px-4 py-6 text-center text-sm text-white/50">
                        Todavia no hay reservas tomadas.
                      </td>
                    </tr>
                  ) : null}

                  {analyticsReservations.map((reservation) => (
                    <tr key={reservation.id} className="border-b border-white/5 last:border-b-0">
                      <td className="px-4 py-4 text-white/70">{formatRequestDate(reservation.startsAt)}</td>
                      <td className="px-4 py-4 text-white/70">{reservation.coachName}</td>
                      <td className="px-4 py-4 text-white/70">{reservation.playerName}</td>
                      <td className="px-4 py-4 text-white/70">
                        {reservation.venueName}
                        {reservation.courtName ? ` · ${reservation.courtName}` : ""}
                      </td>
                      <td className="px-4 py-4 text-white/70">{formatMoney(reservation.courtPriceMinor ?? 0)}</td>
                      <td className="px-4 py-4 text-white/70">{formatMoney(reservation.coachPriceMinor ?? 0)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </article>
        </>
      ) : view === "venues" ? (
        <div className="space-y-6">
          <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div>
                <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Sedes</p>
                <h3 className="mt-2 text-xl font-semibold">Administra tus sedes</h3>
                <p className="mt-2 text-sm text-white/65">
                  Crea sedes rapido aqui y luego entra a cada una para terminar horarios, canchas y profesores con mas detalle.
                </p>
              </div>
              <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                {venues.length} sedes
              </span>
            </div>

            <div className="mt-5 grid gap-3 lg:grid-cols-[1.15fr_0.85fr]">
              <details className="group rounded-[1.5rem] border border-[#c4d600]/20 bg-[radial-gradient(circle_at_top_left,_rgba(196,214,0,0.16),_transparent_52%),linear-gradient(180deg,rgba(255,255,255,0.02),rgba(255,255,255,0))] transition open:border-[#c4d600]/40">
                <summary className="flex min-h-[11rem] cursor-pointer list-none flex-col justify-between p-6 text-left [&::-webkit-details-marker]:hidden">
                  <div>
                    <p className="text-xs uppercase tracking-[0.18em] text-[#c4d600]">Accion principal</p>
                    <h4 className="mt-3 text-3xl font-semibold text-white">Agregar sede</h4>
                    <p className="mt-3 max-w-xl text-sm text-white/65">
                      Crea una sede nueva y despues entras a terminar horarios, canchas y reservas con una configuracion guiada.
                    </p>
                  </div>
                  <div className="flex items-center justify-between gap-3">
                    <div className="flex flex-wrap gap-2 text-xs text-white/55">
                      <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1">{totalCourts} canchas</span>
                      <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1">{coaches.length} profesores</span>
                      <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1">{totalCoachHours} bloques coach</span>
                    </div>
                    <span className="inline-flex h-11 items-center justify-center rounded-xl bg-[#c4d600] px-5 text-sm font-medium text-[#10150d] transition group-hover:bg-[#d2e63e] group-open:hidden">
                      Crear sede
                    </span>
                    <span className="hidden h-11 items-center justify-center rounded-xl border border-white/10 bg-black/20 px-5 text-sm font-medium text-white/70 group-open:inline-flex">
                      Ocultar formulario
                    </span>
                  </div>
                </summary>

                <div className="mt-5 rounded-[1.5rem] border border-[#c4d600]/20 bg-black/20 p-5">
                  <div className="flex flex-wrap items-start justify-between gap-3">
                    <div>
                      <p className="text-xs uppercase tracking-[0.18em] text-[#c4d600]">Nueva sede</p>
                      <h4 className="mt-2 text-xl font-semibold text-white">Primer paso rapido</h4>
                      <p className="mt-2 text-sm text-white/60">
                        Aqui solo defines nombre y cantidad inicial de canchas. Lo mas fino lo terminas dentro de la sede.
                      </p>
                    </div>
                    <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                      Luego la sigues configurando
                    </span>
                  </div>
                  <div className="mt-4 grid gap-4 lg:grid-cols-[1.2fr_0.4fr_0.4fr]">
                    <label className="block text-sm text-white/70">
                      Nombre
                      <input
                        value={newVenueName}
                        onChange={(event) => setNewVenueName(event.target.value)}
                        placeholder="Palermo Indoor, Moron, Sede Norte..."
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      />
                    </label>
                    <label className="block text-sm text-white/70">
                      Techadas
                      <input
                        type="number"
                        min={0}
                        value={coveredCourtCount}
                        onChange={(event) => setCoveredCourtCount(Math.max(0, Number(event.target.value || 0)))}
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      />
                    </label>
                    <label className="block text-sm text-white/70">
                      No techadas
                      <input
                        type="number"
                        min={0}
                        value={uncoveredCourtCount}
                        onChange={(event) => setUncoveredCourtCount(Math.max(0, Number(event.target.value || 0)))}
                        className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                      />
                    </label>
                  </div>
                  <div className="mt-5 flex flex-wrap gap-3">
                    <Button
                      type="button"
                      className="h-11 rounded-xl px-5 text-sm font-medium"
                      disabled={creatingVenue || newVenueName.trim().length === 0}
                      onClick={() => void handleCreateVenue()}
                    >
                      {creatingVenue ? "Creando..." : "Crear sede y abrir configuracion"}
                    </Button>
                  </div>
                </div>
              </details>

              <div className="grid gap-3 sm:grid-cols-3 lg:grid-cols-1 xl:grid-cols-3">
                <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-4">
                  <p className="text-xs uppercase tracking-[0.16em] text-white/45">Canchas</p>
                  <p className="mt-2 text-2xl font-semibold text-white">{totalCourts}</p>
                </div>
                <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-4">
                  <p className="text-xs uppercase tracking-[0.16em] text-white/45">Coaches</p>
                  <p className="mt-2 text-2xl font-semibold text-white">{coaches.length}</p>
                </div>
                <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-4">
                  <p className="text-xs uppercase tracking-[0.16em] text-white/45">Bloques coach</p>
                  <p className="mt-2 text-2xl font-semibold text-white">{totalCoachHours}</p>
                </div>
              </div>
            </div>

            <div className="mt-5">
              {venues.length === 0 ? (
                <p className="text-sm text-white/55">
                  Todavia no cargaste sedes. Crea una y entra para configurar horarios, coaches externos y entrenadores.
                </p>
              ) : (
                <div className="overflow-x-auto rounded-[1.25rem] border border-white/10 bg-black/20">
                  <table className="min-w-[920px] text-left text-sm text-white/75">
                    <caption className="sr-only">Tabla de sedes del club con estado, horario, resumen y accion de edicion.</caption>
                    <thead className="border-b border-white/10 bg-black/20 text-xs uppercase tracking-[0.16em] text-white/45">
                      <tr>
                        <th scope="col" className="px-4 py-3 font-medium">Sede</th>
                        <th scope="col" className="px-4 py-3 font-medium">Estado</th>
                        <th scope="col" className="px-4 py-3 font-medium">Horario</th>
                        <th scope="col" className="px-4 py-3 font-medium">Resumen</th>
                        <th scope="col" className="px-4 py-3 font-medium">Accion</th>
                      </tr>
                    </thead>
                    <tbody>
                      {venues.map((venue) => {
                        const venueCoaches = coaches.filter((coach) => coach.venue?.id === venue.id);

                        return (
                          <tr key={venue.id} className="border-b border-white/5 align-top last:border-b-0">
                            <td className="px-4 py-4">
                              <p className="font-medium text-white">{venue.name}</p>
                              <p className="mt-1 text-xs text-white/50">
                                {venue.courtSummary.total} canchas · {venueCoaches.length} profesores
                              </p>
                            </td>
                            <td className="px-4 py-4">
                              <div className="flex flex-wrap gap-2">
                                <span className="rounded-full border border-white/10 px-2.5 py-1 text-[11px] text-white/60">
                                  {venue.status === "active" ? "Activa" : "Inactiva"}
                                </span>
                                <span className="rounded-full border border-white/10 px-2.5 py-1 text-[11px] text-white/60">
                                  {venue.externalCoachesAllowed ? "Acepta externos" : "Solo club"}
                                </span>
                              </div>
                            </td>
                            <td className="px-4 py-4 text-white/70">{formatOpeningWindow(venue.openingTime, venue.closingTime)}</td>
                            <td className="px-4 py-4">
                              <p className="text-white/70">
                                {venue.courtSummary.coachesEnabled} canchas para coaches · {venue.coachCount} asignados
                              </p>
                              <p className="mt-1 text-xs text-white/50">
                                Externo {formatMoney(venue.coachReservationPrice)} · Club {formatMoney(venue.clubCoachReservationPrice)}
                              </p>
                              {venue.coachPriceOverrides.length > 0 ? (
                                <p className="mt-1 text-xs text-white/50">
                                  {venue.coachPriceOverrides.length} horario{venue.coachPriceOverrides.length === 1 ? "" : "s"} especial
                                </p>
                              ) : null}
                            </td>
                            <td className="px-4 py-4">
                              <div className="flex min-w-[10rem] justify-end">
                                <Link
                                  href={`/clubs/venues/${venue.id}`}
                                  className="inline-flex h-11 items-center justify-center rounded-xl border border-[#c4d600]/35 bg-[#c4d600]/10 px-5 text-sm font-medium text-[#d9ef31] shadow-[0_12px_35px_-24px_rgba(196,214,0,0.9)] transition hover:-translate-y-0.5 hover:border-[#c4d600]/60 hover:bg-[#c4d600]/15 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#c4d600]/70"
                                >
                                  Editar sede
                                </Link>
                              </div>
                            </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          </article>
        </div>
      ) : (
        <div className="grid gap-6 lg:grid-cols-[0.9fr_1.1fr]">
            <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
              <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Link de invitacion para coach</p>
              <h3 className="mt-2 text-xl font-semibold">Agregar profesores</h3>
              <p className="mt-2 text-sm text-white/65">
                No hace falta cargar mail. Cuando el coach entre, luego decides en qué sede trabaja.
              </p>

              <Button
                type="button"
                className="mt-5 h-11 w-full rounded-xl text-sm font-medium"
                disabled={inviteSaving}
                onClick={() => void handleCreateInvite()}
              >
                {inviteSaving ? "Generando..." : "Generar link"}
              </Button>

              {latestInvite ? (
                <div className="mt-5 rounded-[1.25rem] border border-[#c4d600]/20 bg-[#c4d600]/5 p-4">
                  <p className="text-xs uppercase tracking-[0.16em] text-[#c4d600]">Ultimo link generado</p>
                  <input
                    readOnly
                    value={latestInvite.inviteUrl}
                    className="mt-3 h-11 w-full rounded-xl border border-white/10 bg-black/30 px-3 text-xs text-white/80"
                  />
                  <div className="mt-3 flex flex-wrap items-center justify-between gap-3">
                    <span className="text-xs text-white/55">Generado {formatInviteDate(latestInvite.createdAt)}</span>
                    <Button
                      type="button"
                      variant="outline"
                      className="h-10 rounded-xl border-white/15 bg-transparent text-white hover:bg-white/5"
                      onClick={() => {
                        void copyInvite(latestInvite);
                      }}
                    >
                      {copiedInviteId === latestInvite.id ? "Copiado" : "Copiar link"}
                    </Button>
                  </div>
                </div>
              ) : null}
            </article>

            <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <div>
                  <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Profesores</p>
                  <h3 className="mt-2 text-xl font-semibold">Tabla de profesores</h3>
                </div>
                <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                  {coaches.length} coaches
                </span>
              </div>

              <div className="mt-5 overflow-x-auto rounded-[1.25rem] border border-white/10 bg-black/20">
                <table className="min-w-full text-left text-sm text-white/75">
                  <caption className="sr-only">Tabla de profesores del club con sede, clases publicadas, solicitudes y resenas.</caption>
                  <thead className="border-b border-white/10 bg-black/20 text-xs uppercase tracking-[0.16em] text-white/45">
                    <tr>
                      <th scope="col" className="px-4 py-3 font-medium">Profesor</th>
                      <th scope="col" className="px-4 py-3 font-medium">Sede</th>
                      <th scope="col" className="px-4 py-3 font-medium">Clases publicadas</th>
                      <th scope="col" className="px-4 py-3 font-medium">Solicitudes</th>
                      <th scope="col" className="px-4 py-3 font-medium">Resenas</th>
                    </tr>
                  </thead>
                  <tbody>
                    {coaches.length === 0 ? (
                      <tr>
                        <td colSpan={5} className="px-4 py-6 text-center text-sm text-white/50">
                          Todavia no hay coaches vinculados a este club.
                        </td>
                      </tr>
                    ) : null}

                    {coaches.map((coach) => (
                      <tr key={coach.id} className="border-b border-white/5 last:border-b-0">
                        <td className="px-4 py-4">
                          <p className="font-medium text-white">{coach.name}</p>
                          <p className="mt-1 text-xs text-white/50">{coach.email ?? "Sin email"}</p>
                        </td>
                        <td className="px-4 py-4 text-white/70">{coach.venue ? coach.venue.name : "Sin sede asignada"}</td>
                        <td className="px-4 py-4 text-white/70">{coach.metrics.classOffers}</td>
                        <td className="px-4 py-4 text-white/70">{coach.metrics.requestCount}</td>
                        <td className="px-4 py-4 text-white/70">{formatAverageReview(coach.metrics.averageReview)}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </article>
        </div>
      )}

      {error ? <p className="rounded-xl border border-red-500/40 bg-red-500/10 px-4 py-3 text-sm text-red-200">{error}</p> : null}
    </section>
  );
}
