"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  ChevronLeft,
  ChevronRight,
  CalendarDays,
  Clock,
  Loader2,
} from "lucide-react";
import type { CalendarMatch } from "@/lib/services/calendar";
import {
  addMonths,
  buildMonthGrid,
  endOfMonth,
  formatMonthYear,
  matchDisplayDate,
  parseDateKey,
  sameDay,
  startOfMonth,
  toDateKey,
} from "@/lib/calendar/utils";
import { apiFetch } from "@/lib/api/client";
import { cn } from "@/lib/utils";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";

const WEEKDAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];

function matchWhen(m: CalendarMatch) {
  return m.scheduled_at ?? m.proposed_scheduled_at;
}

function statusVariant(status: string) {
  if (status === "completed" || status === "played") return "default" as const;
  if (status === "scheduled" || status === "confirmed") return "secondary" as const;
  return "outline" as const;
}

export function MatchCalendar({
  apiPath,
  title = "Match calendar",
  description = "Plan around fixtures — days with matches glow on the grid.",
}: {
  apiPath: "/api/manager/calendar" | "/api/master/calendar";
  title?: string;
  description?: string;
}) {
  const [month, setMonth] = useState(() => startOfMonth(new Date()));
  const [selected, setSelected] = useState(() => toDateKey(new Date()));
  const [matches, setMatches] = useState<CalendarMatch[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const from = startOfMonth(month).toISOString();
      const to = endOfMonth(month).toISOString();
      const data = await apiFetch<CalendarMatch[]>(
        `${apiPath}?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`
      );
      setMatches(data);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed to load matches");
    } finally {
      setLoading(false);
    }
  }, [apiPath, month]);

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

  const byDate = useMemo(() => {
    const map = new Map<string, CalendarMatch[]>();
    for (const m of matches) {
      const when = matchWhen(m);
      if (!when) continue;
      const key = toDateKey(new Date(when));
      const list = map.get(key) ?? [];
      list.push(m);
      map.set(key, list);
    }
    return map;
  }, [matches]);

  const unscheduled = useMemo(
    () => matches.filter((m) => !matchWhen(m)),
    [matches]
  );

  const grid = useMemo(() => buildMonthGrid(month), [month]);
  const selectedMatches = byDate.get(selected) ?? [];
  const selectedDate = parseDateKey(selected);
  const today = new Date();

  const monthMatchCount = useMemo(() => {
    let n = 0;
    for (const [, list] of byDate) n += list.length;
    return n;
  }, [byDate]);

  return (
    <div className="space-y-6">
      <div>
        <p className="font-display text-[10px] font-bold uppercase tracking-[0.2em] text-neon">
          Schedule
        </p>
        <h1 className="font-display text-3xl font-black uppercase tracking-tight md:text-4xl">
          {title}
        </h1>
        <p className="mt-1 max-w-2xl text-sm text-muted-foreground">{description}</p>
      </div>

      <div className="grid gap-6 lg:grid-cols-[1fr_340px]">
        <div className="retro-card p-4 md:p-6">
          <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
            <div className="flex items-center gap-2">
              <CalendarDays className="h-5 w-5 text-neon" />
              <h2 className="font-display text-xl font-bold uppercase tracking-wide">
                {formatMonthYear(month)}
              </h2>
            </div>
            <div className="flex items-center gap-1">
              <Button
                variant="outline"
                size="icon"
                className="rounded-full border-border"
                onClick={() => setMonth((m) => addMonths(m, -1))}
                aria-label="Previous month"
              >
                <ChevronLeft className="h-4 w-4" />
              </Button>
              <Button
                variant="outline"
                size="sm"
                className="rounded-full"
                onClick={() => {
                  const now = startOfMonth(new Date());
                  setMonth(now);
                  setSelected(toDateKey(new Date()));
                }}
              >
                Today
              </Button>
              <Button
                variant="outline"
                size="icon"
                className="rounded-full border-border"
                onClick={() => setMonth((m) => addMonths(m, 1))}
                aria-label="Next month"
              >
                <ChevronRight className="h-4 w-4" />
              </Button>
            </div>
          </div>

          {loading && (
            <div className="flex items-center justify-center gap-2 py-16 text-muted-foreground">
              <Loader2 className="h-5 w-5 animate-spin text-neon" />
              Loading fixtures…
            </div>
          )}

          {error && !loading && (
            <p className="py-8 text-center text-sm text-red-400">{error}</p>
          )}

          {!loading && !error && (
            <>
              <div className="mb-2 grid grid-cols-7 gap-1">
                {WEEKDAYS.map((d) => (
                  <div
                    key={d}
                    className="py-1 text-center font-display text-[10px] font-bold uppercase tracking-widest text-muted-foreground"
                  >
                    {d}
                  </div>
                ))}
              </div>

              <div className="grid grid-cols-7 gap-1.5">
                {grid.map((day) => {
                  const key = toDateKey(day);
                  const inMonth = day.getMonth() === month.getMonth();
                  const isSelected = key === selected;
                  const isToday = sameDay(day, today);
                  const dayMatches = byDate.get(key) ?? [];
                  const hasMatches = dayMatches.length > 0;

                  return (
                    <button
                      key={key}
                      type="button"
                      onClick={() => setSelected(key)}
                      className={cn(
                        "group relative flex min-h-[52px] flex-col items-center justify-start rounded-xl border px-1 py-2 text-sm transition-all md:min-h-[64px]",
                        inMonth ? "border-border/80 bg-secondary/30" : "border-transparent bg-transparent opacity-35",
                        isSelected && "retro-card-glow border-neon/40 bg-neon/10",
                        !isSelected && hasMatches && "hover:border-neon/30 hover:bg-neon/5",
                        !isSelected && !hasMatches && inMonth && "hover:bg-secondary/50"
                      )}
                    >
                      <span
                        className={cn(
                          "font-display text-base font-bold tabular-nums",
                          isToday && "neon-text",
                          isSelected && !isToday && "text-foreground"
                        )}
                      >
                        {day.getDate()}
                      </span>
                      {hasMatches && (
                        <div className="mt-1 flex flex-wrap justify-center gap-0.5">
                          {dayMatches.slice(0, 3).map((m) => (
                            <span key={m.id} className="neon-dot" />
                          ))}
                          {dayMatches.length > 3 && (
                            <span className="text-[9px] text-neon-muted">
                              +{dayMatches.length - 3}
                            </span>
                          )}
                        </div>
                      )}
                    </button>
                  );
                })}
              </div>

              <p className="mt-4 text-xs text-muted-foreground">
                <span className="neon-text font-semibold">{monthMatchCount}</span>{" "}
                scheduled in {formatMonthYear(month)}
                {unscheduled.length > 0 && (
                  <>
                    {" · "}
                    <span className="text-foreground">{unscheduled.length}</span> awaiting
                    date
                  </>
                )}
              </p>
            </>
          )}
        </div>

        <div className="space-y-4">
          <div className="retro-card retro-card-glow p-4 md:p-5">
            <p className="font-display text-[10px] font-bold uppercase tracking-[0.15em] text-neon">
              {selectedDate.toLocaleDateString(undefined, {
                weekday: "long",
                month: "short",
                day: "numeric",
              })}
            </p>
            <h3 className="font-display mt-1 text-2xl font-black uppercase">
              {selectedMatches.length === 0 ? "No matches" : `${selectedMatches.length} match${selectedMatches.length > 1 ? "es" : ""}`}
            </h3>

            <ul className="mt-4 space-y-3">
              {selectedMatches.length === 0 && (
                <li className="text-sm text-muted-foreground">
                  Pick a glowing day or schedule a fixture from your league.
                </li>
              )}
              {selectedMatches.map((m) => (
                <MatchCard key={m.id} match={m} />
              ))}
            </ul>
          </div>

          {unscheduled.length > 0 && (
            <div className="retro-card p-4">
              <div className="mb-3 flex items-center gap-2">
                <Clock className="h-4 w-4 text-muted-foreground" />
                <h3 className="font-display text-sm font-bold uppercase tracking-wide">
                  Date TBD
                </h3>
              </div>
              <ul className="max-h-64 space-y-2 overflow-y-auto">
                {unscheduled.map((m) => (
                  <MatchCard key={m.id} match={m} compact />
                ))}
              </ul>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function MatchCard({ match, compact }: { match: CalendarMatch; compact?: boolean }) {
  const when = matchWhen(match);
  const href = `/leagues/${match.league_id}/competitions/${match.competition_id}/matches/${match.id}`;

  return (
    <li>
      <Link
        href={href}
        className={cn(
          "block rounded-xl border border-border/80 bg-background/60 p-3 transition-colors hover:border-neon/40 hover:bg-neon/5",
          compact && "p-2.5"
        )}
      >
        <div className="flex flex-wrap items-center gap-2">
          <Badge variant={statusVariant(match.status)} className="text-[10px] uppercase">
            {match.status.replace(/_/g, " ")}
          </Badge>
          {!compact && (
            <span className="text-[10px] text-muted-foreground">{match.league_name}</span>
          )}
        </div>
        <p className={cn("mt-1 font-semibold", compact ? "text-sm" : "text-base")}>
          {match.home_name}{" "}
          <span className="text-muted-foreground font-normal">vs</span> {match.away_name}
        </p>
        <p className="mt-0.5 text-xs text-muted-foreground">{match.competition_name}</p>
        <p className="mt-1 text-xs text-neon-muted">{matchDisplayDate(when)}</p>
      </Link>
    </li>
  );
}
