"use client";

import Link from "next/link";
import { useEffect, useEffectEvent, useMemo, 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 {
  WeeklyAvailabilityGrid,
  type WeeklyAvailabilityRange,
} from "@/components/weekly-availability-grid";
import {
  coachStudentContactMutationResponseSchema,
  coachStudentBookingMutationResponseSchema,
  coachStudentsResponseSchema,
} from "@/lib/contracts/coach-students";
import {
  coachAvailabilityResponseSchema,
  coachClubsResponseSchema,
  coachMeResponseSchema,
} from "@/lib/contracts/coaches";

type CoachSettingsResponse = z.infer<typeof coachMeResponseSchema>;
type CoachStudentsResponse = z.infer<typeof coachStudentsResponseSchema>;
type CoachClubSelection = CoachSettingsResponse["externalClubs"]["selection"];
type CoachPackage = CoachSettingsResponse["commercial"]["packages"][number];
type CoachStudentBooking = CoachStudentsResponse["bookings"][number];
type CoachPageView = "calendar" | "performance" | "configuration" | "students";
type CoachCalendarSessionParticipant = {
  bookingId: string;
  player: CoachStudentBooking["player"];
  paymentStatus: CoachStudentBooking["paymentStatus"];
};
type CoachCalendarSession = {
  key: string;
  startsAt: string;
  endsAt: string;
  startTime: string;
  endTime: string;
  dateKey: string;
  durationMinutes: number;
  venue: CoachStudentBooking["venue"];
  court: CoachStudentBooking["court"];
  note: string | null;
  participants: CoachCalendarSessionParticipant[];
};

type CoachPackageDraft = CoachPackage & {
  clientId: string;
};

type CoachStudentBookingDraft = {
  playerId: string;
  venueId: string;
  date: string;
  startTime: string;
  durationMinutes: number;
  repeatWeeklyCount: number;
  note: string;
  timezone: string;
};

type CoachStudentContactDraft = {
  whatsappPhone: string;
  telegramHandle: string;
};
type CoachStudentCreateDraft = {
  name: string;
  whatsappPhone: string;
  telegramHandle: string;
  gender: "" | "female" | "male" | "other";
  birthYear: string;
  coachCategory: string;
};
type AutoSaveState = "idle" | "saving" | "saved" | "error";

function createLocalId(prefix: string) {
  return `${prefix}-${Math.random().toString(36).slice(2, 10)}`;
}

function createPackageDraft(pkg?: CoachPackage): CoachPackageDraft {
  return {
    clientId: createLocalId("package"),
    id: pkg?.id ?? createLocalId("package-id"),
    title: pkg?.title ?? "Clase individual",
    price: pkg?.price ?? 0,
    durationMinutes: pkg?.durationMinutes ?? 60,
    maxStudents: pkg?.maxStudents ?? 1,
    format: pkg?.format ?? "individual",
    active: pkg?.active ?? true,
  };
}

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

function formatDuration(value: number) {
  return `${value} min`;
}

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

function selectionSignature(selection: CoachClubSelection) {
  return `${selection.mode}:${[...selection.clubIds].sort().join(",")}`;
}

function packageSignature(packages: CoachPackageDraft[]) {
  return JSON.stringify(
    packages.map((pkg) => ({
      title: pkg.title,
      price: pkg.price,
      durationMinutes: pkg.durationMinutes,
      maxStudents: pkg.maxStudents,
      format: pkg.format,
      active: pkg.active,
    }))
  );
}

function availabilitySignature(items: WeeklyAvailabilityRange[], timezone: string) {
  return JSON.stringify({
    timezone,
    items: [...items]
      .map((item) => ({
        dayOfWeek: item.dayOfWeek,
        startTime: item.startTime,
        endTime: item.endTime,
      }))
      .sort((left, right) => {
        if (left.dayOfWeek !== right.dayOfWeek) return left.dayOfWeek - right.dayOfWeek;
        if (left.startTime !== right.startTime) return left.startTime.localeCompare(right.startTime);
        return left.endTime.localeCompare(right.endTime);
      }),
  });
}

function summarizeAllowedHours(ranges: WeeklyAvailabilityRange[]) {
  if (ranges.length === 0) return "Sin horarios abiertos";
  return `${new Set(ranges.map((range) => range.dayOfWeek)).size} dias habilitados`;
}

function formatDateTime(value: string) {
  return new Intl.DateTimeFormat("es-UY", {
    day: "2-digit",
    month: "short",
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date(value));
}

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

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

function buildDateKey(value: string) {
  const date = new Date(value);
  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 formatBookedHours(minutes: number) {
  if (minutes === 0) return "0 hs";

  const hours = minutes / 60;
  return Number.isInteger(hours) ? `${hours} hs` : `${hours.toFixed(1)} hs`;
}

function getCurrentWeekDays() {
  const start = new Date();
  start.setHours(12, 0, 0, 0);
  const daysFromMonday = (start.getDay() + 6) % 7;
  start.setDate(start.getDate() - daysFromMonday);

  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 getDateForWeeklyAvailability(weekDays: string[], dayOfWeek: number) {
  const index = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
  return weekDays[index] ?? weekDays[0] ?? todayDateValue();
}

function getStudentConsistencyLabel(lessonCount: number, upcomingLessonCount: number) {
  if (lessonCount >= 8 && upcomingLessonCount > 0) return "Alta";
  if (lessonCount >= 3) return "Media";
  if (lessonCount > 0) return "Inicial";
  return "Sin datos";
}

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 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: WeeklyAvailabilityRange[]) {
  const slotSet = new Set<string>();
  for (const range of ranges) {
    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 getLocalTimeValue(value: string) {
  const date = new Date(value);
  const hours = String(date.getHours()).padStart(2, "0");
  const minutes = String(date.getMinutes()).padStart(2, "0");
  return `${hours}:${minutes}`;
}

function getGenderLabel(value: CoachStudentsResponse["players"][number]["gender"]) {
  if (value === "female") return "Mujer";
  if (value === "male") return "Hombre";
  if (value === "other") return "Otro";
  return "Sin dato";
}

function getStudentAgeLabel(birthYear: number | null) {
  if (!birthYear) return "Edad sin dato";
  const age = new Date().getFullYear() - birthYear;
  return age > 0 ? `${age} anos` : "Edad sin dato";
}

function getAutoSaveLabel(state: AutoSaveState) {
  if (state === "saving") return "Guardando...";
  if (state === "saved") return "Guardado";
  if (state === "error") return "Error al guardar";
  return "Se guarda automatico";
}

function createStudentContactDraft(player: CoachStudentsResponse["players"][number]): CoachStudentContactDraft {
  return {
    whatsappPhone: player.whatsappPhone ?? "",
    telegramHandle: player.telegramHandle ?? "",
  };
}

function buildWhatsAppHref(value: string | null) {
  if (!value) return null;
  const digits = value.replace(/\D/g, "");
  return digits.length > 0 ? `https://wa.me/${digits}` : null;
}

function buildTelegramHref(value: string | null) {
  if (!value) return null;
  const handle = value.replace(/^@/, "").trim();
  return handle.length > 0 ? `https://t.me/${handle}` : null;
}

function createStudentBookingDraft(
  settings: CoachSettingsResponse,
  panel: CoachStudentsResponse
): CoachStudentBookingDraft {
  const firstPackage = settings.commercial.packages.find((pkg) => pkg.active) ?? settings.commercial.packages[0] ?? null;
  const firstAvailability =
    settings.availability.items[0] ??
    settings.availability.context.allowedHours[0] ??
    null;

  return {
    playerId: panel.players[0]?.id ?? "",
    venueId: panel.venues[0]?.id ?? "",
    date: todayDateValue(),
    startTime: firstAvailability?.startTime ?? "09:00",
    durationMinutes: firstPackage?.durationMinutes ?? 60,
    repeatWeeklyCount: 1,
    note: "",
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone ?? "America/Montevideo",
  };
}

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

export function CoachSettingsPageClient() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [view, setView] = useState<CoachPageView>(() => {
    const nextView = searchParams.get("view");
    if (nextView === "performance" || nextView === "configuration" || nextView === "students") return nextView;
    return "calendar";
  });
  const [settings, setSettings] = useState<CoachSettingsResponse | null>(null);
  const [availabilityDraft, setAvailabilityDraft] = useState<WeeklyAvailabilityRange[]>([]);
  const [availabilityTimezone, setAvailabilityTimezone] = useState("America/Montevideo");
  const [clubSelectionDraft, setClubSelectionDraft] = useState<CoachClubSelection>({ mode: "all", clubIds: [] });
  const [packagesDraft, setPackagesDraft] = useState<CoachPackageDraft[]>([]);
  const [studentsPanel, setStudentsPanel] = useState<CoachStudentsResponse | null>(null);
  const [studentContactDrafts, setStudentContactDrafts] = useState<Record<string, CoachStudentContactDraft>>({});
  const [studentContactSaveStates, setStudentContactSaveStates] = useState<Record<string, AutoSaveState>>({});
  const [studentContactErrors, setStudentContactErrors] = useState<Record<string, string>>({});
  const [studentBookingDraft, setStudentBookingDraft] = useState<CoachStudentBookingDraft>({
    playerId: "",
    venueId: "",
    date: "",
    startTime: "09:00",
    durationMinutes: 60,
    repeatWeeklyCount: 1,
    note: "",
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone ?? "America/Montevideo",
  });
  const [studentCreateDraft, setStudentCreateDraft] = useState<CoachStudentCreateDraft>(() => createStudentCreateDraft());
  const [mercadoPagoHandle, setMercadoPagoHandle] = useState("");
  const [loading, setLoading] = useState(true);
  const [studentsLoading, setStudentsLoading] = useState(true);
  const [pageError, setPageError] = useState<string | null>(null);
  const [studentsError, setStudentsError] = useState<string | null>(null);
  const [availabilityError, setAvailabilityError] = useState<string | null>(null);
  const [clubsError, setClubsError] = useState<string | null>(null);
  const [commercialError, setCommercialError] = useState<string | null>(null);
  const [studentBookingError, setStudentBookingError] = useState<string | null>(null);
  const [studentCreateError, setStudentCreateError] = useState<string | null>(null);
  const [, setSavingAvailability] = useState(false);
  const [, setSavingClubs] = useState(false);
  const [, setSavingCommercial] = useState(false);
  const [savingStudentBooking, setSavingStudentBooking] = useState(false);
  const [creatingStudent, setCreatingStudent] = useState(false);
  const [savingStudentContactId, setSavingStudentContactId] = useState<string | null>(null);
  const [selectedCalendarSessionKey, setSelectedCalendarSessionKey] = useState<string | null>(null);
  const [clubsSaveState, setClubsSaveState] = useState<AutoSaveState>("idle");
  const [availabilitySaveState, setAvailabilitySaveState] = useState<AutoSaveState>("idle");
  const [commercialSaveState, setCommercialSaveState] = useState<AutoSaveState>("idle");
  const clubsSaveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const availabilitySaveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const commercialSaveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  useEffect(() => {
    const nextView = searchParams.get("view");
    if (nextView === "performance" || nextView === "configuration" || nextView === "students") {
      setView(nextView);
      return;
    }

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

  function handleViewChange(nextView: CoachPageView) {
    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 ? `/coaches/settings?${nextQuery}` : "/coaches/settings", { scroll: false });
  }

  function openStudentsComposer() {
    handleViewChange("students");
  }

  function syncDrafts(nextSettings: CoachSettingsResponse) {
    setSettings(nextSettings);
    setAvailabilityDraft(
      nextSettings.availability.items.map((item) => ({
        dayOfWeek: item.dayOfWeek,
        startTime: item.startTime,
        endTime: item.endTime,
      }))
    );
    setAvailabilityTimezone(
      nextSettings.availability.items[0]?.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone ?? "America/Montevideo"
    );
    setClubSelectionDraft(nextSettings.externalClubs.selection);
    setPackagesDraft(nextSettings.commercial.packages.map((pkg) => createPackageDraft(pkg)));
    setMercadoPagoHandle(nextSettings.commercial.mercadoPagoHandle ?? "");
  }

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

      if (!response.ok) {
        setStudentsPanel(null);
        setStudentsError(response.status === 401 ? null : "No pudimos cargar tus alumnos.");
        return;
      }

      const parsed = coachStudentsResponseSchema.parse(payload);
      setStudentsPanel(parsed);
      setStudentContactDrafts((current) => {
        const nextDrafts: Record<string, CoachStudentContactDraft> = {};
        for (const student of parsed.students) {
          nextDrafts[student.player.id] = current[student.player.id] ?? createStudentContactDraft(student.player);
        }
        return nextDrafts;
      });
      setStudentsError(null);
    } catch {
      setStudentsPanel(null);
      setStudentsError("No pudimos cargar tus alumnos.");
    } finally {
      setStudentsLoading(false);
    }
  }

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

      if (!response.ok) {
        setSettings(null);
        setPageError(response.status === 401 ? null : "No pudimos cargar tu panel.");
        return;
      }

      const parsed = coachMeResponseSchema.parse(payload);
      syncDrafts(parsed);
      setPageError(null);
    } catch {
      setSettings(null);
      setPageError("No pudimos cargar tu panel.");
    } finally {
      setLoading(false);
    }
  }

  const loadSettingsEffect = useEffectEvent(loadSettings);
  const loadStudentsPanelEffect = useEffectEvent(loadStudentsPanel);

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

  useEffect(() => {
    if (!settings || !studentsPanel) return;

    setStudentBookingDraft((current) => {
      const nextDefaults = createStudentBookingDraft(settings, studentsPanel);
      const playerStillExists = studentsPanel.players.some((player) => player.id === current.playerId);
      const venueStillExists = studentsPanel.venues.some((venue) => venue.id === current.venueId);
      return {
        playerId: current.playerId && playerStillExists ? current.playerId : nextDefaults.playerId,
        venueId: current.venueId && venueStillExists ? current.venueId : nextDefaults.venueId,
        date: current.date || nextDefaults.date,
        startTime: current.startTime || nextDefaults.startTime,
        durationMinutes: current.durationMinutes || nextDefaults.durationMinutes,
        repeatWeeklyCount: current.repeatWeeklyCount || nextDefaults.repeatWeeklyCount,
        note: current.note,
        timezone: current.timezone || nextDefaults.timezone,
      };
    });
  }, [settings, studentsPanel]);

  const activeStudentBookings = useMemo(
    () => studentsPanel?.bookings.filter((booking) => booking.status !== "canceled") ?? [],
    [studentsPanel]
  );

  const trackedStudents = useMemo(() => studentsPanel?.students ?? [], [studentsPanel]);
  const currentWeekDays = useMemo(() => getCurrentWeekDays(), []);
  const currentWeekDateSet = useMemo(() => new Set(currentWeekDays), [currentWeekDays]);
  const currentWeekBookings = useMemo(
    () => activeStudentBookings.filter((booking) => currentWeekDateSet.has(buildDateKey(booking.startsAt))),
    [activeStudentBookings, currentWeekDateSet]
  );
  const currentWeekEarnings = useMemo(
    () => currentWeekBookings.reduce((total, booking) => total + (booking.coachPriceMinor ?? 0), 0),
    [currentWeekBookings]
  );
  const currentWeekMinutes = useMemo(
    () => currentWeekBookings.reduce((total, booking) => total + booking.durationMinutes, 0),
    [currentWeekBookings]
  );
  const currentWeekStudentCount = useMemo(
    () => new Set(currentWeekBookings.map((booking) => booking.player.id)).size,
    [currentWeekBookings]
  );
  const currentWeekPaidCount = useMemo(
    () => currentWeekBookings.filter((booking) => booking.paymentStatus === "paid").length,
    [currentWeekBookings]
  );
  const currentWeekPendingCount = useMemo(
    () => currentWeekBookings.filter((booking) => booking.paymentStatus === "pending").length,
    [currentWeekBookings]
  );
  const availabilityByDate = useMemo(() => {
    const grouped = new Map<string, WeeklyAvailabilityRange[]>();

    for (const availability of settings?.availability.items ?? []) {
      const dateKey = getDateForWeeklyAvailability(currentWeekDays, availability.dayOfWeek);
      const current = grouped.get(dateKey) ?? [];
      current.push({
        dayOfWeek: availability.dayOfWeek,
        startTime: availability.startTime,
        endTime: availability.endTime,
      });
      grouped.set(dateKey, current);
    }

    return grouped;
  }, [settings, currentWeekDays]);
  const availabilitySlotsByDate = useMemo(() => {
    const grouped = new Map<string, Set<string>>();

    for (const dateKey of currentWeekDays) {
      grouped.set(dateKey, new Set(buildDaySlots(availabilityByDate.get(dateKey) ?? [])));
    }

    return grouped;
  }, [availabilityByDate, currentWeekDays]);
  const coachCalendarSessions = useMemo(() => {
    const grouped = new Map<string, CoachCalendarSession>();

    for (const booking of currentWeekBookings) {
      const dateKey = buildDateKey(booking.startsAt);
      const startsAtMillis = new Date(booking.startsAt).getTime();
      const endsAtMillis = new Date(booking.endsAt).getTime();
      const sessionKey = [
        dateKey,
        booking.venue.id,
        booking.court?.id ?? "sin-cancha",
        startsAtMillis,
        endsAtMillis,
      ].join("|");

      const current = grouped.get(sessionKey) ?? {
        key: sessionKey,
        startsAt: booking.startsAt,
        endsAt: booking.endsAt,
        startTime: getLocalTimeValue(booking.startsAt),
        endTime: getLocalTimeValue(booking.endsAt),
        dateKey,
        durationMinutes: booking.durationMinutes,
        venue: booking.venue,
        court: booking.court,
        note: booking.note,
        participants: [],
      };

      current.note = current.note ?? booking.note;
      current.participants.push({
        bookingId: booking.id,
        player: booking.player,
        paymentStatus: booking.paymentStatus,
      });
      grouped.set(sessionKey, current);
    }

    return Array.from(grouped.values())
      .map((session) => ({
        ...session,
        participants: [...session.participants].sort((left, right) => left.player.name.localeCompare(right.player.name)),
      }))
      .sort((left, right) => new Date(left.startsAt).getTime() - new Date(right.startsAt).getTime());
  }, [currentWeekBookings]);
  const coachCalendarSessionsByDayAndSlot = useMemo(() => {
    const grouped = new Map<string, CoachCalendarSession>();

    for (const session of coachCalendarSessions) {
      for (const slot of listHalfHourSlots(session.startTime, session.endTime)) {
        grouped.set(`${session.dateKey}|${slot}`, session);
      }
    }

    return grouped;
  }, [coachCalendarSessions]);
  const calendarWeekSlots = useMemo(() => {
    const slotSet = new Set<string>();

    for (const dateKey of currentWeekDays) {
      for (const slot of buildDaySlots(availabilityByDate.get(dateKey) ?? [])) {
        slotSet.add(slot);
      }
    }

    for (const session of coachCalendarSessions) {
      for (const slot of listHalfHourSlots(session.startTime, session.endTime)) {
        slotSet.add(slot);
      }
    }

    return Array.from(slotSet).sort((left, right) => (parseTimeToMinutes(left) ?? 0) - (parseTimeToMinutes(right) ?? 0));
  }, [availabilityByDate, coachCalendarSessions, currentWeekDays]);
  const currentWeekSessionMinutes = useMemo(
    () => coachCalendarSessions.reduce((total, session) => total + session.durationMinutes, 0),
    [coachCalendarSessions]
  );
  const todaySessionCount = useMemo(
    () => coachCalendarSessions.filter((session) => session.dateKey === todayDateValue()).length,
    [coachCalendarSessions]
  );
  const selectedCalendarSession = useMemo(
    () => coachCalendarSessions.find((session) => session.key === selectedCalendarSessionKey) ?? null,
    [coachCalendarSessions, selectedCalendarSessionKey]
  );
  useEffect(() => {
    if (selectedCalendarSessionKey && coachCalendarSessions.some((session) => session.key === selectedCalendarSessionKey)) return;
    setSelectedCalendarSessionKey(coachCalendarSessions[0]?.key ?? null);
  }, [coachCalendarSessions, selectedCalendarSessionKey]);
  const studentAnalyticsRows = useMemo(
    () =>
      trackedStudents.map((student) => {
        const weekBookings = currentWeekBookings.filter((booking) => booking.player.id === student.player.id);

        return {
          student,
          weekClassCount: weekBookings.length,
          weekRevenue: weekBookings.reduce((total, booking) => total + (booking.coachPriceMinor ?? 0), 0),
          consistency: getStudentConsistencyLabel(student.lessonCount, student.upcomingLessonCount),
        };
      }),
    [trackedStudents, currentWeekBookings]
  );

  const selectionDirty = settings ? selectionSignature(settings.externalClubs.selection) !== selectionSignature(clubSelectionDraft) : false;
  const availabilityDirty =
    settings !== null &&
    availabilitySignature(
      settings.availability.items.map((item) => ({
        dayOfWeek: item.dayOfWeek,
        startTime: item.startTime,
        endTime: item.endTime,
      })),
      settings.availability.items[0]?.timezone ?? availabilityTimezone
    ) !== availabilitySignature(availabilityDraft, availabilityTimezone);
  const commercialDirty =
    settings !== null &&
    ((settings.commercial.mercadoPagoHandle ?? "") !== mercadoPagoHandle ||
      packageSignature(settings.commercial.packages.map((pkg) => createPackageDraft(pkg))) !== packageSignature(packagesDraft));

  function updatePackage(clientId: string, patch: Partial<CoachPackageDraft>) {
    setPackagesDraft((current) =>
      current.map((pkg) =>
        pkg.clientId === clientId
          ? {
              ...pkg,
              ...patch,
            }
          : pkg
      )
    );
  }

  function removePackage(clientId: string) {
    setPackagesDraft((current) => current.filter((pkg) => pkg.clientId !== clientId));
  }

  function addPackage() {
    setPackagesDraft((current) => [...current, createPackageDraft()]);
  }

  function toggleClub(clubId: string) {
    setClubSelectionDraft((current) => {
      if (current.mode !== "custom") return current;

      const selectedIds = new Set(current.clubIds);
      if (selectedIds.has(clubId)) {
        selectedIds.delete(clubId);
      } else {
        selectedIds.add(clubId);
      }

      return {
        ...current,
        clubIds: [...selectedIds],
      };
    });
  }

  async function handleSaveAvailability(options?: { background?: boolean }) {
    if (!settings) return;
    const background = options?.background ?? false;

    if (!background) {
      setSavingAvailability(true);
      setAvailabilityError(null);
    }

    try {
      const response = await fetch("/api/coaches/availability", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          items: availabilityDraft.map((item) => ({
            ...item,
            timezone: availabilityTimezone,
          })),
        }),
      });
      const payload = await response.json().catch(() => null);

      if (!response.ok) {
        if (!background) {
          setAvailabilityError(payload?.details?.message ?? "No pudimos guardar tus horarios.");
          setAvailabilitySaveState("error");
        }
        return;
      }

      if (!background) {
        const parsed = coachAvailabilityResponseSchema.parse(payload);
        setAvailabilityDraft(
          parsed.items.map((item) => ({
            dayOfWeek: item.dayOfWeek,
            startTime: item.startTime,
            endTime: item.endTime,
          }))
        );
        setAvailabilityTimezone(parsed.items[0]?.timezone ?? availabilityTimezone);
        await loadSettings();
        setAvailabilitySaveState("saved");
      }
    } catch {
      if (!background) {
        setAvailabilityError("No pudimos guardar tus horarios.");
        setAvailabilitySaveState("error");
      }
    } finally {
      if (!background) {
        setSavingAvailability(false);
      }
    }
  }

  async function handleSaveClubs(options?: { background?: boolean }) {
    if (!settings) return;
    const background = options?.background ?? false;

    if (!background) {
      setSavingClubs(true);
      setClubsError(null);
    }

    try {
      const response = await fetch("/api/coaches/clubs", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(clubSelectionDraft),
      });
      const payload = await response.json().catch(() => null);

      if (!response.ok) {
        if (!background) {
          setClubsError(payload?.details?.message ?? "No pudimos guardar tus clubes.");
          setClubsSaveState("error");
        }
        return;
      }

      if (!background) {
        coachClubsResponseSchema.parse(payload);
        await loadSettings();
        setClubsSaveState("saved");
      }
    } catch {
      if (!background) {
        setClubsError("No pudimos guardar tus clubes.");
        setClubsSaveState("error");
      }
    } finally {
      if (!background) {
        setSavingClubs(false);
      }
    }
  }

  async function handleSaveCommercial(options?: { background?: boolean }) {
    if (!settings) return;
    const background = options?.background ?? false;

    if (!background) {
      setSavingCommercial(true);
      setCommercialError(null);
    }

    try {
      const response = await fetch("/api/coaches/me", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          mercadoPagoHandle: mercadoPagoHandle.trim() || null,
          packages: packagesDraft.map((pkg) => ({
            id: pkg.id,
            title: pkg.title,
            price: pkg.price,
            durationMinutes: pkg.durationMinutes,
            maxStudents: pkg.maxStudents,
            format: pkg.format,
            active: pkg.active,
          })),
        }),
      });
      const payload = await response.json().catch(() => null);

      if (!response.ok) {
        if (!background) {
          setCommercialError(payload?.details?.message ?? "No pudimos guardar tu configuracion comercial.");
          setCommercialSaveState("error");
        }
        return;
      }

      if (!background) {
        const parsed = coachMeResponseSchema.parse(payload);
        syncDrafts(parsed);
        setCommercialError(null);
        setCommercialSaveState("saved");
      }
    } catch {
      if (!background) {
        setCommercialError("No pudimos guardar tu configuracion comercial.");
        setCommercialSaveState("error");
      }
    } finally {
      if (!background) {
        setSavingCommercial(false);
      }
    }
  }

  const handleSaveClubsEffect = useEffectEvent(handleSaveClubs);
  const handleSaveAvailabilityEffect = useEffectEvent(handleSaveAvailability);
  const handleSaveCommercialEffect = useEffectEvent(handleSaveCommercial);

  useEffect(
    () => () => {
      if (clubsSaveTimer.current) {
        clearTimeout(clubsSaveTimer.current);
        clubsSaveTimer.current = null;
        void handleSaveClubsEffect({ background: true });
      }
      if (availabilitySaveTimer.current) {
        clearTimeout(availabilitySaveTimer.current);
        availabilitySaveTimer.current = null;
        void handleSaveAvailabilityEffect({ background: true });
      }
      if (commercialSaveTimer.current) {
        clearTimeout(commercialSaveTimer.current);
        commercialSaveTimer.current = null;
        void handleSaveCommercialEffect({ background: true });
      }
    },
    []
  );

  useEffect(() => {
    if (!settings || loading || !selectionDirty) return;

    setClubsSaveState("saving");
    if (clubsSaveTimer.current) clearTimeout(clubsSaveTimer.current);
    clubsSaveTimer.current = setTimeout(() => {
      clubsSaveTimer.current = null;
      void handleSaveClubsEffect();
    }, 700);
  }, [clubSelectionDraft, selectionDirty, settings, loading]);

  useEffect(() => {
    if (!settings || loading || selectionDirty || !availabilityDirty) return;

    setAvailabilitySaveState("saving");
    if (availabilitySaveTimer.current) clearTimeout(availabilitySaveTimer.current);
    availabilitySaveTimer.current = setTimeout(() => {
      availabilitySaveTimer.current = null;
      void handleSaveAvailabilityEffect();
    }, 700);
  }, [availabilityDraft, availabilityTimezone, availabilityDirty, selectionDirty, settings, loading]);

  useEffect(() => {
    if (!settings || loading || !commercialDirty) return;

    setCommercialSaveState("saving");
    if (commercialSaveTimer.current) clearTimeout(commercialSaveTimer.current);
    commercialSaveTimer.current = setTimeout(() => {
      commercialSaveTimer.current = null;
      void handleSaveCommercialEffect();
    }, 700);
  }, [packagesDraft, mercadoPagoHandle, commercialDirty, settings, loading]);

  async function handleCreateStudentBooking() {
    if (!studentsPanel || !settings) return;

    setSavingStudentBooking(true);
    setStudentBookingError(null);

    try {
      const response = await fetch("/api/coaches/students", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          playerId: studentBookingDraft.playerId,
          venueId: studentBookingDraft.venueId,
          startsAt: new Date(`${studentBookingDraft.date}T${studentBookingDraft.startTime}:00`).toISOString(),
          durationMinutes: studentBookingDraft.durationMinutes,
          timezone: studentBookingDraft.timezone,
          note: studentBookingDraft.note.trim() || null,
          recurrence:
            studentBookingDraft.repeatWeeklyCount > 1
              ? { frequency: "weekly", occurrences: studentBookingDraft.repeatWeeklyCount }
              : undefined,
        }),
      });
      const payload = await response.json().catch(() => null);

      if (!response.ok) {
        if (payload?.error === "BOOKING_OVERLAP") {
          setStudentBookingError("Ya tienes una clase cargada en ese horario.");
        } else if (payload?.error === "BOOKING_OUTSIDE_AVAILABILITY") {
          setStudentBookingError("Ese horario debe caer dentro de tu disponibilidad activa y de la sede elegida.");
        } else if (payload?.error === "PLAYER_NOT_FOUND") {
          setStudentBookingError("Ese alumno ya no existe.");
        } else if (payload?.error === "VENUE_NOT_FOUND") {
          setStudentBookingError("Esa sede ya no esta disponible para ti.");
        } else {
          setStudentBookingError(payload?.details?.message ?? "No pudimos guardar la clase tomada.");
        }
        return;
      }

      coachStudentBookingMutationResponseSchema.parse(payload);
      await loadStudentsPanel();
      setStudentBookingDraft((current) => ({
        ...current,
        repeatWeeklyCount: 1,
        note: "",
      }));
    } catch {
      setStudentBookingError("No pudimos guardar la clase tomada.");
    } finally {
      setSavingStudentBooking(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/coaches/students/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 loadStudentsPanel();
      setStudentBookingDraft((current) => ({
        ...current,
        playerId: parsed.item.id,
      }));
      setStudentCreateDraft(createStudentCreateDraft());
    } catch {
      setStudentCreateError("No pudimos crear el alumno.");
    } finally {
      setCreatingStudent(false);
    }
  }

  function updateStudentContactDraft(playerId: string, patch: Partial<CoachStudentContactDraft>) {
    setStudentContactDrafts((current) => ({
      ...current,
      [playerId]: {
        whatsappPhone: current[playerId]?.whatsappPhone ?? "",
        telegramHandle: current[playerId]?.telegramHandle ?? "",
        ...patch,
      },
    }));
  }

  async function handleSaveStudentContact(playerId: string) {
    const draft = studentContactDrafts[playerId];
    if (!draft) return;

    setSavingStudentContactId(playerId);
    setStudentContactSaveStates((current) => ({ ...current, [playerId]: "saving" }));
    setStudentContactErrors((current) => {
      const next = { ...current };
      delete next[playerId];
      return next;
    });

    try {
      const response = await fetch(`/api/coaches/students/players/${playerId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          whatsappPhone: draft.whatsappPhone.trim() || null,
          telegramHandle: draft.telegramHandle.trim() || null,
        }),
      });
      const payload = await response.json().catch(() => null);

      if (!response.ok) {
        const message = payload?.details?.message ?? "No pudimos guardar el contacto del alumno.";
        setStudentContactSaveStates((current) => ({ ...current, [playerId]: "error" }));
        setStudentContactErrors((current) => ({ ...current, [playerId]: message }));
        return;
      }

      coachStudentContactMutationResponseSchema.parse(payload);
      setStudentContactSaveStates((current) => ({ ...current, [playerId]: "saved" }));
      await loadStudentsPanel();
    } catch {
      setStudentContactSaveStates((current) => ({ ...current, [playerId]: "error" }));
      setStudentContactErrors((current) => ({
        ...current,
        [playerId]: "No pudimos guardar el contacto del alumno.",
      }));
    } finally {
      setSavingStudentContactId(null);
    }
  }

  function getPackageFinalPriceNote(price: number) {
    return `Tu precio por clase: ${formatMoney(price)}`;
  }

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

  if (!settings) {
    return (
      <div className="mt-8 max-w-xl rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6 text-white">
        <h2 className="text-2xl font-semibold">Acceso coach</h2>
        <p className="mt-2 text-sm text-white/65">
          Entra desde <span className="text-white">/coaches</span> para hacer sign in o sign up.
        </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>
        {pageError ? <p className="mt-4 text-sm text-red-200">{pageError}</p> : null}
      </div>
    );
  }

  const { coach, dashboard } = settings;
  const { context } = settings.availability;
  const availabilityStatusId = "coach-availability-status";
  const availabilityHelpId = "coach-availability-help";
  const availabilitySummaryId = "coach-availability-summary";
  const availabilityInstructionsId = "coach-availability-instructions";
  const availabilityErrorId = "coach-availability-error";
  const canSubmitStudentBooking =
    !!studentsPanel &&
    studentsPanel.venues.length > 0 &&
    studentsPanel.players.length > 0 &&
    !studentsPanel.summary.note &&
    studentBookingDraft.playerId.length > 0 &&
    studentBookingDraft.venueId.length > 0 &&
    studentBookingDraft.date.length > 0 &&
    studentBookingDraft.startTime.length > 0;
  return (
    <section className="space-y-6 text-white">
      <AuthenticatedWorkspaceNavbar
        email={coach.email}
        sections={[
          {
            label: "Calendario",
            active: view === "calendar",
            onClick: () => handleViewChange("calendar"),
          },
          {
            label: "Performance",
            active: view === "performance",
            onClick: () => handleViewChange("performance"),
          },
          {
            label: "Alumnos",
            active: view === "students",
            onClick: () => handleViewChange("students"),
          },
          {
            label: "Horarios y Clases",
            active: view === "configuration",
            onClick: () => handleViewChange("configuration"),
          },
        ]}
        onSignOut={async () => {
          await fetch("/api/coaches/logout", { method: "POST" });
          window.location.href = "/coaches";
        }}
      />

      {view === "calendar" ? (
        <>
          <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
            <button
              type="button"
              onClick={openStudentsComposer}
              className="group flex w-full flex-col justify-between gap-6 rounded-[1.5rem] border border-[#c4d600]/20 bg-[radial-gradient(circle_at_top_left,_rgba(196,214,0,0.16),_transparent_48%),linear-gradient(180deg,rgba(255,255,255,0.02),rgba(255,255,255,0))] p-6 text-left transition hover:border-[#c4d600]/40 hover:bg-[radial-gradient(circle_at_top_left,_rgba(196,214,0,0.22),_transparent_52%),linear-gradient(180deg,rgba(255,255,255,0.03),rgba(255,255,255,0))]"
            >
              <div>
                <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Accion rapida</p>
                <h3 className="mt-3 text-3xl font-semibold text-white">Agregar clase</h3>
                <p className="mt-3 max-w-2xl text-sm text-white/65">
                  Te llevamos a <span className="text-white">Alumnos</span> para cargar una clase nueva, elegir un alumno existente
                  o crear uno en el momento.
                </p>
              </div>

              <div className="flex flex-wrap 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">
                    {context.mode === "venue"
                      ? coach.venue
                        ? `Sede ${coach.venue.name}`
                        : "Pendiente de sede"
                      : context.mode === "external-clubs"
                        ? "Coach externo"
                        : "Esperando habilitacion"}
                  </span>
                  <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1">
                    {summarizeAllowedHours(context.allowedHours)}
                  </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]">
                  Ir a alumnos
                </span>
              </div>
            </button>
          </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]">Calendario</p>
                <h3 className="mt-2 text-2xl font-semibold">Tus alumnos por semana y por hora</h3>
              </div>
              <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                {coachCalendarSessions.length} clases cargadas
              </span>
            </div>

            <div className="mt-5 grid gap-3 md:grid-cols-2 xl:grid-cols-4">
              <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">Clases hoy</p>
                <p className="mt-2 text-2xl font-semibold text-white">{todaySessionCount}</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">Semana</p>
                <p className="mt-2 text-2xl font-semibold text-white">{coachCalendarSessions.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">Horas semana</p>
                <p className="mt-2 text-2xl font-semibold text-white">
                  {formatBookedHours(currentWeekSessionMinutes)}
                </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">Pagos</p>
                <p className="mt-2 text-2xl font-semibold text-white">{currentWeekPaidCount}</p>
                <p className="mt-1 text-xs text-white/55">{currentWeekPendingCount} pendientes</p>
              </div>
            </div>

            {studentsLoading ? (
              <p className="mt-5 text-sm text-white/55">Cargando alumnos y agenda...</p>
            ) : studentsError ? (
              <p className="mt-5 rounded-xl border border-red-500/40 bg-red-500/10 px-4 py-3 text-sm text-red-200">{studentsError}</p>
            ) : studentsPanel?.summary.note ? (
              <div className="mt-5 rounded-[1rem] border border-white/10 bg-[#0d110d] p-4 text-sm text-white/65">
                {studentsPanel.summary.note}
              </div>
            ) : calendarWeekSlots.length === 0 ? (
              <div className="mt-5 rounded-[1.25rem] border border-dashed border-white/10 bg-black/10 p-5 text-sm text-white/55">
                Todavia no tienes horarios ni clases en esta semana.
              </div>
            ) : (
              <div className="mt-5 space-y-5">
                <div className="overflow-x-auto rounded-[1.25rem] border border-white/10 bg-black/20">
                  <table className="min-w-[980px] table-fixed border-separate border-spacing-0 text-left align-top">
                    <thead>
                      <tr>
                        <th className="w-[7.5rem] border-b border-white/10 bg-[#0d110d] px-4 py-4 text-xs uppercase tracking-[0.16em] text-white/45">
                          Hora
                        </th>
                        {currentWeekDays.map((dateKey) => {
                          const daySessions = coachCalendarSessions.filter((session) => session.dateKey === dateKey).length;

                          return (
                            <th key={dateKey} className="min-w-[12rem] border-b border-l border-white/10 bg-[#0d110d] px-4 py-4">
                              <p className="text-sm font-medium text-white">{formatLongDate(dateKey)}</p>
                              <p className="mt-1 text-xs text-white/50">{daySessions} clases</p>
                            </th>
                          );
                        })}
                      </tr>
                    </thead>
                    <tbody>
                      {calendarWeekSlots.map((slot) => (
                        <tr key={slot}>
                          <th className="border-b border-white/10 bg-[#0d110d] px-4 py-4 align-top text-lg font-medium text-white">
                            {formatSlotLabel(slot)}
                          </th>
                          {currentWeekDays.map((dateKey) => {
                            const session = coachCalendarSessionsByDayAndSlot.get(`${dateKey}|${slot}`) ?? null;
                            const isAllowed = availabilitySlotsByDate.get(dateKey)?.has(slot) ?? false;

                            if (session) {
                              const paidCount = session.participants.filter((participant) => participant.paymentStatus === "paid").length;
                              const pendingCount = session.participants.length - paidCount;
                              const isSelected = selectedCalendarSession?.key === session.key;

                              return (
                                <td key={`${dateKey}-${slot}`} className="border-b border-l border-white/10 p-2 align-top">
                                  <button
                                    type="button"
                                    onClick={() => setSelectedCalendarSessionKey(session.key)}
                                    className={`flex min-h-[10.5rem] w-full flex-col rounded-[1rem] border p-3 text-left transition ${
                                      isSelected
                                        ? "border-[#c4d600]/45 bg-[#1b2411]"
                                        : "border-[#c4d600]/25 bg-[#141b10] hover:border-[#c4d600]/40"
                                    }`}
                                  >
                                    <div className="flex flex-wrap items-start justify-between gap-2">
                                      <div>
                                        <p className="text-sm font-semibold text-white">
                                          {session.participants.length > 1 ? `Grupal · ${session.participants.length} alumnos` : "Individual"}
                                        </p>
                                        <p className="mt-1 text-xs text-white/60">
                                          {session.venue.name}
                                          {session.court ? ` · ${session.court.name}` : ""}
                                        </p>
                                      </div>
                                      <span className="rounded-full border border-white/10 px-2.5 py-1 text-[11px] text-white/70">
                                        {paidCount}/{session.participants.length} pagos
                                      </span>
                                    </div>

                                    <div className="mt-3 space-y-2">
                                      {session.participants.slice(0, 2).map((participant) => (
                                        <div key={participant.bookingId} className="rounded-xl border border-white/10 bg-black/15 px-3 py-2">
                                          <p className="text-sm font-medium text-white">{participant.player.name}</p>
                                          <p className="mt-1 text-[11px] text-white/55">
                                            {getGenderLabel(participant.player.gender)} · {getStudentAgeLabel(participant.player.birthYear)} ·{" "}
                                            {participant.player.coachCategory ?? "Sin categoria"}
                                          </p>
                                        </div>
                                      ))}
                                      {session.participants.length > 2 ? (
                                        <p className="text-xs text-white/55">+{session.participants.length - 2} alumnos mas</p>
                                      ) : null}
                                    </div>

                                    <div className="mt-auto pt-3">
                                      <p className="text-xs font-medium text-[#d9ef31]">{session.startTime} - {session.endTime}</p>
                                      {pendingCount > 0 ? (
                                        <p className="mt-1 text-[11px] text-amber-200">{pendingCount} reserva{pendingCount === 1 ? "" : "s"} sin pagar</p>
                                      ) : (
                                        <p className="mt-1 text-[11px] text-emerald-200">Todo pago</p>
                                      )}
                                    </div>
                                  </button>
                                </td>
                              );
                            }

                            return (
                              <td key={`${dateKey}-${slot}`} className="border-b border-l border-white/10 p-2 align-top">
                                <div
                                  className={`flex min-h-[10.5rem] w-full flex-col rounded-[1rem] border p-3 ${
                                    isAllowed
                                      ? "border-dashed border-white/15 bg-black/10"
                                      : "border-red-500/15 bg-[#220c0c]/70"
                                  }`}
                                >
                                  <p className="text-sm font-medium text-white">
                                    {isAllowed ? "Disponible" : "Fuera de disponibilidad"}
                                  </p>
                                  <p className="mt-2 text-xs text-white/50">
                                    {isAllowed
                                      ? "Ese bloque esta abierto para que tomes una clase."
                                      : "No tienes horario abierto para dar clase en esta media hora."}
                                  </p>
                                </div>
                              </td>
                            );
                          })}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>

                {selectedCalendarSession ? (
                  <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-5">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <div>
                        <p className="text-xs uppercase tracking-[0.16em] text-[#c4d600]">Detalle de clase</p>
                        <h4 className="mt-2 text-xl font-semibold text-white">
                          {selectedCalendarSession.participants.length > 1 ? "Clase grupal" : "Clase individual"}
                        </h4>
                        <p className="mt-2 text-sm text-white/60">
                          {formatLongDate(selectedCalendarSession.dateKey)} · {selectedCalendarSession.startTime} - {selectedCalendarSession.endTime}
                        </p>
                        <p className="mt-1 text-sm text-white/60">
                          {selectedCalendarSession.venue.clubName} · {selectedCalendarSession.venue.name}
                          {selectedCalendarSession.court ? ` · ${selectedCalendarSession.court.name}` : ""}
                        </p>
                      </div>
                      <div className="flex flex-wrap gap-2">
                        <span className="rounded-full border border-emerald-500/25 bg-emerald-500/10 px-3 py-1 text-xs text-emerald-100">
                          {
                            selectedCalendarSession.participants.filter((participant) => participant.paymentStatus === "paid").length
                          }{" "}
                          pagos
                        </span>
                        <span className="rounded-full border border-amber-500/25 bg-amber-500/10 px-3 py-1 text-xs text-amber-100">
                          {
                            selectedCalendarSession.participants.filter((participant) => participant.paymentStatus === "pending").length
                          }{" "}
                          pendientes
                        </span>
                      </div>
                    </div>

                    {selectedCalendarSession.note ? (
                      <div className="mt-4 rounded-[1rem] border border-white/10 bg-[#0d110d] px-4 py-3 text-sm text-white/65">
                        {selectedCalendarSession.note}
                      </div>
                    ) : null}

                    <div className="mt-5 grid gap-4 xl:grid-cols-2">
                      {selectedCalendarSession.participants.map((participant) => {
                        const whatsappHref = buildWhatsAppHref(participant.player.whatsappPhone);
                        const telegramHref = buildTelegramHref(participant.player.telegramHandle);

                        return (
                          <div key={participant.bookingId} className="rounded-[1.1rem] border border-white/10 bg-[#0d110d] p-4">
                            <div className="flex flex-wrap items-start justify-between gap-3">
                              <div>
                                <p className="text-lg font-medium text-white">{participant.player.name}</p>
                                <p className="mt-1 text-sm text-white/55">
                                  {getGenderLabel(participant.player.gender)} · {getStudentAgeLabel(participant.player.birthYear)} ·{" "}
                                  {participant.player.coachCategory ?? "Sin categoria"}
                                </p>
                              </div>
                              <span
                                className={`rounded-full border px-3 py-1 text-xs ${
                                  participant.paymentStatus === "paid"
                                    ? "border-emerald-500/25 bg-emerald-500/10 text-emerald-100"
                                    : "border-amber-500/25 bg-amber-500/10 text-amber-100"
                                }`}
                              >
                                {participant.paymentStatus === "paid" ? "Pago" : "Pendiente"}
                              </span>
                            </div>

                            <div className="mt-4 flex flex-wrap gap-2">
                              {whatsappHref ? (
                                <a
                                  href={whatsappHref}
                                  target="_blank"
                                  rel="noreferrer"
                                  aria-label={`Abrir WhatsApp de ${participant.player.name} en una nueva pestaña`}
                                  className="rounded-full border border-white/10 px-3 py-1.5 text-xs text-white/75 transition hover:border-white/20 hover:text-white"
                                >
                                  WhatsApp
                                </a>
                              ) : null}
                              {telegramHref ? (
                                <a
                                  href={telegramHref}
                                  target="_blank"
                                  rel="noreferrer"
                                  aria-label={`Abrir Telegram de ${participant.player.name} en una nueva pestaña`}
                                  className="rounded-full border border-white/10 px-3 py-1.5 text-xs text-white/75 transition hover:border-white/20 hover:text-white"
                                >
                                  Telegram
                                </a>
                              ) : null}
                            </div>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                ) : null}
              </div>
            )}
          </article>
        </>
      ) : view === "performance" ? (
        <>
          <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]">Clubs</p>
                <h3 className="mt-2 text-2xl font-semibold">Tu performance por club</h3>
              </div>
              <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                {dashboard.clubs.length} clubs
              </span>
            </div>

            <div className="mt-5 space-y-4">
              {dashboard.clubs.length === 0 ? (
                <div className="rounded-[1.25rem] border border-dashed border-white/10 bg-black/10 p-5 text-sm text-white/55">
                  Todavia no tienes actividad en clubs. En configuracion puedes elegir donde vender y abrir tus horarios.
                </div>
              ) : null}

              {dashboard.clubs.map((clubItem) => (
                <div key={clubItem.id} className="rounded-[1.5rem] border border-white/10 bg-black/20 p-5">
                  <div className="flex flex-wrap items-center justify-between gap-3">
                    <div>
                      <p className="text-lg font-medium text-white">{clubItem.name}</p>
                      <p className="mt-1 text-sm text-white/60">
                        {clubItem.venueNames.length > 0
                          ? clubItem.venueNames.join(" · ")
                          : clubItem.role === "club-coach"
                            ? "Sin sede asignada"
                            : "Sin sedes elegidas"}
                      </p>
                    </div>
                    <div className="flex flex-wrap items-center gap-3">
                      <span className="rounded-full border border-white/10 px-3 py-1 text-xs text-white/60">
                        {clubItem.role === "club-coach" ? "Coach del club" : "Coach externo"}
                      </span>
                      <span className="rounded-full border border-white/10 px-3 py-1 text-xs text-white/60">
                        {formatAverageReview(clubItem.averageReview)}
                      </span>
                    </div>
                  </div>

                  <div className="mt-4 grid gap-3 sm:grid-cols-4">
                    <div className="rounded-xl border border-white/10 bg-[#0d110d] p-3">
                      <p className="text-xs uppercase tracking-[0.16em] text-white/45">Clases</p>
                      <p className="mt-2 text-sm text-white">{clubItem.publishedLessons}</p>
                    </div>
                    <div className="rounded-xl border border-white/10 bg-[#0d110d] p-3">
                      <p className="text-xs uppercase tracking-[0.16em] text-white/45">Solicitudes</p>
                      <p className="mt-2 text-sm text-white">{clubItem.requestCount}</p>
                    </div>
                    <div className="rounded-xl border border-white/10 bg-[#0d110d] p-3">
                      <p className="text-xs uppercase tracking-[0.16em] text-white/45">Valor publicado</p>
                      <p className="mt-2 text-sm text-white">{formatMoney(clubItem.listedRevenue)}</p>
                    </div>
                    <div className="rounded-xl border border-white/10 bg-[#0d110d] p-3">
                      <p className="text-xs uppercase tracking-[0.16em] text-white/45">Fees del club</p>
                      <p className="mt-2 text-sm text-white">{formatMoney(clubItem.estimatedClubFees)}</p>
                    </div>
                  </div>
                </div>
              ))}
            </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]">Performance</p>
                <h3 className="mt-2 text-2xl font-semibold">Como te esta yendo esta semana</h3>
              </div>
              <span className="rounded-full border border-white/10 bg-black/20 px-3 py-1 text-xs text-white/60">
                {formatShortDateLabel(currentWeekDays[0] ?? todayDateValue())} - {formatShortDateLabel(currentWeekDays[6] ?? todayDateValue())}
              </span>
            </div>

            <div className="mt-5 grid gap-3 md:grid-cols-2 xl:grid-cols-4">
              <div className="rounded-[1.25rem] border border-[#c4d600]/25 bg-[#c4d600]/10 p-4">
                <p className="text-xs uppercase tracking-[0.16em] text-[#d9ef31]">Ganaste esta semana</p>
                <p className="mt-2 text-3xl font-semibold text-white">{formatMoney(currentWeekEarnings)}</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">Clases semana</p>
                <p className="mt-2 text-3xl font-semibold text-white">{currentWeekBookings.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">Alumnos semana</p>
                <p className="mt-2 text-3xl font-semibold text-white">{currentWeekStudentCount}</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">Horas semana</p>
                <p className="mt-2 text-3xl font-semibold text-white">{formatBookedHours(currentWeekMinutes)}</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">
                <thead className="border-b border-white/10 bg-black/20 text-xs uppercase tracking-[0.16em] text-white/45">
                  <tr>
                    <th className="px-4 py-3 font-medium">Alumno</th>
                    <th className="px-4 py-3 font-medium">Clases totales</th>
                    <th className="px-4 py-3 font-medium">Esta semana</th>
                    <th className="px-4 py-3 font-medium">Consistencia</th>
                    <th className="px-4 py-3 font-medium">Reviews</th>
                    <th className="px-4 py-3 font-medium">Ingreso semana</th>
                  </tr>
                </thead>
                <tbody>
                  {studentAnalyticsRows.length === 0 ? (
                    <tr>
                      <td colSpan={6} className="px-4 py-6 text-center text-sm text-white/50">
                        Todavia no hay alumnos con seguimiento.
                      </td>
                    </tr>
                  ) : null}

                  {studentAnalyticsRows.map((row) => (
                    <tr key={row.student.player.id} className="border-b border-white/5 last:border-b-0">
                      <td className="px-4 py-4">
                        <p className="font-medium text-white">{row.student.player.name}</p>
                        <p className="mt-1 text-xs text-white/50">{row.student.venueNames.join(" · ") || "Sin sede"}</p>
                      </td>
                      <td className="px-4 py-4 text-white/70">{row.student.lessonCount}</td>
                      <td className="px-4 py-4 text-white/70">{row.weekClassCount}</td>
                      <td className="px-4 py-4 text-white/70">{row.consistency}</td>
                      <td className="px-4 py-4 text-white/70">Sin resenas</td>
                      <td className="px-4 py-4 text-white/70">{formatMoney(row.weekRevenue)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </article>
        </>
      ) : view === "configuration" ? (
        <>
          <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
            <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Afiliacion</p>
            {coach.club ? (
              <>
                <h3 className="mt-2 text-2xl font-semibold">{coach.club.name}</h3>
                <p className="mt-2 text-sm text-white/65">
                  {coach.venue ? `Trabajas desde la sede ${coach.venue.name}.` : "Todavia no te asignaron una sede dentro del club."}
                </p>
                {coach.court ? <p className="mt-1 text-sm text-white/50">Cancha asignada: {coach.court.name}</p> : null}
              </>
            ) : (
              <>
                <h3 className="mt-2 text-2xl font-semibold">Coach independiente</h3>
                <p className="mt-2 text-sm text-white/65">
                  Puedes abrir horarios en clubes que acepten profesores externos y vender ahi tus clases.
                </p>
              </>
            )}

            {context.assignedVenue ? (
              <div className="mt-5 grid gap-4 lg:grid-cols-[1fr_0.8fr]">
                <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-4">
                  <p className="text-sm font-medium text-white">Tu sede</p>
                  <p className="mt-2 text-lg text-white">{context.assignedVenue.name}</p>
                  <p className="mt-2 text-sm text-white/60">Tu club define internamente el valor de la cancha para cada horario.</p>
                  <p className="mt-1 text-sm text-white/60">
                    Cancelacion tardia: {context.assignedVenue.coachCancellationWindowHours} hs antes
                  </p>
                </div>
                <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-4">
                  <p className="text-sm font-medium text-white">Canchas habilitadas</p>
                  <div className="mt-3 flex flex-wrap gap-2">
                    {context.assignedVenue.availableCourts.length === 0 ? (
                      <span className="text-sm text-white/55">El club todavia no habilito canchas para coaches.</span>
                    ) : (
                      context.assignedVenue.availableCourts.map((court) => (
                        <span key={court.id} className="rounded-full border border-white/10 px-3 py-1 text-xs text-white/70">
                          {court.name} · {court.covered ? "techada" : "no techada"}
                        </span>
                      ))
                    )}
                  </div>
                </div>
              </div>
            ) : null}
          </article>

          {coach.affiliation === "independent" ? (
            <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]">Clubes externos</p>
                  <h3 className="mt-2 text-xl font-semibold">Donde quieres dar clases</h3>
                  <p className="mt-2 text-sm text-white/65">
                    Eliges en que clubes vender, y despues tu disponibilidad se adapta a los horarios que ellos habilitaron para coaches externos.
                  </p>
                </div>
                <span
                  className={`rounded-full border px-3 py-1 text-xs ${
                    clubsSaveState === "error"
                      ? "border-red-500/30 bg-red-500/10 text-red-200"
                      : clubsSaveState === "saved"
                        ? "border-[#c4d600]/30 bg-[#c4d600]/10 text-[#d9ef31]"
                        : "border-white/10 bg-black/20 text-white/55"
                  }`}
                >
                  {getAutoSaveLabel(clubsSaveState)}
                </span>
              </div>

              <fieldset className="mt-5 flex flex-wrap gap-3">
                <legend className="sr-only">Modo de seleccion de clubes</legend>
                <label
                  className={`rounded-full border px-4 py-2 text-sm transition ${
                    clubSelectionDraft.mode === "all"
                      ? "border-[#c4d600]/40 bg-[#c4d600]/15 text-white"
                      : "border-white/10 bg-black/20 text-white/65 hover:border-white/20 hover:text-white"
                  }`}
                >
                  <input
                    type="radio"
                    name="club-selection-mode"
                    value="all"
                    checked={clubSelectionDraft.mode === "all"}
                    onChange={() => setClubSelectionDraft({ mode: "all", clubIds: settings.externalClubs.clubs.map((club) => club.id) })}
                    className="sr-only"
                  />
                  Todos los clubes abiertos
                </label>
                <label
                  className={`rounded-full border px-4 py-2 text-sm transition ${
                    clubSelectionDraft.mode === "custom"
                      ? "border-[#c4d600]/40 bg-[#c4d600]/15 text-white"
                      : "border-white/10 bg-black/20 text-white/65 hover:border-white/20 hover:text-white"
                  }`}
                >
                  <input
                    type="radio"
                    name="club-selection-mode"
                    value="custom"
                    checked={clubSelectionDraft.mode === "custom"}
                    onChange={() =>
                      setClubSelectionDraft({
                        mode: "custom",
                        clubIds: clubSelectionDraft.mode === "custom" ? clubSelectionDraft.clubIds : [],
                      })
                    }
                    className="sr-only"
                  />
                  Elegir manualmente
                </label>
              </fieldset>

              <div className="mt-5 grid gap-4 lg:grid-cols-2">
                {settings.externalClubs.clubs.length === 0 ? (
                  <div className="rounded-[1.25rem] border border-white/10 bg-black/20 p-5 text-sm text-white/55">
                    Todavia no hay clubes con sedes activas para coaches externos.
                  </div>
                ) : (
                  settings.externalClubs.clubs.map((clubItem) => {
                    const selected = clubSelectionDraft.mode === "all" || clubSelectionDraft.clubIds.includes(clubItem.id);

                    return (
                      <button
                        key={clubItem.id}
                        type="button"
                        disabled={clubSelectionDraft.mode !== "custom"}
                        aria-pressed={selected}
                        onClick={() => toggleClub(clubItem.id)}
                        className={`rounded-[1.25rem] border p-5 text-left transition ${
                          selected
                            ? "border-[#c4d600]/35 bg-[#13180f]"
                            : "border-white/10 bg-black/20 hover:border-white/20"
                        } ${clubSelectionDraft.mode !== "custom" ? "cursor-default" : ""}`}
                      >
                        <div className="flex flex-wrap items-center justify-between gap-3">
                          <div>
                            <p className="text-lg font-medium text-white">{clubItem.name}</p>
                            <p className="mt-1 text-sm text-white/55">{clubItem.externalVenueCount} sedes externas habilitadas</p>
                          </div>
                          <span className="rounded-full border border-white/10 px-3 py-1 text-xs text-white/65">
                            {selected ? "Seleccionado" : "Disponible"}
                          </span>
                        </div>
                        <div className="mt-4 flex flex-wrap gap-2">
                          {clubItem.venues.map((venue) => (
                            <span key={venue.id} className="rounded-full border border-white/10 px-3 py-1 text-xs text-white/60">
                              {venue.name}
                            </span>
                          ))}
                        </div>
                      </button>
                    );
                  })
                )}
              </div>

              {selectionDirty ? <p className="mt-4 text-sm text-[#c4d600]">Estamos recalculando tus clubes y horarios habilitados.</p> : null}
              {clubsError ? <p className="mt-4 text-sm text-red-200">{clubsError}</p> : null}
            </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]">Disponibilidad</p>
                <h3 className="mt-2 text-xl font-semibold">Cuando quieres trabajar</h3>
                <p className="mt-2 text-sm text-white/65">
                  Marcás tus bloques de media hora dentro de lo que te permite tu sede o tus clubes externos.
                </p>
              </div>
              <span
                id={availabilityStatusId}
                role="status"
                aria-live="polite"
                className={`rounded-full border px-3 py-1 text-xs ${
                  availabilitySaveState === "error"
                    ? "border-red-500/30 bg-red-500/10 text-red-200"
                    : availabilitySaveState === "saved"
                      ? "border-[#c4d600]/30 bg-[#c4d600]/10 text-[#d9ef31]"
                      : "border-white/10 bg-black/20 text-white/55"
                }`}
              >
                {getAutoSaveLabel(availabilitySaveState)}
              </span>
            </div>

            <div className="mt-5 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 id={availabilitySummaryId} className="text-sm font-medium text-white">
                    {context.mode === "venue"
                      ? "Horarios de tu sede"
                      : context.mode === "external-clubs"
                        ? "Horarios permitidos por tus clubes"
                        : "Todavia no tienes horarios habilitados"}
                  </p>
                  <p id={availabilityHelpId} className="mt-1 text-xs text-white/55">
                    {context.note ?? "Lo rojo marca franjas cerradas o no habilitadas para coaches."}
                  </p>
                </div>
                <span className="rounded-full border border-white/10 px-3 py-1 text-xs text-white/60">
                  {summarizeAllowedHours(context.allowedHours)}
                </span>
              </div>
            </div>

            {selectionDirty ? (
              <p className="mt-4 text-sm text-[#c4d600]">Esperando que se guarde la seleccion de clubes para actualizar esta grilla.</p>
            ) : context.allowedHours.length === 0 ? (
              <div className="mt-4 rounded-[1.25rem] border border-white/10 bg-black/20 p-5 text-sm text-white/55">
                {context.note ?? "Todavia no hay horarios disponibles para marcar."}
              </div>
            ) : (
              <fieldset className="mt-4 rounded-[1.25rem] border border-white/10 bg-black/10 p-4">
                <legend className="px-2 text-sm font-medium text-white">Grilla semanal de disponibilidad</legend>
                <p className="mt-2 text-xs text-white/55">Marca solo los bloques donde quieres tomar clases. La grilla se guarda automaticamente.</p>
                <div aria-describedby={`${availabilitySummaryId} ${availabilityHelpId} ${availabilityInstructionsId} ${availabilityStatusId}${availabilityError ? ` ${availabilityErrorId}` : ""}`}>
                  <WeeklyAvailabilityGrid
                    value={availabilityDraft}
                    onChange={setAvailabilityDraft}
                    blockedRanges={context.allowedHours}
                    selectedLabel="Disponible"
                    openLabel="Disponible para marcar"
                    blockedLabel="Fuera del horario permitido"
                    instructionsId={availabilityInstructionsId}
                  />
                </div>
              </fieldset>
            )}

            {availabilityError ? (
              <p id={availabilityErrorId} role="alert" className="mt-4 text-sm text-red-200">
                {availabilityError}
              </p>
            ) : 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]">Paquetes</p>
                <h3 className="mt-2 text-xl font-semibold">Como quieres vender tus clases</h3>
                <p className="mt-2 text-sm text-white/65">
                  Defines tu precio, duracion, cantidad maxima de alumnos y si la clase es individual o grupal.
                </p>
              </div>
              <div className="flex flex-wrap items-center gap-3">
                <button
                  type="button"
                  onClick={addPackage}
                  className="rounded-full border border-white/10 px-4 py-2 text-sm text-white/70 transition hover:border-white/20 hover:text-white"
                >
                  Agregar paquete
                </button>
                <span
                  role="status"
                  aria-live="polite"
                  className={`rounded-full border px-3 py-1 text-xs ${
                    commercialSaveState === "error"
                      ? "border-red-500/30 bg-red-500/10 text-red-200"
                      : commercialSaveState === "saved"
                        ? "border-[#c4d600]/30 bg-[#c4d600]/10 text-[#d9ef31]"
                        : "border-white/10 bg-black/20 text-white/55"
                  }`}
                >
                  {getAutoSaveLabel(commercialSaveState)}
                </span>
              </div>
            </div>

            <div className="mt-5 space-y-4">
              {packagesDraft.length === 0 ? (
                <div className="rounded-[1.25rem] border border-dashed border-white/10 bg-black/10 p-5 text-sm text-white/55">
                  Todavia no armaste paquetes. Puedes empezar con una clase individual y despues sumar grupales.
                </div>
              ) : null}

              {packagesDraft.map((pkg, packageIndex) => {
                const packageTitle = pkg.title.trim().length > 0 ? pkg.title : `Paquete ${packageIndex + 1}`;
                const packageBaseId = `coach-package-${pkg.clientId}`;
                const formatHelpId = `${packageBaseId}-format-help`;
                const studentHelpId = `${packageBaseId}-students-help`;
                const activeHelpId = `${packageBaseId}-active-help`;

                return (
                  <fieldset key={pkg.clientId} className="rounded-[1.25rem] border border-white/10 bg-black/20 p-5">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <legend className="text-sm font-medium text-white">{packageTitle}</legend>
                      <button
                        type="button"
                        className="rounded-xl border border-red-500/25 px-4 py-2 text-sm text-red-200 transition hover:bg-red-500/10"
                        onClick={() => removePackage(pkg.clientId)}
                      >
                        Quitar
                      </button>
                    </div>

                    <div className="mt-4 grid gap-4 lg:grid-cols-[1.1fr_0.8fr_0.8fr_0.8fr]">
                      <label className="block text-sm text-white/70">
                        Nombre del paquete
                        <input
                          value={pkg.title}
                          onChange={(event) => updatePackage(pkg.clientId, { title: 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">
                        Tu precio
                        <input
                          type="number"
                          min={0}
                          step={1}
                          value={pkg.price}
                          onChange={(event) => updatePackage(pkg.clientId, { price: 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">
                        Duracion
                        <select
                          value={pkg.durationMinutes}
                          onChange={(event) => updatePackage(pkg.clientId, { durationMinutes: Number(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"
                        >
                          {[30, 60, 90, 120].map((value) => (
                            <option key={value} value={value}>
                              {formatDuration(value)}
                            </option>
                          ))}
                        </select>
                      </label>
                      <label className="block text-sm text-white/70">
                        Max alumnos
                        <input
                          type="number"
                          min={pkg.format === "group" ? 2 : 1}
                          step={1}
                          value={pkg.maxStudents}
                          onChange={(event) =>
                            updatePackage(pkg.clientId, {
                              maxStudents: Math.max(pkg.format === "group" ? 2 : 1, Number(event.target.value || (pkg.format === "group" ? 2 : 1))),
                            })
                          }
                          disabled={pkg.format === "individual"}
                          aria-describedby={studentHelpId}
                          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"
                        />
                      </label>
                    </div>

                    <div className="mt-4 grid gap-4 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-start">
                      <fieldset>
                        <legend className="text-sm text-white/70">Formato de la clase</legend>
                        <p id={formatHelpId} className="mt-1 text-xs text-white/50">
                          Individual usa un alumno. Grupal habilita dos o mas alumnos.
                        </p>
                        <div className="mt-3 flex flex-wrap gap-3" aria-describedby={formatHelpId}>
                          <label
                            className={`inline-flex cursor-pointer items-center gap-2 rounded-full border px-4 py-2 text-sm transition ${
                              pkg.format === "individual"
                                ? "border-[#c4d600]/40 bg-[#c4d600]/15 text-white"
                                : "border-white/10 bg-black/20 text-white/65 hover:border-white/20 hover:text-white"
                            }`}
                          >
                            <input
                              type="radio"
                              name={`${packageBaseId}-format`}
                              checked={pkg.format === "individual"}
                              onChange={() => updatePackage(pkg.clientId, { format: "individual", maxStudents: 1 })}
                              className="sr-only"
                            />
                            <span>Individual</span>
                          </label>
                          <label
                            className={`inline-flex cursor-pointer items-center gap-2 rounded-full border px-4 py-2 text-sm transition ${
                              pkg.format === "group"
                                ? "border-[#c4d600]/40 bg-[#c4d600]/15 text-white"
                                : "border-white/10 bg-black/20 text-white/65 hover:border-white/20 hover:text-white"
                            }`}
                          >
                            <input
                              type="radio"
                              name={`${packageBaseId}-format`}
                              checked={pkg.format === "group"}
                              onChange={() => updatePackage(pkg.clientId, { format: "group", maxStudents: pkg.maxStudents < 2 ? 4 : pkg.maxStudents })}
                              className="sr-only"
                            />
                            <span>Grupal</span>
                          </label>
                        </div>
                      </fieldset>

                      <label
                        className={`inline-flex cursor-pointer items-center gap-3 rounded-full border px-4 py-2 text-sm transition ${
                          pkg.active
                            ? "border-white/15 bg-white/5 text-white"
                            : "border-white/10 bg-black/20 text-white/55 hover:border-white/20 hover:text-white"
                        }`}
                      >
                        <input
                          type="checkbox"
                          checked={pkg.active}
                          onChange={(event) => updatePackage(pkg.clientId, { active: event.target.checked })}
                          aria-describedby={activeHelpId}
                          className="sr-only"
                        />
                        <span className="font-medium">Activo para vender</span>
                        <span aria-hidden="true" className="text-xs text-white/60">
                          {pkg.active ? "Si" : "No"}
                        </span>
                      </label>
                      <p id={activeHelpId} className="sr-only">
                        Habilita este paquete para venderlo. Desactivalo para ocultarlo de la venta.
                      </p>
                    </div>

                    <p id={studentHelpId} className="mt-3 text-xs text-white/50">
                      {pkg.format === "individual" ? "Las clases individuales usan un solo alumno." : "Para clases grupales define el maximo de alumnos."}
                    </p>
                    <p className="mt-1 text-xs text-white/45">Usa Tab para llegar al interruptor y Enter o Espacio para cambiarlo.</p>

                    <div className="mt-4 rounded-[1rem] border border-white/10 bg-[#0d110d] p-4">
                      <p className="text-sm font-medium text-white">{getPackageFinalPriceNote(pkg.price)}</p>
                      <p className="mt-1 text-xs text-white/55">Ese valor es el que defines tu como entrenador para vender tus clases.</p>
                    </div>
                  </fieldset>
                );
              })}
            </div>

            {commercialError ? <p className="mt-4 text-sm text-red-200">{commercialError}</p> : null}
            {commercialDirty && !commercialError ? <p className="mt-4 text-sm text-[#c4d600]">Guardando cambios comerciales...</p> : null}
          </article>

          <article className="rounded-[1.75rem] border border-white/10 bg-[#0f140f]/80 p-6">
            <p className="text-xs uppercase tracking-[0.2em] text-[#c4d600]">Cobros</p>
            <h3 className="mt-2 text-xl font-semibold">Mercado Pago</h3>
            <p className="mt-2 text-sm text-white/65">
              Por ahora guardamos el alias o mail donde quieres cobrar. La conexion real la hacemos despues.
            </p>

            <div className="mt-5 grid gap-4 lg:grid-cols-[1fr_auto]">
              <label className="block text-sm text-white/70">
                Alias o mail de Mercado Pago
                <input
                  value={mercadoPagoHandle}
                  onChange={(event) => setMercadoPagoHandle(event.target.value)}
                  placeholder="tu-alias o tu@mail.com"
                  className="mt-2 h-11 w-full rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                />
              </label>
              <div className="flex items-end">
                <span className="rounded-full border border-white/10 bg-black/20 px-4 py-3 text-sm text-white/65">
                  {mercadoPagoHandle.trim() ? "Listo para conectar" : "Pendiente"}
                </span>
              </div>
            </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]">Alumnos</p>
                <h3 className="mt-2 text-2xl font-semibold">Tus alumnos</h3>
                <p className="mt-2 text-sm text-white/65">
                  Aqui ves tu base de alumnos y abres la carga de clases solo cuando la necesitas.
                </p>
              </div>
              <div className="flex flex-wrap gap-3">
                <Button type="button" className="h-11 rounded-xl px-5 text-sm font-medium" onClick={openStudentsComposer}>
                  Ir a alumnos
                </Button>
              </div>
            </div>

            {studentsLoading ? (
              <p className="mt-5 text-sm text-white/55">Cargando alumnos y agenda...</p>
            ) : studentsError ? (
              <p className="mt-5 rounded-xl border border-red-500/40 bg-red-500/10 px-4 py-3 text-sm text-red-200">{studentsError}</p>
            ) : (
              <details className="mt-5 rounded-[1.35rem] border border-white/10 bg-black/20 p-6" open>
                <summary className="cursor-pointer list-none text-sm font-medium text-white [&::-webkit-details-marker]:hidden">
                  Carga de clase y alta de alumno
                </summary>
                <div className="mt-5 grid gap-5 xl:grid-cols-2">
                  <div className="rounded-[1rem] border border-white/10 bg-[#0d110d] p-5">
                    <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 agregas una vez y despues lo reutilizas en tus clases.</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">
                      <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">
                        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>
                      <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 CoachStudentCreateDraft["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>
                    </div>

                    {studentCreateError ? (
                      <p 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>

                  <div className="rounded-[1rem] border border-white/10 bg-[#0d110d] p-5">
                    <div>
                      <p className="text-sm font-medium text-white">Carga de clase</p>
                      <p className="mt-1 text-xs text-white/55">Elige el alumno, la sede y el horario que quieres ocupar.</p>
                    </div>

                    <div className="mt-4 grid gap-4 sm:grid-cols-2">
                      <label className="block text-sm text-white/70 sm:col-span-2">
                        Alumno existente
                        <select
                          value={studentBookingDraft.playerId}
                          onChange={(event) => setStudentBookingDraft((current) => ({ ...current, playerId: 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="">Selecciona un alumno</option>
                          {studentsPanel?.players.map((player) => (
                            <option key={player.id} value={player.id}>
                              {player.name}
                              {player.clubNames.length > 0 ? ` · ${player.clubNames.join(", ")}` : ""}
                            </option>
                          ))}
                        </select>
                      </label>

                      <label className="block text-sm text-white/70 sm:col-span-2">
                        Sede
                        <select
                          value={studentBookingDraft.venueId}
                          onChange={(event) => setStudentBookingDraft((current) => ({ ...current, venueId: 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="">Selecciona una sede</option>
                          {studentsPanel?.venues.map((venue) => (
                            <option key={venue.id} value={venue.id}>
                              {venue.clubName} · {venue.name}
                            </option>
                          ))}
                        </select>
                      </label>

                      <label className="block text-sm text-white/70">
                        Fecha
                        <input
                          type="date"
                          value={studentBookingDraft.date}
                          onChange={(event) => setStudentBookingDraft((current) => ({ ...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">
                        Hora
                        <input
                          type="time"
                          step={1800}
                          value={studentBookingDraft.startTime}
                          onChange={(event) => setStudentBookingDraft((current) => ({ ...current, startTime: 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={studentBookingDraft.durationMinutes}
                          onChange={(event) =>
                            setStudentBookingDraft((current) => ({ ...current, durationMinutes: Number(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"
                        >
                          {[30, 60, 90, 120].map((value) => (
                            <option key={value} value={value}>
                              {formatDuration(value)}
                            </option>
                          ))}
                        </select>
                      </label>

                      <label className="block text-sm text-white/70">
                        Repetir semanalmente
                        <select
                          value={studentBookingDraft.repeatWeeklyCount}
                          onChange={(event) =>
                            setStudentBookingDraft((current) => ({ ...current, repeatWeeklyCount: Number(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={1}>Solo esta clase</option>
                          {[4, 8, 12].map((value) => (
                            <option key={value} value={value}>
                              {value} semanas
                            </option>
                          ))}
                        </select>
                      </label>

                      <label className="block text-sm text-white/70 sm:col-span-2">
                        Nota interna
                        <textarea
                          value={studentBookingDraft.note}
                          onChange={(event) => setStudentBookingDraft((current) => ({ ...current, note: event.target.value }))}
                          rows={4}
                          placeholder="Objetivo de la clase, observaciones, seguimiento..."
                          className="mt-2 w-full rounded-xl border border-white/15 bg-black/30 px-3 py-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={savingStudentBooking || !canSubmitStudentBooking}
                        onClick={() => void handleCreateStudentBooking()}
                      >
                        {savingStudentBooking ? "Guardando..." : "Confirmar clase"}
                      </Button>
                    </div>
                  </div>
                </div>

                {studentsPanel?.summary.note ? (
                  <div className="mt-4 rounded-[1rem] border border-white/10 bg-[#0d110d] p-4 text-sm text-white/65">
                    {studentsPanel.summary.note}
                  </div>
                ) : null}
                {studentsPanel && studentsPanel.players.length === 0 ? (
                  <div className="mt-4 rounded-[1rem] border border-white/10 bg-[#0d110d] p-4 text-sm text-white/65">
                    Todavia no hay alumnos existentes en Ballbox. Primero cargalos desde Players.
                  </div>
                ) : null}
                {studentBookingError ? <p className="mt-4 text-sm text-red-200">{studentBookingError}</p> : null}
              </details>
            )}

            {trackedStudents.length === 0 ? (
              <div className="mt-5 rounded-[1.25rem] border border-dashed border-white/10 bg-black/10 p-5 text-sm text-white/55">
                Aun no tienes alumnos vinculados. Cuando cargues la primera clase tomada, apareceran aqui.
              </div>
            ) : (
              <div className="mt-5 overflow-x-auto rounded-[1.25rem] border border-white/10 bg-black/20">
                <table className="min-w-[1100px] text-left text-sm text-white/75">
                  <thead className="border-b border-white/10 bg-black/20 text-xs uppercase tracking-[0.16em] text-white/45">
                    <tr>
                      <th className="px-4 py-3 font-medium">Alumno</th>
                      <th className="px-4 py-3 font-medium">Categoria</th>
                      <th className="px-4 py-3 font-medium">Contacto</th>
                      <th className="px-4 py-3 font-medium">Sedes</th>
                      <th className="px-4 py-3 font-medium">Proxima clase</th>
                      <th className="px-4 py-3 font-medium">Ultima clase</th>
                      <th className="px-4 py-3 font-medium">Clases</th>
                      <th className="px-4 py-3 font-medium">Acciones</th>
                    </tr>
                  </thead>
                  <tbody>
                    {trackedStudents.map((student) => {
                      const draft = studentContactDrafts[student.player.id] ?? createStudentContactDraft(student.player);
                      const whatsappHref = buildWhatsAppHref(student.player.whatsappPhone);
                      const telegramHref = buildTelegramHref(student.player.telegramHandle);
                      const contactBaseId = `student-contact-${student.player.id}`;
                      const whatsappInputId = `${contactBaseId}-whatsapp`;
                      const telegramInputId = `${contactBaseId}-telegram`;
                      const contactHelpId = `${contactBaseId}-help`;
                      const contactStatusId = `${contactBaseId}-status`;
                      const contactErrorId = `${contactBaseId}-error`;
                      const contactState = studentContactSaveStates[student.player.id] ?? "idle";
                      const contactError = studentContactErrors[student.player.id] ?? null;
                      const describedByIds = [contactHelpId, contactStatusId, contactError ? contactErrorId : null]
                        .filter(Boolean)
                        .join(" ");

                      return (
                        <tr key={student.player.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">{student.player.name}</p>
                            <p className="mt-1 text-xs text-white/50">
                              {getGenderLabel(student.player.gender)} · {getStudentAgeLabel(student.player.birthYear)}
                            </p>
                          </td>
                          <td className="px-4 py-4 text-white/70">{student.player.coachCategory ?? "Sin categoria"}</td>
                          <td className="px-4 py-4">
                            <fieldset className="min-w-[14rem] rounded-[1rem] border border-white/10 bg-black/20 p-3">
                              <legend className="px-1 text-xs font-medium uppercase tracking-[0.16em] text-white/45">Contacto</legend>
                              <div className="grid gap-3">
                                <div className="grid gap-1.5">
                                  <label htmlFor={whatsappInputId} className="text-xs text-white/60">
                                    WhatsApp
                                  </label>
                                  <input
                                    id={whatsappInputId}
                                    value={draft.whatsappPhone}
                                    onChange={(event) => updateStudentContactDraft(student.player.id, { whatsappPhone: event.target.value })}
                                    placeholder="WhatsApp"
                                    aria-describedby={describedByIds}
                                    className="h-10 rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                                  />
                                </div>
                                <div className="grid gap-1.5">
                                  <label htmlFor={telegramInputId} className="text-xs text-white/60">
                                    Telegram
                                  </label>
                                  <input
                                    id={telegramInputId}
                                    value={draft.telegramHandle}
                                    onChange={(event) => updateStudentContactDraft(student.player.id, { telegramHandle: event.target.value })}
                                    placeholder="@telegram"
                                    aria-describedby={describedByIds}
                                    className="h-10 rounded-xl border border-white/15 bg-black/30 px-3 text-sm text-white"
                                  />
                                </div>
                              </div>
                              <p id={contactHelpId} className="mt-3 text-xs text-white/45">
                                Guarda los datos antes de abrir accesos rapidos a WhatsApp o Telegram.
                              </p>
                              <p id={contactStatusId} role="status" aria-live="polite" className="mt-2 text-xs text-white/55">
                                {getAutoSaveLabel(contactState)}
                              </p>
                              {contactError ? (
                                <p id={contactErrorId} className="mt-2 text-xs text-red-200">
                                  {contactError}
                                </p>
                              ) : null}
                            </fieldset>
                          </td>
                          <td className="px-4 py-4 text-white/70">{student.venueNames.join(" · ") || "Sin sedes"}</td>
                          <td className="px-4 py-4 text-white/70">
                            {student.nextLessonAt ? formatDateTime(student.nextLessonAt) : "Sin clase futura"}
                          </td>
                          <td className="px-4 py-4 text-white/70">
                            {student.lastLessonAt ? formatDateTime(student.lastLessonAt) : "Sin historial"}
                          </td>
                          <td className="px-4 py-4 text-white/70">{student.lessonCount}</td>
                          <td className="px-4 py-4">
                            <div className="flex min-w-[12rem] flex-wrap gap-2">
                              <Button
                                type="button"
                                className="h-10 rounded-xl px-4 text-sm font-medium"
                                disabled={savingStudentContactId === student.player.id}
                                aria-label={`Guardar contacto de ${student.player.name}`}
                                onClick={() => void handleSaveStudentContact(student.player.id)}
                              >
                                {savingStudentContactId === student.player.id ? "Guardando..." : "Guardar"}
                              </Button>
                              {whatsappHref ? (
                                <a
                                  href={whatsappHref}
                                  target="_blank"
                                  rel="noreferrer"
                                  aria-label={`Abrir WhatsApp de ${student.player.name} en una nueva pestaña`}
                                  className="rounded-full border border-white/10 px-3 py-2 text-xs text-white/75 transition hover:border-white/20 hover:text-white"
                                >
                                  WhatsApp
                                </a>
                              ) : null}
                              {telegramHref ? (
                                <a
                                  href={telegramHref}
                                  target="_blank"
                                  rel="noreferrer"
                                  aria-label={`Abrir Telegram de ${student.player.name} en una nueva pestaña`}
                                  className="rounded-full border border-white/10 px-3 py-2 text-xs text-white/75 transition hover:border-white/20 hover:text-white"
                                >
                                  Telegram
                                </a>
                              ) : null}
                            </div>
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            )}

          </article>
        </>
      )}

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