import { Link } from "react-router";
import {
  addMonths,
  differenceInCalendarDays,
  eachMonthOfInterval,
  format,
  parseISO,
} from "date-fns";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card";
import type { DraftScheduleWindow } from "~/models/sports-season";

export interface GanttSport {
  id: string;
  name: string;
  slug: string;
  iconUrl: string | null;
  windows: DraftScheduleWindow[];
}

interface DraftScheduleGanttProps {
  sports: GanttSport[];
  /** Horizon start (today) as a YYYY-MM-DD string. */
  today: string;
  /** Number of months the timeline spans. */
  months: number;
}

// Bar color by sport-season status, using the theme chart tokens from app.css.
const STATUS_COLORS: Record<DraftScheduleWindow["status"], string> = {
  active: "var(--chart-1)",
  upcoming: "var(--chart-2)",
  completed: "var(--muted-foreground)",
};

const STATUS_LABELS: Record<DraftScheduleWindow["status"], string> = {
  active: "Active",
  upcoming: "Upcoming",
  completed: "Completed",
};

const clampPct = (n: number) => Math.max(0, Math.min(100, n));

export function DraftScheduleGantt({ sports, today, months }: DraftScheduleGanttProps) {
  const start = parseISO(today);
  const end = addMonths(start, months);
  const totalDays = Math.max(differenceInCalendarDays(end, start), 1);

  const pct = (date: Date) => (differenceInCalendarDays(date, start) / totalDays) * 100;

  // Month-boundary gridlines that fall inside the horizon.
  const monthLines = eachMonthOfInterval({ start, end })
    .map((date) => ({ date, left: pct(date) }))
    .filter((m) => m.left >= 0 && m.left <= 100);

  if (sports.length === 0) {
    return (
      <Card>
        <CardHeader>
          <CardTitle>Draft Schedule</CardTitle>
          <CardDescription>Draft windows across the next {months} months</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="text-center py-12 text-muted-foreground">
            <p>No sports found.</p>
            <p className="text-sm mt-2">Create a sport to start scheduling draft windows.</p>
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader>
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            <CardTitle>Draft Schedule</CardTitle>
            <CardDescription>
              Draft windows across the next {months} months (each bar spans a
              sport-season&rsquo;s draft-on &rarr; draft-off window)
            </CardDescription>
          </div>
          <div className="flex flex-wrap gap-3 text-xs text-muted-foreground">
            {(Object.keys(STATUS_COLORS) as DraftScheduleWindow["status"][]).map((status) => (
              <div key={status} className="flex items-center gap-1.5">
                <span
                  className="h-3 w-3 rounded-sm"
                  style={{ backgroundColor: STATUS_COLORS[status] }}
                  aria-hidden="true"
                />
                <span>{STATUS_LABELS[status]}</span>
              </div>
            ))}
          </div>
        </div>
      </CardHeader>
      <CardContent>
        <div className="overflow-x-auto">
          <div className="flex" style={{ minWidth: 160 + months * 80 }}>
            {/* Sport labels column */}
            <div className="w-40 shrink-0">
              <div className="h-8" aria-hidden="true" />
              {sports.map((sport) => (
                <div
                  key={sport.id}
                  className="flex h-11 items-center border-b border-border/50 pr-2"
                >
                  <span className="truncate text-sm font-medium" title={sport.name}>
                    {sport.name}
                  </span>
                </div>
              ))}
            </div>

            {/* Timeline column */}
            <div className="relative flex-1">
              {/* Month gridlines (full height) */}
              {monthLines.map((m) => (
                <div
                  key={`line-${m.date.toISOString()}`}
                  className="pointer-events-none absolute bottom-0 top-0 w-px bg-border/60"
                  style={{ left: `${m.left}%` }}
                  aria-hidden="true"
                />
              ))}
              {/* Today marker (full height) */}
              <div
                className="pointer-events-none absolute bottom-0 top-0 w-0.5 bg-primary/80"
                style={{ left: 0 }}
                aria-hidden="true"
              />

              {/* Month labels header */}
              <div className="relative h-8">
                {monthLines.map((m) => (
                  <span
                    key={`label-${m.date.toISOString()}`}
                    className="absolute top-1 text-xs text-muted-foreground"
                    style={{ left: `calc(${m.left}% + 4px)` }}
                  >
                    {format(m.date, "MMM yyyy")}
                  </span>
                ))}
              </div>

              {/* Rows */}
              {sports.map((sport) => (
                <div
                  key={sport.id}
                  className="relative h-11 border-b border-border/50"
                >
                  {sport.windows.length === 0 ? (
                    <span className="absolute left-2 top-1/2 -translate-y-1/2 text-xs italic text-muted-foreground/70">
                      No draft window
                    </span>
                  ) : (
                    sport.windows.map((w) => {
                      const left = clampPct(pct(parseISO(w.draftOn)));
                      const right = clampPct(pct(parseISO(w.draftOff)));
                      const width = Math.max(right - left, 0.75);
                      return (
                        <Link
                          key={w.id}
                          to={`/admin/sports-seasons/${w.id}`}
                          className="absolute top-1/2 flex h-6 -translate-y-1/2 items-center overflow-hidden rounded px-1.5 text-xs font-medium text-background transition-opacity hover:opacity-80"
                          style={{
                            left: `${left}%`,
                            width: `${width}%`,
                            backgroundColor: STATUS_COLORS[w.status],
                          }}
                          title={`${w.name} (${w.year}) · ${w.draftOn} → ${w.draftOff}`}
                        >
                          <span className="truncate">{w.name}</span>
                        </Link>
                      );
                    })
                  )}
                </div>
              ))}
            </div>
          </div>
        </div>
      </CardContent>
    </Card>
  );
}
