import { useState, useEffect, useRef, Fragment } from "react";
import { useTheme } from "../useTheme";
import { useAuth } from "@clerk/react";
import Badge from "./Badge";
import DocStatusBar from "./DocStatusBar";
import ConfirmVisitModal from "./ConfirmVisitModal";
import StatusLegend from "./StatusLegend";
import { updateDocStatus } from "../lib/api";

function daysLabel(days, flag) {
  if (days === undefined || days === null) return <span className="font-mono font-medium text-[var(--text-warm)]">—</span>;
  if (days < 0)
    return <span className="font-mono font-semibold text-[#FF7070]">Expired {Math.abs(days)}d ago</span>;
  // RESUPPLY_READY: days left means window closing, not a problem — show as teal urgency not red alert
  if (flag === "RESUPPLY_READY") {
    if (days <= 7) return <span className="font-mono font-medium text-[var(--brand)]">{days} days</span>;
    if (days <= 30) return <span className="font-mono font-medium text-[var(--accent-text)]">{days} days</span>;
    return <span className="font-mono font-medium text-[var(--text-primary)]">{days} days</span>;
  }
  if (days <= 7)
    return <span className="font-mono font-medium text-[#FF7070]">{days} days</span>;
  if (days <= 30)
    return <span className="font-mono font-medium text-[var(--accent-text)]">{days} days</span>;
  return <span className="font-mono font-medium text-[var(--text-primary)]">{days} days</span>;
}

function scoreClass(priority) {
  if (priority >= 1000) return "text-[#B00000]";
  if (priority >= 500) return "text-[var(--accent-text)]";
  if (priority >= 200) return "text-[var(--text-secondary)]";
  return "text-[var(--text-warm)]";
}

const FILTERS = [
  { key: "all",            label: "All",            color: null,      check: false },
  { key: "at-risk",        label: "At Risk",         color: "#E53E3E", check: false },
  { key: "action-needed",  label: "Action Needed",   color: "#F59E0B", check: false },
  { key: "RESUPPLY_READY", label: "Clear to Ship",   color: "#22C55E", check: true  },
  { key: "ACTIVE",         label: "On Track",        color: "#2EA3A3", check: false },
];

const SWO_CYCLE = ["pending", "requested", "on_file"];
const PA_CYCLE = ["not_required", "requested", "approved", "denied"];
const DOC_STATUS_LABELS = {
  pending: "Pending", requested: "Requested", on_file: "On File",
  not_required: "Not Required", approved: "Approved", denied: "Denied",
};

const AT_RISK_FLAGS = ["SUPPLY_LAPSED", "VISIT_REQUIRED", "RENEWAL_CRITICAL"];
const ACTION_NEEDED_FLAGS = ["RENEWAL_ELEVATED", "RENEWAL_SOON", "TRANSFER_PENDING"];

const HIGH_PRIORITY_FLAGS = ["SUPPLY_LAPSED", "VISIT_REQUIRED", "RENEWAL_CRITICAL", "TRANSFER_PENDING"];
const CONFIRM_VISIT_FLAGS = ["VISIT_REQUIRED", "RENEWAL_CRITICAL", "RENEWAL_ELEVATED", "RENEWAL_SOON"];

