import { useCallback, useEffect, useState } from "react";
import { api } from "../lib/api";

interface Item {
  id: number; position: number; title: string; zendesk_tickets: string;
  jira_key: string; jira_status: string; body: string; links: string[];
  state: string; remove_at_end_of_shift: boolean; first_raised_on: string | null;
  carried_from_id: number | null;
}
interface RunpodRow {
  machine_id: string; name: string; colour: string; zendesk_ticket: string;
  jira_key: string; jira_status: string; gpu_reserved: number; gpu_total: number;
  last_error: string; next_steps: string; hours_unlisted: number | null; unlist_count: number;
}
interface Doc {
  id: number; title: string; shift: string; shift_date: string; handing_to: string;
  status: string; team_members: string; significant_issues_checked: boolean;
  hubspot_checked: boolean; total_open_tickets: number | null;
  member_checks: { name: string; hs_checked: boolean; jira_checked: boolean }[];
  other_comments: string; item_count: number; items: Item[];
}

const STATES: Record<string, string> = {
  pending_infra: "Pending Infra", pending_customer: "Pending customer",
  pending_runpod: "Pending RunPod", pending_rma: "Pending RMA", pending_cx: "Pending CX",
  in_progress: "In progress", monitoring: "Monitoring",
  no_further_engagement: "No further engagement", done: "Done",
};

const COLOURS: Record<string, { dot: string; text: string }> = {
  red: { dot: "#f2545b", text: "Blocked from relisting — recurring issue" },
  purple: { dot: "#a97bf0", text: "Pending RunPod" },
  yellow: { dot: "#e0a336", text: "Pending Infrastructure / DC team" },
  blue: { dot: "#59a0f5", text: "Pending removal from the RunPod platform" },
  green: { dot: "#35c46a", text: "Stress testing >24h — GPUs may look reserved" },
  white: { dot: "#8a93a5", text: "Actionable by CX" },
};

const blankItem = (): Partial<Item> => ({
  title: "", zendesk_tickets: "", jira_key: "", jira_status: "", body: "",
  links: [], state: "in_progress", remove_at_end_of_shift: false,
});

