import { initI18n, onLangChange, t, tDyn, getLang } from "./i18n";
import { initSidebar } from "./sidebar";

interface Deadline {
  id: string;
  project_id: string;
  title: string;
  due_date: string;
  status: string;
  project_reference: string;
  project_title: string;
}

let allDeadlines: Deadline[] = [];
let viewYear = 0;
let viewMonth = 0; // 0-11

function esc(s: string): string {
  const d = document.createElement("div");
  d.textContent = s;
  return d.innerHTML;
}

function fmtMonth(year: number, month: number): string {
  return `${tDyn(`cal.month.${month}`)} ${year}`;
}

function urgencyClass(due: string, status: string): string {
  if (status === "completed") return "frist-urgency-done";
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const d = new Date(due.slice(0, 10) + "T00:00:00");
  const diffDays = Math.floor((d.getTime() - today.getTime()) / 86400000);
  if (diffDays < 0) return "frist-urgency-overdue";
  if (diffDays <= 7) return "frist-urgency-soon";
  return "frist-urgency-later";
}

async function loadDeadlines() {
  try {
    const resp = await fetch("/api/deadlines?status=all");
    if (resp.ok) allDeadlines = await resp.json();
  } catch {
    /* non-fatal */
  }
}

function deadlinesForDate(iso: string): Deadline[] {
  return allDeadlines.filter((f) => f.due_date.slice(0, 10) === iso);
}

function isoDate(year: number, month: number, day: number): string {
  const m = String(month + 1).padStart(2, "0");
  const d = String(day).padStart(2, "0");
  return `${year}-${m}-${d}`;
}

function render() {
  document.getElementById("cal-month-label")!.textContent = fmtMonth(viewYear, viewMonth);

  const firstDay = new Date(viewYear, viewMonth, 1);
  const jsWeekday = firstDay.getDay();
  const offset = (jsWeekday + 6) % 7;
  const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
  const today = new Date();
  const todayISO = isoDate(today.getFullYear(), today.getMonth(), today.getDate());

  const cells: string[] = [];
  for (let i = 0; i < offset; i++) {
    cells.push(`<div class="frist-cal-cell frist-cal-cell-empty"></div>`);
  }
  for (let day = 1; day <= daysInMonth; day++) {
    const iso = isoDate(viewYear, viewMonth, day);
    const items = deadlinesForDate(iso);
    const isToday = iso === todayISO;

    const dots = items
      .slice(0, 4)
      .map((f) => `<span class="frist-cal-dot ${urgencyClass(f.due_date, f.status)}"></span>`)
      .join("");
    const more = items.length > 4 ? `<span class="frist-cal-more">+${items.length - 4}</span>` : "";

    cells.push(
      `<div class="frist-cal-cell${isToday ? " frist-cal-today" : ""}${items.length > 0 ? " frist-cal-cell-has" : ""}" data-iso="${iso}">
        <span class="frist-cal-day">${day}</span>
        <div class="frist-cal-dots">${dots}${more}</div>
      </div>`,
    );
  }

  const grid = document.getElementById("deadline-cal-grid")!;
  grid.innerHTML = cells.join("");

  grid.querySelectorAll<HTMLElement>(".frist-cal-cell-has").forEach((cell) => {
    cell.addEventListener("click", () => openPopup(cell.dataset.iso!));
  });

  const monthStart = isoDate(viewYear, viewMonth, 1);
  const monthEnd = isoDate(viewYear, viewMonth, daysInMonth);
  const hasInMonth = allDeadlines.some((f) => {
    const iso = f.due_date.slice(0, 10);
    return iso >= monthStart && iso <= monthEnd;
  });
  const empty = document.getElementById("deadline-cal-empty")!;
  empty.style.display = hasInMonth ? "none" : "";
}

function openPopup(iso: string) {
  const items = deadlinesForDate(iso);
  if (items.length === 0) return;
  const popup = document.getElementById("cal-popup")!;
  const dateEl = document.getElementById("cal-popup-date")!;
  const list = document.getElementById("cal-popup-list")!;

  const d = new Date(iso + "T00:00:00");
  dateEl.textContent = d.toLocaleDateString(getLang() === "de" ? "de-DE" : "en-GB", {
    weekday: "long",
    year: "numeric",
    month: "long",
    day: "numeric",
  });

  list.innerHTML = items
    .map((f) => {
      const cls = urgencyClass(f.due_date, f.status);
      return `<li class="frist-cal-popup-item">
        <span class="frist-cal-dot ${cls}"></span>
        <a href="/deadlines/${esc(f.id)}" class="frist-cal-popup-title">${esc(f.title)}</a>
        <a href="/projects/${esc(f.project_id)}" class="frist-cal-popup-project">${esc(f.project_reference)}</a>
      </li>`;
    })
    .join("");
  popup.style.display = "flex";
}

function initPopup() {
  const popup = document.getElementById("cal-popup")!;
  const close = document.getElementById("cal-popup-close")!;
  close.addEventListener("click", () => (popup.style.display = "none"));
  popup.addEventListener("click", (e) => {
    if (e.target === e.currentTarget) popup.style.display = "none";
  });
}

function initNav() {
  document.getElementById("cal-prev")!.addEventListener("click", () => {
    viewMonth -= 1;
    if (viewMonth < 0) {
      viewMonth = 11;
      viewYear -= 1;
    }
    render();
  });
  document.getElementById("cal-next")!.addEventListener("click", () => {
    viewMonth += 1;
    if (viewMonth > 11) {
      viewMonth = 0;
      viewYear += 1;
    }
    render();
  });
  document.getElementById("cal-today")!.addEventListener("click", () => {
    const now = new Date();
    viewYear = now.getFullYear();
    viewMonth = now.getMonth();
    render();
  });
}

document.addEventListener("DOMContentLoaded", async () => {
  initI18n();
  initSidebar();
  const now = new Date();
  viewYear = now.getFullYear();
  viewMonth = now.getMonth();
  initNav();
  initPopup();
  onLangChange(render);
  await loadDeadlines();
  render();
});
