"use client";

import { useState } from "react";
import { VacationStatus } from "@capakraken/shared";
import { trpc } from "~/lib/trpc/client.js";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
import { VACATION_CALENDAR_COLORS } from "~/lib/status-styles.js";

const MONTH_NAMES = [
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
];

function isoDate(d: Date | string): string {
  const date = typeof d === "string" ? new Date(d) : d;
  return date.toISOString().slice(0, 10);
}

export function TeamCalendar() {
  const now = new Date();
  const [month, setMonth] = useState(now.getMonth());
  const [year, setYear] = useState(now.getFullYear());
  const [chapter, setChapter] = useState<string>("");

  const firstDay = new Date(Date.UTC(year, month, 1));
  const daysInMonth = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();

  const { data: resources } = trpc.resource.directory.useQuery(
    { isActive: true, limit: 500, ...(chapter ? { chapter } : {}) },
    { staleTime: 60_000 },
  );

  const { data: vacations } = trpc.vacation.list.useQuery(
    {
      startDate: firstDay,
      endDate: new Date(Date.UTC(year, month + 1, 0)),
      limit: 500,
    },
    { staleTime: 15_000 },
  );

  // Fetch all chapters independently so the dropdown isn't affected by chapter filter
  const { data: allChapters } = trpc.resource.chapters.useQuery(undefined, { staleTime: 60_000 });
  const chapters = allChapters ?? [];

  const resourceList: { id: string; displayName: string }[] = resources?.resources ?? [];
  const vacationList = (vacations ?? []).filter(
    (v) => v.status !== VacationStatus.CANCELLED && v.status !== VacationStatus.REJECTED,
  );

  // Build map: resourceId → date → vacation
  const vacationMap = new Map<string, Map<string, { type: string; status: string }>>();
  for (const v of vacationList) {
    const start = isoDate(v.startDate);
    const end = isoDate(v.endDate);
    let cur = start;
    while (cur <= end) {
      const resourceVacs = vacationMap.get(v.resourceId) ?? new Map();
      if (!resourceVacs.has(cur)) {
        resourceVacs.set(cur, { type: v.type, status: v.status });
      }
      vacationMap.set(v.resourceId, resourceVacs);
      // next day
      const d = new Date(cur);
      d.setUTCDate(d.getUTCDate() + 1);
      cur = d.toISOString().slice(0, 10);
    }
  }

  const days = Array.from({ length: daysInMonth }, (_, i) => i + 1);
  const today = now.toISOString().slice(0, 10);

  function prevMonth() {
    if (month === 0) { setMonth(11); setYear(y => y - 1); }
    else setMonth(m => m - 1);
  }

  function nextMonth() {
    if (month === 11) { setMonth(0); setYear(y => y + 1); }
    else setMonth(m => m + 1);
  }

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
      {/* Toolbar */}
      <div className="flex items-center gap-3 px-4 py-3 border-b border-gray-100 dark:border-gray-700 flex-wrap">
        <button type="button" onClick={prevMonth} className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded text-gray-500 dark:text-gray-400">
          ‹
        </button>
        <span className="text-sm font-semibold text-gray-900 dark:text-gray-100 min-w-[120px] text-center">
          {MONTH_NAMES[month]} {year}
        </span>
        <button type="button" onClick={nextMonth} className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded text-gray-500 dark:text-gray-400">
          ›
        </button>

        <div className="flex-1" />

        <select
          value={chapter}
          onChange={(e) => setChapter(e.target.value)}
          className="text-sm border border-gray-200 dark:border-gray-600 rounded-lg px-2 py-1 focus:outline-none focus:ring-2 focus:ring-brand-500 dark:bg-gray-900 dark:text-gray-100"
        >
          <option value="">All chapters</option>
          {chapters.map((c) => (
            <option key={c} value={c}>{c}</option>
          ))}
        </select>
      </div>

      {/* Grid */}
      <div className="overflow-x-auto">
        <table className="min-w-full text-xs">
          <thead>
            <tr className="bg-gray-50 dark:bg-gray-900 border-b border-gray-100 dark:border-gray-700">
              <th className="sticky left-0 z-10 bg-gray-50 dark:bg-gray-900 px-3 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-400 w-36 border-r border-gray-100 dark:border-gray-700">
                <span className="inline-flex items-center gap-0.5">Resource<InfoTooltip content="Matrix view: each row is a resource, each column is a calendar day. Colored cells indicate vacation days (color = type, faded = pending)." width="w-72" /></span>
              </th>
              {days.map((d) => {
                const dateStr = `${year}-${String(month + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
                const dow = new Date(dateStr).getUTCDay(); // 0=Sun, 6=Sat
                const isWeekend = dow === 0 || dow === 6;
                const isToday = dateStr === today;
                return (
                  <th
                    key={d}
                    className={`px-1 py-2 text-center font-medium w-7 ${isWeekend ? "text-gray-300 dark:text-gray-600 bg-gray-50 dark:bg-gray-900" : isToday ? "text-brand-700 bg-brand-50" : "text-gray-500 dark:text-gray-400"}`}
                  >
                    {d}
                  </th>
                );
              })}
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-50 dark:divide-gray-700">
            {resourceList.map((r) => {
              const rMap = vacationMap.get(r.id);
              return (
                <tr key={r.id} className="hover:bg-gray-50 dark:hover:bg-gray-700/50">
                  <td className="sticky left-0 z-10 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/50 px-3 py-1.5 border-r border-gray-100 dark:border-gray-700 font-medium text-gray-800 dark:text-gray-100 truncate max-w-[9rem]">
                    {r.displayName}
                  </td>
                  {days.map((d) => {
                    const dateStr = `${year}-${String(month + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
                    const vac = rMap?.get(dateStr);
                    const dow = new Date(dateStr).getUTCDay();
                    const isWeekend = dow === 0 || dow === 6;
                    const isToday = dateStr === today;

                    let cellClass = "w-7 h-7";
                    if (vac) {
                      const color = VACATION_CALENDAR_COLORS[vac.type] ?? "bg-gray-400";
                      const opacity = vac.status === "PENDING" ? "opacity-50" : "";
                      cellClass += ` ${color} ${opacity}`;
                    } else if (isWeekend) {
                      cellClass += " bg-gray-50 dark:bg-gray-900";
                    } else if (isToday) {
                      cellClass += " bg-brand-50";
                    }

                    return (
                      <td key={d} className="px-0.5 py-0.5">
                        <div
                          className={cellClass + " rounded-sm"}
                          title={vac ? `${r.displayName}: ${vac.type} (${vac.status})` : undefined}
                        />
                      </td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </table>

        {resourceList.length === 0 && (
          <div className="p-8 text-center text-sm text-gray-400">No resources found.</div>
        )}
      </div>

      {/* Legend */}
      <div className="px-4 py-2 border-t border-gray-100 dark:border-gray-700 flex gap-4 flex-wrap">
        {Object.entries(VACATION_CALENDAR_COLORS).map(([type, color]) => (
          <span key={type} className="flex items-center gap-1.5 text-xs text-gray-500 dark:text-gray-400">
            <span className={`${color} w-3 h-3 rounded-sm inline-block`} />
            {type.replace("_", " ")}
          </span>
        ))}
        <span className="flex items-center gap-1.5 text-xs text-gray-400 dark:text-gray-500">
          <span className="opacity-50 bg-brand-500 w-3 h-3 rounded-sm inline-block" />
          Pending
        </span>
      </div>
    </div>
  );
}
