"use client";

import { useState } from "react";
import { VacationStatus } from "@capakraken/shared";
import { VACATION_CALENDAR_COLORS } from "~/lib/status-styles.js";
import { buildVacationExplainabilityTooltip, type VacationExplainabilityEntry } from "./vacationExplainability.js";

interface VacationEntry extends VacationExplainabilityEntry {
  id: string;
  startDate: Date | string;
  endDate: Date | string;
  type: string;
  status: string;
  resource?: { displayName: string; eid: string } | null;
}

interface VacationCalendarProps {
  vacations: VacationEntry[];
  year?: number;
  initialMonth?: number; // 0-indexed
}

const STATUS_OPACITY: Record<string, string> = {
  APPROVED: "opacity-100",
  PENDING: "opacity-60",
  REJECTED: "opacity-30",
  CANCELLED: "opacity-20",
};

const DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
const MONTH_NAMES = [
  "January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December",
];

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

function addDays(dateStr: string, n: number): string {
  const d = new Date(dateStr);
  d.setUTCDate(d.getUTCDate() + n);
  return d.toISOString().slice(0, 10);
}

function getDatesInRange(start: Date | string, end: Date | string): Set<string> {
  const dates = new Set<string>();
  let cur = isoDate(start);
  const last = isoDate(end);
  while (cur <= last) {
    dates.add(cur);
    cur = addDays(cur, 1);
  }
  return dates;
}

export function VacationCalendar({ vacations, year = new Date().getFullYear(), initialMonth = new Date().getMonth() }: VacationCalendarProps) {
  const [month, setMonth] = useState(initialMonth);
  const [currentYear, setCurrentYear] = useState(year);

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

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

  // Build a set of date → vacation entries for fast lookup
  const dateMap = new Map<string, VacationEntry[]>();
  for (const v of vacations) {
    if ([VacationStatus.CANCELLED, VacationStatus.REJECTED].includes(v.status as VacationStatus)) continue;
    const dates = getDatesInRange(v.startDate, v.endDate);
    for (const d of dates) {
      const existing = dateMap.get(d) ?? [];
      existing.push(v);
      dateMap.set(d, existing);
    }
  }

  // Build calendar grid
  const firstDay = new Date(Date.UTC(currentYear, month, 1));
  const daysInMonth = new Date(Date.UTC(currentYear, month + 1, 0)).getUTCDate();
  // ISO weekday: Mon=1, Sun=7 → index 0-6
  const startOffset = (firstDay.getUTCDay() + 6) % 7; // Mon first

  const cells: (number | null)[] = [
    ...Array<null>(startOffset).fill(null),
    ...Array.from({ length: daysInMonth }, (_, i) => i + 1),
  ];
  // Pad to complete last row
  while (cells.length % 7 !== 0) cells.push(null);

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
      {/* Header */}
      <div className="flex items-center justify-between px-4 py-3 border-b border-gray-100 dark:border-gray-700">
        <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>
        <h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">
          {MONTH_NAMES[month]} {currentYear}
        </h3>
        <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>

      {/* Day names */}
      <div className="grid grid-cols-7 border-b border-gray-100 dark:border-gray-700">
        {DAYS.map((d) => (
          <div key={d} className="px-2 py-1.5 text-center text-xs font-medium text-gray-400 dark:text-gray-500">
            {d}
          </div>
        ))}
      </div>

      {/* Days grid */}
      <div className="grid grid-cols-7">
        {cells.map((day, idx) => {
          if (!day) {
            return <div key={`empty-${idx}`} className="p-1 min-h-[60px] border-b border-r border-gray-50 dark:border-gray-700 bg-gray-50/30 dark:bg-gray-900/30" />;
          }

          const dateStr = `${currentYear}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
          const dayVacations = dateMap.get(dateStr) ?? [];
          const today = new Date().toISOString().slice(0, 10);
          const isToday = dateStr === today;

          return (
            <div
              key={dateStr}
              className={`p-1 min-h-[60px] border-b border-r border-gray-50 dark:border-gray-700 ${isToday ? "bg-brand-50" : ""}`}
            >
              <span className={`text-xs font-medium block mb-1 ${isToday ? "text-brand-700" : "text-gray-500 dark:text-gray-400"}`}>
                {day}
              </span>
              <div className="space-y-0.5">
                {dayVacations.slice(0, 3).map((v) => {
                  const colorClass = VACATION_CALENDAR_COLORS[v.type] ?? "bg-gray-400";
                  const opacityClass = STATUS_OPACITY[v.status] ?? "opacity-100";
                  const name = v.resource?.displayName ?? "—";
                  const explainabilityTitle = buildVacationExplainabilityTooltip(v);
                  return (
                    <div
                      key={v.id + dateStr}
                      className={`${colorClass} ${opacityClass} text-white text-xs px-1 rounded truncate`}
                      title={[`${name} — ${v.type} (${v.status})`, explainabilityTitle].filter(Boolean).join("\n")}
                    >
                      {name.split(" ")[0]}
                    </div>
                  );
                })}
                {dayVacations.length > 3 && (
                  <div className="text-xs text-gray-400 dark:text-gray-500 pl-1">+{dayVacations.length - 3}</div>
                )}
              </div>
            </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>
        ))}
      </div>
    </div>
  );
}