export default function WorklistTable({ records, activeFilter, onFilterChange, onVisitConfirmed }) {
  const { dark } = useTheme();
  const { getToken } = useAuth();
  const [expandedRow, setExpandedRow] = useState(() => localStorage.getItem("signal_expanded_row") || null);
  const [activePatientId, setActivePatientId] = useState(null);
  const [confirmingRecord, setConfirmingRecord] = useState(null);
  const [localRecords, setLocalRecords] = useState(records);
  const [toast, setToast] = useState({ visible: false, message: "" });
  const [localDocStates, setLocalDocStates] = useState({});
  const rowRefs = useRef({});

  useEffect(() => {
    setLocalRecords(records);
    setLocalDocStates({});
  }, [records]);

  function showToast(message) {
    setToast({ visible: true, message });
    setTimeout(() => setToast({ visible: false, message: "" }), 5000);
  }

  function handleSaveSuccess({ patient_id: savedPatientId }) {
    setActivePatientId(prev => (prev === savedPatientId ? null : prev));

    const EXCLUDED_FLAGS = ["ACTIVE", "NO_RECENT_SHIPMENT"];
    const next = localRecords
      .filter(r => !EXCLUDED_FLAGS.includes(r.flag) && r.patient_id !== savedPatientId)
      .sort((a, b) => (b.priority_score || b.priority || 0) - (a.priority_score || a.priority || 0))[0];

    if (next) {
      const label = next.reason || next.flag || "";
      showToast(`Done. Next: Patient ${next.patient_id}: ${label}`);
    } else {
      showToast("Done. Your list is clear.");
    }
  }

  function handleVisitConfirmed(patientId, updatedRecord) {
    setLocalRecords(prev =>
      prev.map(r => r.patient_id === patientId ? { ...r, ...updatedRecord } : r)
        .sort((a, b) => (b.priority_score || b.priority || 0) - (a.priority_score || a.priority || 0))
    );
    onVisitConfirmed?.(patientId, updatedRecord);
  }

  const filtered =
    activeFilter === "all"
      ? localRecords
      : activeFilter === "at-risk"
      ? localRecords.filter((r) => AT_RISK_FLAGS.includes(r.flag))
      : activeFilter === "action-needed"
      ? localRecords.filter((r) => ACTION_NEEDED_FLAGS.includes(r.flag))
      : localRecords.filter((r) => r.flag === activeFilter);

  const todayStr = new Date().toLocaleDateString("en-US", {
    month: "short",
    day: "numeric",
    year: "numeric",
  });

  const total = localRecords.length;
  const tabCounts = {
    all:              total,
    "at-risk":        localRecords.filter(r => AT_RISK_FLAGS.includes(r.flag)).length,
    "action-needed":  localRecords.filter(r => ACTION_NEEDED_FLAGS.includes(r.flag)).length,
    RESUPPLY_READY:   localRecords.filter(r => r.flag === "RESUPPLY_READY" && !(r.cascade?.length > 0)).length,
    ACTIVE:           localRecords.filter(r => r.flag === "ACTIVE").length,
  };

  return (
    <div className="bg-[var(--bg-card)] border border-[var(--border-color)] rounded-[10px] shadow-[var(--shadow-card-md)] overflow-hidden transition-colors">
      {/* Header */}
      <div className="flex items-center justify-between px-[22px] py-4 border-b border-[var(--border-color)] bg-[var(--bg-elevated)] gap-4 flex-wrap">
        <div>
          <div className="font-heading font-bold text-[15px] text-[var(--text-heading)]">
            Outreach Worklist
          </div>
          <div className="font-mono text-[11px] text-[var(--text-warm)] mt-[2px]">
            {localRecords.length} patients · sorted by priority score · {todayStr}
          </div>
        </div>
        <div className="flex gap-[6px] flex-wrap">
          {FILTERS.map((f) => {
            const count = tabCounts[f.key] ?? 0;
            const pct = total > 0 && f.key !== "all" ? Math.round((count / total) * 100) : null;
            const isActive = activeFilter === f.key;
            const indicatorColor = isActive ? "white" : f.color;
            return (
              <button
                key={f.key}
                onClick={() => onFilterChange(f.key)}
                className={`px-3 py-[5px] rounded-full text-[11.5px] cursor-pointer font-body transition-all border inline-flex items-center gap-[5px] ${
                  isActive
                    ? "bg-[var(--brand)] text-white border-[var(--brand)]"
                    : "bg-transparent border-[var(--border-color)] text-[var(--text-secondary)] hover:border-[var(--brand)] hover:text-[var(--brand)]"
                }`}
              >
                {f.color && (
                  f.check
                    ? <span style={{ color: indicatorColor, fontSize: "12px", fontWeight: 800, lineHeight: 1, marginTop: "-1px" }}>✓</span>
                    : <span style={{ width: 6, height: 6, borderRadius: "50%", backgroundColor: indicatorColor, display: "inline-block", flexShrink: 0 }} />
                )}
                {f.label}
                {total > 0 && (
                  <span style={{ opacity: 0.65, fontSize: "10.5px", fontWeight: 500 }}>
                    {f.key === "all" ? count : `${count}${pct !== null ? ` · ${pct}%` : ""}`}
                  </span>
                )}
              </button>
            );
          })}
        </div>
      </div>

      {/* Working-on banner */}
      {activePatientId && (
        <div
          style={{
            backgroundColor: "#2EA3A3",
            color: "#ffffff",
            fontSize: "12px",
            fontWeight: 500,
            padding: "6px 22px",
            cursor: "pointer",
            lineHeight: "1.4",
          }}
          onClick={() => {
            const targetKey = Object.keys(rowRefs.current).find(k => k.startsWith(activePatientId + "-"));
            if (targetKey) {
              setExpandedRow(targetKey);
              localStorage.setItem("signal_expanded_row", targetKey);
              rowRefs.current[targetKey]?.scrollIntoView({ behavior: "smooth", block: "center" });
            }
          }}
        >
          Working on Patient {activePatientId}, click to return
        </div>
      )}

      {/* Table */}
      <table className="w-full border-collapse">
        <thead>
          <tr>
            {["Patient ID", "Device", "Payer", "Days Left", "Status", "Priority", "Action"].map(h => (
              <th key={h} className="px-[22px] py-[10px] text-left text-[10.5px] font-semibold tracking-[0.06em] uppercase text-[var(--text-warm)] bg-[var(--bg-elevated)] border-b border-[var(--border-color)] whitespace-nowrap">
                {h}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {filtered.map((r, i) => {
            const hp = HIGH_PRIORITY_FLAGS.includes(r.flag);
            const isStale = r.flag === "NO_RECENT_SHIPMENT";
            const rowKey = r.patient_id + "-" + i;
            const isExpanded = expandedRow === rowKey;
            // NO_RECENT_SHIPMENT rows never show Confirm Visit — those patients need prescriber
            // verification first, not a visit date entry. CONFIRM_VISIT_FLAGS does not include
            // NO_RECENT_SHIPMENT, so the estimated-visit fallback check is also gated.
            const showConfirmVisit = !isStale && (CONFIRM_VISIT_FLAGS.includes(r.flag) || r.visit_date_confidence === "estimated");
            // Support both API shape (days_until_coverage_end) and legacy local shape (daysUntilEnd)
            const daysLeft = r.days_until_coverage_end ?? r.daysUntilEnd;
            const priority = r.priority_score ?? r.priority;
            const deviceDisplay = r.device_display || r.device_type;
            // RESUPPLY_READY with open cascade items means timing is fine but docs are not.
            // Show amber "Docs Required" badge instead of green "Clear to Ship".
            const effectiveFlag = (r.flag === "RESUPPLY_READY" && r.cascade?.length > 0)
              ? "DOCS_REQUIRED"
              : r.flag;

            return (
              <Fragment key={rowKey}>
                <tr
                  ref={el => { rowRefs.current[rowKey] = el; }}
                  className={`border-b border-[var(--border-subtle)] transition-colors cursor-pointer hover:bg-[var(--row-hover)] ${
                    isStale
                      ? "opacity-50"
                      : hp
                      ? dark
                        ? "bg-[rgba(224,104,48,0.09)] hover:bg-[rgba(203,107,32,0.14)]"
                        : "bg-[rgba(224,96,40,0.05)] hover:bg-[rgba(203,107,32,0.14)]"
                      : ""
                  }`}
                  onClick={() => {
                    if (isExpanded) {
                      // Collapsing — clear active if this is the active patient
                      setActivePatientId(prev => (prev === r.patient_id ? null : prev));
                      setExpandedRow(null);
                      localStorage.removeItem("signal_expanded_row");
                    } else {
                      // Expanding — mark as active if showConfirmVisit
                      if (showConfirmVisit) {
                        setActivePatientId(r.patient_id);
                      }
                      setExpandedRow(rowKey);
                      localStorage.setItem("signal_expanded_row", rowKey);
                    }
                  }}
                >
                  <td className="px-[22px] py-[13px] align-middle">
                    <div className={`font-mono text-[12.5px] font-bold ${isStale ? "italic text-[var(--text-warm)]" : hp ? "text-[var(--accent-text)]" : "text-[var(--text-secondary)]"}`}>
                      {r.patient_id}
                    </div>
                    {i === 0 && (
                      <div className="font-mono text-[9.5px] font-semibold tracking-[0.06em] text-[var(--accent-text)] mt-[2px]">
                        ★ TOP PRIORITY
                      </div>
                    )}
                    {r.visit_date_confidence === "estimated" && (
                      <div className="text-[9px] text-[#CB6B20] mt-[2px]">Estimated visit date</div>
                    )}
                  </td>
                  <td className="px-[22px] py-[13px] text-[13.5px] font-medium text-[var(--text-primary)] align-middle">
                    {deviceDisplay}
                  </td>
                  <td className="px-[22px] py-[13px] text-[13px] text-[var(--text-secondary)] align-middle">
                    {r.payer}
                  </td>
                  <td className="px-[22px] py-[13px] align-middle">
                    {daysLabel(daysLeft, r.flag)}
                  </td>
                  <td className="px-[22px] py-[13px] align-middle">
                    <div className="flex items-center gap-[8px]">
                      <Badge flag={effectiveFlag} />
                      {r.doc_state && <DocStatusBar docState={r.doc_state} />}
                    </div>
                    {r.reason && (
                      <div className="text-[10.5px] text-[var(--text-warm)] mt-[4px] max-w-[260px] leading-[1.4]">
                        {r.reason}
                      </div>
                    )}
                    {r.flag === "ACTIVE" && r.next_visit_due_date && (
                      <div className="text-[10.5px] text-[var(--text-warm)] mt-[4px]">
                        Next visit due: {new Date(r.next_visit_due_date + "T00:00:00").toLocaleDateString("en-US", { month: "short", year: "numeric" })}
                      </div>
                    )}
                  </td>
                  <td className="px-[22px] py-[13px] align-middle">
                    <span className={`font-mono text-[16px] font-medium ${scoreClass(priority)}`}>
                      {priority}
                    </span>
                  </td>
                  <td className="px-[22px] py-[13px] align-middle" onClick={e => e.stopPropagation()}>
                    <ActionCell
                      flag={effectiveFlag}
                      cascade={r.cascade}
                      showConfirmVisit={showConfirmVisit}
                      onConfirmVisit={() => setConfirmingRecord(r)}
                      onExpand={(e) => {
                        e.stopPropagation();
                        if (isExpanded) {
                          setActivePatientId(prev => (prev === r.patient_id ? null : prev));
                          setExpandedRow(null);
                          localStorage.removeItem("signal_expanded_row");
                        } else {
                          if (showConfirmVisit) setActivePatientId(r.patient_id);
                          setExpandedRow(rowKey);
                          localStorage.setItem("signal_expanded_row", rowKey);
                        }
                      }}
                    />
                  </td>
                </tr>

                {/* Expanded row — cascade + doc checklist */}
                {isExpanded && (
                  <tr key={rowKey + "-expanded"} className="bg-[var(--bg-elevated)]">
                    <td colSpan={7} className="px-[32px] py-[16px]">
                      {r.cascade && r.cascade.length > 0 && (
                        <div className="mb-4">
                          <div className="text-[11px] font-semibold text-[#CC2222] uppercase tracking-[0.06em] mb-2">
                            Documentation Actions Required
                          </div>
                          <ul className="list-none m-0 p-0 space-y-[6px]">
                            {r.cascade.map((item, idx) => {
                              const isDenied = /denied/i.test(item);
                              const color = isDenied ? "#CC2222" : "#CB6B20";
                              return (
                                <li key={idx} className="flex gap-[8px] items-start text-[12.5px] leading-[1.5]" style={{ color }}>
                                  <span className="shrink-0 font-bold mt-[1px]">•</span>
                                  <span>{item}</span>
                                </li>
                              );
                            })}
                          </ul>
                        </div>
                      )}
                      {r.doc_state && (
                        <div>
                          <div className="text-[11px] font-semibold text-[var(--text-warm)] uppercase tracking-[0.06em] mb-2">
                            Documentation Checklist
                          </div>
                          <div className="grid grid-cols-2 gap-y-[6px] gap-x-[20px] text-[12px]">
                            <DocItem
                              label="SWO"
                              value={localDocStates[`${r.patient_id}:${r.device_type}`]?.swo ?? r.doc_state.swo}
                              patientId={r.patient_id} deviceType={r.device_type} docType="swo" cycle={SWO_CYCLE}
                              getToken={getToken}
                              onUpdated={(type, label) => setLocalDocStates(prev => ({
                                ...prev, [`${r.patient_id}:${r.device_type}`]: { ...prev[`${r.patient_id}:${r.device_type}`], [type]: label }
                              }))}
                            />
                            <DocItem label="Qualifying Visit" value={r.doc_state.visit} />
                            <DocItem label="PECOS Enrollment" value={r.doc_state.pecos} />
                            <DocItem
                              label="Prior Authorization"
                              value={localDocStates[`${r.patient_id}:${r.device_type}`]?.pa ?? r.doc_state.pa}
                              patientId={r.patient_id} deviceType={r.device_type} docType="pa" cycle={PA_CYCLE}
                              getToken={getToken}
                              onUpdated={(type, label) => setLocalDocStates(prev => ({
                                ...prev, [`${r.patient_id}:${r.device_type}`]: { ...prev[`${r.patient_id}:${r.device_type}`], [type]: label }
                              }))}
                            />
                            <DocItem label="Diagnosis on File" value={r.doc_state.diagnosis} />
                          </div>
                        </div>
                      )}
                      {!r.doc_state && !r.cascade?.length && (
                        <div className="text-[12px] text-[var(--text-warm)]">No documentation details available. Upload a CSV with doc columns to see the full checklist.</div>
                      )}
                    </td>
                  </tr>
                )}
              </Fragment>
            );
          })}
          {filtered.length === 0 && (
            <tr>
              <td colSpan={7} className="px-[22px] py-8 text-center text-[var(--text-warm)]">
                No patients match this filter.
              </td>
            </tr>
          )}
        </tbody>
      </table>

      {/* Footer */}
      <div className="flex items-center justify-between px-[22px] py-3 border-t border-[var(--border-subtle)] text-[11px] text-[var(--text-warm)] bg-[var(--bg-elevated)]">
        <span className="flex items-center gap-[6px] text-[var(--text-secondary)]">
          PHI-safe — patient names and DOBs never stored. Crosswalk: patient_id only.
        </span>
        <span>
          {activeFilter === "all"
            ? `${localRecords.length} patients · all results shown`
            : `${filtered.length} of ${localRecords.length} · filtered`}
        </span>
      </div>

      {/* Confirm Visit Modal */}
      {confirmingRecord && (
        <ConfirmVisitModal
          record={confirmingRecord}
          onClose={() => setConfirmingRecord(null)}
          onConfirmed={handleVisitConfirmed}
          onSaveSuccess={handleSaveSuccess}
        />
      )}

      {/* Next-priority toast */}
      {toast.visible && (
        <div
          style={{
            position: "fixed",
            bottom: "24px",
            right: "24px",
            backgroundColor: "#2EA3A3",
            color: "#ffffff",
            padding: "10px 16px",
            borderRadius: "8px",
            fontSize: "12.5px",
            fontWeight: 500,
            boxShadow: "0 4px 12px rgba(0,0,0,0.18)",
            zIndex: 9999,
            maxWidth: "340px",
            lineHeight: "1.4",
          }}
        >
          {toast.message}
        </div>
      )}
    </div>
  );
}

function ActionCell({ flag, cascade, showConfirmVisit, onConfirmVisit, onExpand }) {
  const hasCascade = cascade && cascade.length > 0;
  const accentBtn = "bg-transparent border border-[var(--accent)] text-[var(--accent-text)] px-[10px] py-[4px] rounded-md text-[11px] cursor-pointer font-body whitespace-nowrap transition-all hover:bg-[rgba(203,107,32,0.1)] self-start";
  const mutedBtn = "bg-transparent border border-[var(--border-color)] text-[var(--text-secondary)] px-[13px] py-[5px] rounded-md text-xs cursor-pointer font-body whitespace-nowrap transition-all hover:border-[var(--brand)] hover:text-[var(--brand)]";

  if (flag === "RESUPPLY_READY") {
    return (
      <div className="flex items-center gap-[5px]" style={{ color: "#1A8040" }}>
        <span style={{ fontSize: "13px", fontWeight: 800 }}>✓</span>
        <span className="text-[11.5px] font-medium">Ready to ship</span>
      </div>
    );
  }

  if (hasCascade) {
    return (
      <div className="flex flex-col gap-[4px]">
        <ul className="list-none m-0 p-0 space-y-[2px]">
          {cascade.map((item, idx) => {
            const shortLabel = item.split(" — ")[0];
            const isDenied = /denied/i.test(item);
            return (
              <li key={idx} className="flex gap-[5px] items-start text-[11px] leading-[1.35]"
                style={{ color: isDenied ? "#CC2222" : "#CB6B20" }}>
                <span className="shrink-0 mt-[1px]">•</span>
                <span>{shortLabel}</span>
              </li>
            );
          })}
        </ul>
        {showConfirmVisit ? (
          <button onClick={onConfirmVisit} className={accentBtn}>Confirm Visit →</button>
        ) : (
          <button onClick={onExpand} className={accentBtn}>Update →</button>
        )}
      </div>
    );
  }

  if (showConfirmVisit) {
    return (
      <button onClick={onConfirmVisit} className="bg-transparent border border-[var(--accent)] text-[var(--accent-text)] px-[13px] py-[5px] rounded-md text-xs cursor-pointer font-body whitespace-nowrap transition-all hover:bg-[rgba(203,107,32,0.1)]">
        Confirm Visit →
      </button>
    );
  }

  if (flag === "TRANSFER_PENDING") {
    return <button onClick={onExpand} className={`${mutedBtn} !border-[var(--accent)] !text-[var(--accent-text)] hover:bg-[rgba(203,107,32,0.1)]`}>Verify Docs →</button>;
  }
  if (flag === "NO_RECENT_SHIPMENT" || flag === "SUPPLY_LAPSED") {
    return <button onClick={onExpand} className={mutedBtn}>Update →</button>;
  }
  return null;
}

function DocItem({ label, value, patientId, deviceType = "", docType, cycle, getToken, onUpdated }) {
  const [saving, setSaving] = useState(false);

  const isGood = value && (
    value === "On File" || value === "Verified" || value === "Not Required" ||
    value.startsWith("Confirmed") || value.startsWith("Approved") || value === "N/A"
  );
  const isBad = value && (
    value === "Missing" || value === "Not Verified" || value === "Expired" ||
    value === "Denied" || value === "Required — Not Started" || value === "Pending"
  );
  const color = isGood ? "text-[#1A8040]" : isBad ? "text-[#CC2222]" : "text-[#CB6B20]";

  const currentKey = Object.entries(DOC_STATUS_LABELS).find(([, v]) => v === value)?.[0];

  const handleCycle = async () => {
    if (!cycle || !patientId || saving) return;
    const idx = currentKey ? cycle.indexOf(currentKey) : -1;
    const nextKey = cycle[(idx + 1) % cycle.length];
    const nextLabel = DOC_STATUS_LABELS[nextKey];
    setSaving(true);
    const token = getToken ? await getToken().catch(() => null) : null;
    const result = await updateDocStatus(patientId, docType, nextKey, null, null, token, deviceType);
    setSaving(false);
    if (result && onUpdated) onUpdated(docType, nextLabel);
  };

  return (
    <div className="flex items-start gap-[6px]">
      <span className="text-[var(--text-warm)] w-[140px] shrink-0">{label}:</span>
      {cycle ? (
        <button
          onClick={handleCycle}
          disabled={saving}
          title={saving ? "Saving…" : `Click to update ${label} status`}
          className={`font-medium ${color} hover:underline underline-offset-2 cursor-pointer disabled:opacity-50 bg-transparent border-none p-0 text-left`}
          style={{ fontSize: "inherit", fontFamily: "inherit" }}
        >
          {saving ? "Saving…" : (value || "Unknown")}
        </button>
      ) : (
        <span className={`font-medium ${color}`}>{value || "Unknown"}</span>
      )}
    </div>
  );
}
