import { useMemo, useState } from "react";
import { Link } from "react-router-dom";
import type { CalendarEvent } from "../lib/api";
import {
  calendarEventShortLabel,
  categoryTip,
  impactClass,
  impactLabel,
} from "../lib/calendarInfo";
import { Explain, Tag } from "./ui";

const WEEKDAYS = ["日", "一", "二", "三", "四", "五", "六"] as const;

function sortDayEvents(list: CalendarEvent[]) {
  const rank: Record<string, number> = { high: 0, medium: 1, low: 2 };
  return [...list].sort((a, b) => {
    const ra = rank[a.impact || ""] ?? 2;
    const rb = rank[b.impact || ""] ?? 2;
    if (ra !== rb) return ra - rb;
    return String(a.titleZh || a.title).localeCompare(String(b.titleZh || b.title));
  });
}

function chipClass(ev: CalendarEvent) {
  return `cal-ev ${ev.impact || "low"} cat-${ev.category || "macro"}`;
}

function dotClass(ev: CalendarEvent) {
  return `cal-dot ${ev.impact || "low"} cat-${ev.category || "macro"}`;
}

export default function CalendarWeekPreview({ events }: { events: CalendarEvent[] }) {
  const today = new Date().toISOString().slice(0, 10);
  const weekDays = useMemo(() => {
    const out: { iso: string; day: number; dow: string }[] = [];
    const base = new Date(`${today}T12:00:00`);
    for (let i = 0; i < 7; i++) {
      const d = new Date(base.getTime() + i * 86400000);
      const iso = d.toISOString().slice(0, 10);
      out.push({ iso, day: d.getDate(), dow: WEEKDAYS[d.getDay()] });
    }
    return out;
  }, [today]);

  const byDate = useMemo(() => {
    const map = new Map<string, CalendarEvent[]>();
    for (const ev of events) {
      const list = map.get(ev.date) || [];
      list.push(ev);
      map.set(ev.date, list);
    }
    for (const [k, list] of map) map.set(k, sortDayEvents(list));
    return map;
  }, [events]);

  const [selected, setSelected] = useState(today);
  const selectedEvents = byDate.get(selected) || [];

  if (!weekDays.some((d) => (byDate.get(d.iso) || []).length)) {
    return <p className="muted small">未來 7 天沒有追蹤中的事件。</p>;
  }

  return (
    <div className="cal-week-preview">
      <div className="cal-week-grid">
        {weekDays.map((d) => {
          const dayEvents = byDate.get(d.iso) || [];
          const cls = [
            "cal-week-cell",
            d.iso === today ? "today" : "",
            selected === d.iso ? "selected" : "",
            dayEvents.length ? "has-events" : "",
          ]
            .filter(Boolean)
            .join(" ");
          return (
            <button
              key={d.iso}
              type="button"
              className={cls}
              aria-pressed={selected === d.iso}
              onClick={() => setSelected(d.iso)}
            >
              <span className="cal-week-dow">{d.dow}</span>
              <span className="cal-week-day">{d.day}</span>
              {dayEvents.length > 0 && (
                <span className="cal-dots cal-dots-week" aria-hidden>
                  {dayEvents.slice(0, 3).map((ev, i) => (
                    <span key={i} className={dotClass(ev)} />
                  ))}
                </span>
              )}
            </button>
          );
        })}
      </div>

      {selectedEvents.length === 0 ? (
        <p className="muted small cal-week-empty">這天沒有事件。</p>
      ) : (
        <div className="cal-week-events">
          {selectedEvents.map((ev, i) => {
            const ci = categoryTip(ev.category);
            return (
              <div className={`cal-week-ev ${ev.impact || "low"}`} key={i}>
                <div className="cal-week-ev-head">
                  <span className={chipClass(ev)}>{calendarEventShortLabel(ev)}</span>
                  <b>{ev.titleZh || ev.title}</b>
                  {ev.symbol && (
                    <Link to={`/research?sym=${encodeURIComponent(ev.symbol)}`} className="event-symbol">
                      {ev.symbol}
                    </Link>
                  )}
                  <Tag>{ci?.label}</Tag>
                  <span className={"tag " + impactClass(ev.impact)}>{impactLabel(ev.impact)}</span>
                  <Explain tip={ci?.tip} label={`${ci?.label}・這天會公布什麼`} />
                </div>
                <div className="cal-week-ev-note">
                  {ev.note || (ev.impact === "high" ? "高關注事件：數據公布當日宜控槓桿、留意跳空。" : "留意是否偏離市場預期。")}
                  {ev.time ? ` · ${ev.time}` : ""}
                </div>
              </div>
            );
          })}
        </div>
      )}

      <Link to="/market" className="small muted cal-week-link">
        前往市場世界 · 完整事件日曆 →
      </Link>
    </div>
  );
}