export default function HandoverPage() {
  const [doc, setDoc] = useState<Doc | null>(null);
  const [runpod, setRunpod] = useState<RunpodRow[]>([]);
  const [editing, setEditing] = useState<Partial<Item> | null>(null);
  const [saved, setSaved] = useState("");
  const [busy, setBusy] = useState(false);

  const load = useCallback(async () => {
    const r = await api.get<{ handover: Doc | null; runpod: RunpodRow[] }>("/api/handover/current");
    setDoc(r.handover); setRunpod(r.runpod ?? []);
  }, []);
  useEffect(() => { void load(); }, [load]);

  const flash = (m: string) => { setSaved(m); setTimeout(() => setSaved(""), 2200); };

  const saveDoc = async (patch: Partial<Doc>) => {
    if (!doc) return;
    const next = await api.post<Doc>(`/api/handover/${doc.id}`, { ...doc, ...patch });
    setDoc(next); flash("Saved");
  };

  const saveItem = async () => {
    if (!doc || !editing) return;
    setBusy(true);
    try {
      const path = editing.id
        ? `/api/handover/${doc.id}/items/${editing.id}`
        : `/api/handover/${doc.id}/items`;
      setDoc(await api.post<Doc>(path, editing));
      setEditing(null); flash("Item saved");
    } finally { setBusy(false); }
  };

  const handOver = async () => {
    if (!doc) return;
    if (!confirm("Close this shift and start the next one? Live items carry forward; " +
                 "anything done or flagged 'remove at end of shift' is left behind.")) return;
    const r = await api.post<{ next: Doc; carried: number }>(`/api/handover/${doc.id}/hand-over`);
    setDoc(r.next); flash(`Handed over — ${r.carried} items carried forward`);
  };

  if (!doc) {
    return (
      <main style={{ padding: 26 }}>
        <div className="card">
          <h3 className="sec">No handover yet</h3>
          <button className="pri" onClick={async () => {
            await api.post("/api/handover", { shift: "APAC", handing_to: "EMEA" });
            void load();
          }}>Start today's handover</button>
        </div>
      </main>
    );
  }

  return (
    <main style={{ padding: "22px 26px 80px", maxWidth: 1180 }}>
      <div className="row">
        <h2 style={{ margin: 0, fontSize: 20 }}>{doc.title}</h2>
        <span className="badge">{doc.shift} → {doc.handing_to}</span>
        <span className={`badge ${doc.status === "draft" ? "" : "ok"}`}>{doc.status.replace("_", " ")}</span>
        <span className="spacer" style={{ marginLeft: "auto" }} />
        {saved && <span className="t-ok" style={{ fontSize: 12.5 }}>{saved}</span>}
        <button className="pri" onClick={handOver} disabled={doc.status !== "draft"}>Hand over shift</button>
      </div>

      <div className="card mt">
        <h3 className="sec">Shift</h3>
        <div style={{ display: "grid", gridTemplateColumns: "190px 1fr", gap: "10px 12px", alignItems: "center" }}>
          <label className="hint" style={{ margin: 0 }}>CX team members</label>
          <input defaultValue={doc.team_members} onBlur={(e) => saveDoc({ team_members: e.target.value })} />
          <label className="hint" style={{ margin: 0 }}>Total open tickets</label>
          <input type="number" defaultValue={doc.total_open_tickets ?? undefined} style={{ maxWidth: 140 }}
                 onBlur={(e) => saveDoc({ total_open_tickets: Number(e.target.value) })} />
          <label className="hint" style={{ margin: 0 }}>Checks</label>
          <div className="row">
            <label className="row" style={{ gap: 6 }}>
              <input type="checkbox" style={{ width: "auto" }} checked={doc.significant_issues_checked}
                     onChange={(e) => saveDoc({ significant_issues_checked: e.target.checked })} />
              Active issues of significance
            </label>
            <label className="row" style={{ gap: 6 }}>
              <input type="checkbox" style={{ width: "auto" }} checked={doc.hubspot_checked}
                     onChange={(e) => saveDoc({ hubspot_checked: e.target.checked })} />
              HubSpot “My tickets on hold”
            </label>
          </div>
        </div>
      </div>

      <div className="row mt">
        <h3 className="sec" style={{ flex: 1, margin: 0 }}>Key updates ({doc.items.length})</h3>
        <button onClick={() => setEditing(blankItem())}>Add an update</button>
      </div>

      {doc.items.map((it) => (
        <div className="card" key={it.id} style={{ marginBottom: 10 }}>
          <div className="row">
            <b style={{ flex: 1 }}>{it.title || "(untitled)"}</b>
            {it.carried_from_id && <span className="badge" title={`First raised ${it.first_raised_on}`}>carried over</span>}
            {it.remove_at_end_of_shift && <span className="badge">remove at end of shift</span>}
            <span className={`badge ${it.state === "done" ? "ok" : it.state.startsWith("pending") ? "real" : ""}`}>
              {STATES[it.state] ?? it.state}</span>
            <button className="sm" onClick={() => setEditing(it)}>Edit</button>
            <button className="sm del" onClick={async () => {
              if (!confirm("Remove this update?")) return;
              setDoc(await api.del<Doc>(`/api/handover/${doc.id}/items/${it.id}`));
            }}>Remove</button>
          </div>
          <div className="row" style={{ gap: 14, marginTop: 2 }}>
            {it.zendesk_tickets && <span className="hint" style={{ margin: 0 }}>Zendesk {it.zendesk_tickets}</span>}
            {it.jira_key && <span className="hint" style={{ margin: 0 }}>{it.jira_key} {it.jira_status}</span>}
          </div>
          {it.body && <div style={{ whiteSpace: "pre-wrap", marginTop: 8, fontSize: 13.5 }}>{it.body}</div>}
          {(it.links ?? []).map((l) => (
            <div key={l}><a href={l} target="_blank" rel="noreferrer" style={{ fontSize: 12 }}>{l}</a></div>
          ))}
        </div>
      ))}

      {editing && (
        <div className="card" style={{ borderColor: "var(--accent)" }}>
          <div className="fld"><label>Title</label>
            <input value={editing.title ?? ""} onChange={(e) => setEditing({ ...editing, title: e.target.value })} /></div>
          <div className="row">
            <div className="fld" style={{ flex: 1 }}><label>Zendesk ticket(s)</label>
              <input value={editing.zendesk_tickets ?? ""} placeholder="#8495, #8453"
                     onChange={(e) => setEditing({ ...editing, zendesk_tickets: e.target.value })} /></div>
            <div className="fld" style={{ flex: 1 }}><label>Jira key</label>
              <input value={editing.jira_key ?? ""} placeholder="OIE-3213"
                     onChange={(e) => setEditing({ ...editing, jira_key: e.target.value })} /></div>
            <div className="fld" style={{ flex: 1 }}><label>Jira status</label>
              <input value={editing.jira_status ?? ""} placeholder="In Progress"
                     onChange={(e) => setEditing({ ...editing, jira_status: e.target.value })} /></div>
          </div>
          <div className="fld"><label>Detail</label>
            <textarea value={editing.body ?? ""} onChange={(e) => setEditing({ ...editing, body: e.target.value })} /></div>
          <div className="row">
            <div className="fld" style={{ flex: 1 }}><label>Status</label>
              <select value={editing.state ?? "in_progress"}
                      onChange={(e) => setEditing({ ...editing, state: e.target.value })}>
                {Object.entries(STATES).map(([v, l]) => <option key={v} value={v}>{l}</option>)}
              </select></div>
            <label className="row" style={{ gap: 6, marginTop: 18 }}>
              <input type="checkbox" style={{ width: "auto" }} checked={!!editing.remove_at_end_of_shift}
                     onChange={(e) => setEditing({ ...editing, remove_at_end_of_shift: e.target.checked })} />
              Remove at end of shift
            </label>
          </div>
          <div className="row">
            <button className="pri" onClick={saveItem} disabled={busy}>Save</button>
            <button onClick={() => setEditing(null)}>Cancel</button>
          </div>
        </div>
      )}

      <h3 className="sec" style={{ marginTop: 28 }}>RunPod — unlisted machines ({runpod.length})</h3>
      <div className="hint" style={{ marginTop: 0 }}>
        Live from RunPod, not retyped. Colours follow the handover key.
      </div>
      <div className="row" style={{ gap: 14, margin: "8px 0 12px" }}>
        {Object.entries(COLOURS).map(([k, v]) => (
          <span key={k} className="hint" style={{ margin: 0 }} title={v.text}>
            <i style={{ display: "inline-block", width: 9, height: 9, borderRadius: 2,
                        background: v.dot, marginRight: 5 }} />{k}
          </span>
        ))}
      </div>
      <div className="card" style={{ padding: 0 }}>
        {runpod.length === 0 ? <div className="empty">Nothing unlisted.</div> : runpod.map((r, i) => (
          <div key={r.machine_id} style={{ padding: "10px 14px", borderTop: i ? "1px solid var(--line)" : undefined }}>
            <div className="row">
              <i style={{ width: 9, height: 9, borderRadius: 2, background: COLOURS[r.colour]?.dot ?? "#888" }}
                 title={COLOURS[r.colour]?.text} />
              <b style={{ flex: 1 }}>{r.name}</b>
              <span className="hint" style={{ margin: 0, fontFamily: "var(--mono)" }}>{r.machine_id}</span>
              {r.zendesk_ticket && <span className="badge">ZD {r.zendesk_ticket}</span>}
              {r.jira_key && <span className="badge">{r.jira_key} {r.jira_status}</span>}
              <span className="badge">{r.gpu_reserved}/{r.gpu_total} GPU</span>
              {r.hours_unlisted != null && <span className="badge">{r.hours_unlisted}h</span>}
              {r.unlist_count > 3 && <span className="badge overdue">{r.unlist_count}× unlisted</span>}
            </div>
            {r.last_error && (
              <pre style={{ marginTop: 6, fontSize: 11.5, background: "var(--bg)" }}>{r.last_error}</pre>
            )}
            {r.next_steps && <div className="hint" style={{ marginTop: 4 }}>{r.next_steps}</div>}
          </div>
        ))}
      </div>

      <h3 className="sec" style={{ marginTop: 28 }}>Other comments</h3>
      <div className="card">
        <textarea defaultValue={doc.other_comments} style={{ minHeight: 160 }}
                  onBlur={(e) => saveDoc({ other_comments: e.target.value })} />
      </div>
    </main>
  );
}
