import { useCallback, useEffect, useState } from "react";
import { apiGet, apiPost } from "../../api";
import { PageHead, Empty, Loading } from "../../components/ui";
import { IconCalendar, IconCheck, IconRefresh } from "../../components/icons";
import { useToast } from "../../lib/toast";

interface AiringItem {
  id: string;
  name: string;
  year?: number;
  status: string;
  air_days: string[];
  poster_url: string;
  has_logo: boolean;
  selected_week_air_at: string | null;
  selected_week_episode_label: string | null;
  next_air_at: string | null;
  next_episode_label: string | null;
  season_number: number | null;
  eligible_new_season: boolean;
}
interface Snapshot {
  items: AiringItem[];
  week_start: string;
  week_end: string;
  week_offset: number;
}

const WEEKS = [
  { off: -1, label: "Last week" },
  { off: 0, label: "This week" },
  { off: 1, label: "Next week" },
];

function fmtDate(iso: string | null) {
  if (!iso) return null;
  return new Date(iso).toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" });
}

export default function Airing() {
  const toast = useToast();
  const [snap, setSnap] = useState<Snapshot | null>(null);
  const [loading, setLoading] = useState(true);
  const [weekOffset, setWeekOffset] = useState(0);
  const [eligibleOnly, setEligibleOnly] = useState(false);
  const [busy, setBusy] = useState<Record<string, boolean>>({});
  const [selected, setSelected] = useState<Set<string>>(new Set());

  const load = useCallback(
    (refresh = false) => {
      setLoading(true);
      apiGet<Snapshot>(`/api/airing?week_offset=${weekOffset}&eligible_only=${eligibleOnly}&limit=48&refresh=${refresh}`)
        .then(setSnap)
        .catch((e) => toast(e.message, "err"))
        .finally(() => setLoading(false));
    },
    [weekOffset, eligibleOnly, toast]
  );

  useEffect(() => {
    load();
  }, [load]);

  async function applyOne(item: AiringItem) {
    setBusy((b) => ({ ...b, [item.id]: true }));
    try {
      await apiPost("/api/airing/apply-new-season", {
        item_id: item.id,
        generate_primary: true,
        week_offset: weekOffset,
      });
      toast(`New Season artwork applied to ${item.name}`, "ok");
    } catch (e: any) {
      toast(e.message, "err");
    } finally {
      setBusy((b) => ({ ...b, [item.id]: false }));
    }
  }

  async function applySelected() {
    const ids = [...selected];
    if (!ids.length) return;
    try {
      const res = await apiPost("/api/airing/apply-new-season/bulk", { item_ids: ids });
      toast(`Applied to ${res.applied_count} series`, "ok");
      setSelected(new Set());
    } catch (e: any) {
      toast(e.message, "err");
    }
  }

  function toggle(id: string) {
    setSelected((s) => {
      const n = new Set(s);
      n.has(id) ? n.delete(id) : n.add(id);
      return n;
    });
  }

  return (
    <>
      <PageHead title="Airing & New Seasons" icon={<IconCalendar />} />

      <div className="row between wrap" style={{ marginBottom: 18, gap: 12 }}>
        <div className="row gap-sm wrap">
          <div className="seg">
            {WEEKS.map((w) => (
              <button key={w.off} className={`seg-btn ${weekOffset === w.off ? "active" : ""}`} onClick={() => setWeekOffset(w.off)}>
                {w.label}
              </button>
            ))}
          </div>
          <button className={`chip ${eligibleOnly ? "active" : ""}`} onClick={() => setEligibleOnly((v) => !v)}>
            Eligible only
          </button>
        </div>
        <div className="row gap-sm">
          {selected.size > 0 && (
            <button className="btn btn-primary" onClick={applySelected}>
              <IconCheck /> Apply {selected.size} selected
            </button>
          )}
          <button className="btn" onClick={() => load(true)}>
            <IconRefresh /> Refresh
          </button>
        </div>
      </div>

      {loading ? (
        <Loading label="Loading airing snapshot…" />
      ) : !snap?.items.length ? (
        <div className="panel">
          <Empty icon={<IconCalendar />}>No airing series found for this week.</Empty>
        </div>
      ) : (
        <div className="card-grid" style={{ gridTemplateColumns: "repeat(auto-fill, minmax(230px, 1fr))" }}>
          {snap.items.map((item) => (
            <div key={item.id} className={`panel ${selected.has(item.id) ? "selected" : ""}`} style={{ overflow: "hidden" }}>
              <div style={{ display: "flex", gap: 12, padding: 12 }}>
                <img src={item.poster_url} className="result-poster" style={{ width: 56, height: 84 }} alt="" loading="lazy" />
                <div className="grow" style={{ minWidth: 0 }}>
                  <div className="media-title">{item.name}</div>
                  <div className="row wrap" style={{ gap: 5, marginTop: 5 }}>
                    <span className={`badge ${item.status.toLowerCase() === "continuing" ? "badge-ok" : ""}`}>{item.status}</span>
                    {item.eligible_new_season && <span className="badge badge-accent">eligible</span>}
                    {!item.has_logo && <span className="badge badge-warn">no logo</span>}
                  </div>
                  <div className="hint" style={{ marginTop: 6 }}>
                    {item.selected_week_episode_label || item.next_episode_label || "—"}
                    {fmtDate(item.selected_week_air_at || item.next_air_at) && (
                      <div className="dim mono">{fmtDate(item.selected_week_air_at || item.next_air_at)}</div>
                    )}
                  </div>
                </div>
              </div>
              <div className="row" style={{ padding: "0 12px 12px", gap: 8 }}>
                <label className="chip" style={{ padding: "6px 10px" }}>
                  <input type="checkbox" checked={selected.has(item.id)} onChange={() => toggle(item.id)} /> Select
                </label>
                <button
                  className="btn btn-sm btn-primary grow"
                  disabled={!item.has_logo || !item.eligible_new_season || busy[item.id]}
                  onClick={() => applyOne(item)}
                >
                  {busy[item.id] ? <span className="spinner" /> : <IconCheck />} New Season
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </>
  );
}
