/* global React */
// Admin Console — manage team members, Workable IDs, timezones, working hours,
// and weekend shift coverage windows. Has sub-tabs: Roster | Weekend Hours.

const { useState: useStateA, useMemo: useMemoA, useRef: useRefA } = React;

const TEAM_OPTIONS = ["L1", "L2", "Invoicing"];
const REGION_OPTIONS = ["EMEA", "APAC", "LATAM"];
const STATUS_OPTIONS = [
  { value: "working", label: "Working" },
  { value: "off",     label: "Time Off" },
];
const REASON_OPTIONS = ["Time Off", "WR", "Sick", "Holiday", "Parental", "Other"];
const TZ_SUGGESTIONS = ["GMT", "WET", "CET", "EET", "MSK", "IST", "PKT", "AEST", "BRT", "ART", "COT", "CLT", "MXT", "PT", "ET"];
const SECTIONS = [
  { id: "roster",  label: "Roster" },
  { id: "weekend", label: "Weekend Shift Hours" },
  { id: "leaders", label: "Daily Call Leaders" },
];

function AdminConsole({ people, setPeople, leadHistory, setLeadHistory, onLogout }) {
  const [section, setSection] = useStateA("roster");

  const updatePerson = (origName, patch) => {
    setPeople(prev => prev.map(p => p.name === origName ? { ...p, ...patch } : p));
  };

  const counts = useMemoA(() => ({
    total: people.length,
    L1: people.filter(p => p.team === "L1").length,
    L2: people.filter(p => p.team === "L2").length,
    Invoicing: people.filter(p => p.team === "Invoicing").length,
    off: people.filter(p => p.status === "off").length,
    noWorkable: people.filter(p => !p.workableId).length,
  }), [people]);

  return (
    <div className="adm-root">
      <header className="adm-header">
        <div>
          <div className="adm-eyebrow">Admin</div>
          <h1 className="adm-title">
            {section === "roster"   ? "Team members" :
             section === "weekend"  ? "Weekend shift hours" :
                                       "Daily call leaders"}
          </h1>
          <nav className="adm-section-tabs">
            {SECTIONS.map(s => (
              <button key={s.id}
                className={section === s.id ? "is-active" : ""}
                onClick={() => setSection(s.id)}>
                {s.label}
              </button>
            ))}
          </nav>
        </div>

        {section === "roster" && (
          <div className="adm-stat-row">
            <Stat label="Total" value={counts.total} />
            <Stat label="L1"    value={counts.L1} />
            <Stat label="L2"    value={counts.L2} />
            <Stat label="Inv."  value={counts.Invoicing} />
            <Stat label="Off"   value={counts.off} tone="red" />
            <Stat label="No Workable ID" value={counts.noWorkable} tone={counts.noWorkable ? "amber" : "muted"} />
          </div>
        )}
      </header>

      {section === "roster"
        ? <RosterPanel people={people} setPeople={setPeople} updatePerson={updatePerson} />
        : section === "weekend"
          ? <WeekendHoursPanel people={people} updatePerson={updatePerson} setPeople={setPeople} />
          : <LeadersPanel people={people} leadHistory={leadHistory} setLeadHistory={setLeadHistory} />}

      <footer className="adm-footer">
        <span className="adm-footer-note">
          Changes are saved to your browser automatically. Use Export to back them up.
        </span>
        {onLogout && (
          <button className="adm-btn adm-btn-ghost adm-signout" onClick={onLogout}>
            Sign out
          </button>
        )}
      </footer>
    </div>
  );
}

/* ── Roster panel ─────────────────────────────────────────── */
function RosterPanel({ people, setPeople, updatePerson }) {
  const [query, setQuery] = useStateA("");
  const [teamFilter, setTeamFilter] = useStateA("All");
  const fileInputRef = useRefA(null);

  const filtered = useMemoA(() => {
    const q = query.trim().toLowerCase();
    return people.filter(p => {
      if (teamFilter !== "All" && p.team !== teamFilter) return false;
      if (!q) return true;
      return (p.name + " " + (p.workableId || "") + " " + (p.region || "") + " " + (p.tz || ""))
        .toLowerCase().includes(q);
    });
  }, [people, query, teamFilter]);

  const removePerson = (name) => {
    if (!confirm(`Remove ${name} from the roster?`)) return;
    setPeople(prev => prev.filter(p => p.name !== name));
  };

  const addPerson = () => {
    const base = window.CSStore.withDefaults({
      name: "New Member",
      team: "L1",
      region: "EMEA",
      tz: "CET",
      status: "working",
      shift: "off",
    });
    let n = 1; let candidate = base.name;
    const existing = new Set(people.map(p => p.name));
    while (existing.has(candidate)) { n += 1; candidate = `New Member ${n}`; }
    base.name = candidate;
    setPeople(prev => [...prev, base]);
    setTimeout(() => {
      const input = document.querySelector(`input[data-admin-name="${candidate}"]`);
      if (input) { input.focus(); input.select(); }
    }, 30);
  };

  const exportJson = () => {
    const blob = new Blob([JSON.stringify(people, null, 2)], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `cs-roster-${new Date().toISOString().slice(0,10)}.json`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const importJson = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (ev) => {
      try {
        const parsed = JSON.parse(ev.target.result);
        if (!Array.isArray(parsed)) throw new Error("Not an array");
        setPeople(parsed.map(window.CSStore.withDefaults));
      } catch (err) {
        alert("Import failed: " + err.message);
      }
    };
    reader.readAsText(file);
    e.target.value = "";
  };

  const resetToDefaults = () => {
    if (!confirm("Reset roster to the original spreadsheet defaults? Your edits will be lost.")) return;
    window.CSStore.resetPeople();
    setPeople(window.CSStore.loadPeople());
  };

  return (
    <>
      <div className="adm-toolbar">
        <input
          className="adm-search"
          type="search"
          placeholder="Search by name, Workable ID, region…"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />
        <div className="adm-team-filter">
          {["All", ...TEAM_OPTIONS].map(t => (
            <button key={t}
              className={teamFilter === t ? "is-active" : ""}
              onClick={() => setTeamFilter(t)}>{t}</button>
          ))}
        </div>
        <div className="adm-toolbar-actions">
          <button className="adm-btn adm-btn-ghost" onClick={exportJson}>↓ Export</button>
          <button className="adm-btn adm-btn-ghost" onClick={() => fileInputRef.current?.click()}>↑ Import</button>
          <input type="file" accept="application/json" ref={fileInputRef} style={{ display: "none" }} onChange={importJson} />
          <button className="adm-btn adm-btn-ghost" onClick={resetToDefaults}>↺ Reset</button>
          <button className="adm-btn adm-btn-primary" onClick={addPerson}>+ Add member</button>
        </div>
      </div>

      <div className="adm-table-wrap">
        <table className="adm-table">
          <thead>
            <tr>
              <th className="adm-th-name">Name</th>
              <th>Team</th>
              <th>Region</th>
              <th>Timezone</th>
              <th>Working hours</th>
              <th>Workable ID</th>
              <th>Status today</th>
              <th>Shift</th>
              <th className="adm-th-actions"></th>
            </tr>
          </thead>
          <tbody>
            {filtered.map(p => (
              <tr key={p.name}>
                <td className="adm-td-name">
                  <input
                    type="text"
                    value={p.name}
                    data-admin-name={p.name}
                    onChange={(e) => updatePerson(p.name, { name: e.target.value })}
                    className="adm-input adm-input-name"
                  />
                </td>
                <td>
                  <select
                    className="adm-input"
                    value={p.team}
                    onChange={(e) => updatePerson(p.name, { team: e.target.value })}>
                    {TEAM_OPTIONS.map(t => <option key={t} value={t}>{t}</option>)}
                  </select>
                </td>
                <td>
                  <select
                    className="adm-input"
                    value={p.region || ""}
                    onChange={(e) => updatePerson(p.name, { region: e.target.value })}>
                    {REGION_OPTIONS.map(r => <option key={r} value={r}>{r}</option>)}
                  </select>
                </td>
                <td>
                  <input
                    type="text"
                    className="adm-input adm-input-mono"
                    list="tz-suggestions"
                    value={p.tz || ""}
                    onChange={(e) => updatePerson(p.name, { tz: e.target.value })}
                  />
                </td>
                <td>
                  <input
                    type="text"
                    className="adm-input adm-input-mono"
                    placeholder="09:00–17:00"
                    value={p.hours || ""}
                    onChange={(e) => updatePerson(p.name, { hours: e.target.value })}
                  />
                </td>
                <td>
                  <input
                    type="text"
                    className="adm-input adm-input-mono"
                    placeholder="(unset)"
                    value={p.workableId || ""}
                    onChange={(e) => updatePerson(p.name, { workableId: e.target.value })}
                  />
                </td>
                <td>
                  <select
                    className={`adm-input adm-status-${p.status}`}
                    value={p.status}
                    onChange={(e) => {
                      const next = { status: e.target.value };
                      if (e.target.value === "working") next.reason = undefined;
                      else if (!p.reason) next.reason = "Time Off";
                      updatePerson(p.name, next);
                    }}>
                    {STATUS_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
                  </select>
                  {p.status === "off" && (
                    <select
                      className="adm-input adm-input-sm"
                      value={p.reason || "Time Off"}
                      onChange={(e) => updatePerson(p.name, { reason: e.target.value })}>
                      {REASON_OPTIONS.map(r => <option key={r} value={r}>{r}</option>)}
                    </select>
                  )}
                </td>
                <td>
                  <div className="adm-shift-toggle">
                    <button
                      className={p.shift === "on" ? "is-active is-on" : ""}
                      onClick={() => updatePerson(p.name, { shift: "on" })}>On</button>
                    <button
                      className={p.shift !== "on" ? "is-active is-off" : ""}
                      onClick={() => updatePerson(p.name, { shift: "off" })}>Off</button>
                  </div>
                </td>
                <td className="adm-td-actions">
                  <button className="adm-row-del" onClick={() => removePerson(p.name)} title="Remove">✕</button>
                </td>
              </tr>
            ))}
            {filtered.length === 0 && (
              <tr><td colSpan={9} className="adm-empty">No members match your filters.</td></tr>
            )}
          </tbody>
        </table>
        <datalist id="tz-suggestions">
          {TZ_SUGGESTIONS.map(t => <option key={t} value={t} />)}
        </datalist>
      </div>
    </>
  );
}

/* ── Weekend Hours panel ──────────────────────────────────── */
function WeekendHoursPanel({ people, updatePerson, setPeople }) {
  const [query, setQuery] = useStateA("");
  const [regionFilter, setRegionFilter] = useStateA("All");

  const filtered = useMemoA(() => {
    const q = query.trim().toLowerCase();
    return people.filter(p => {
      if (regionFilter !== "All" && p.region !== regionFilter && !(regionFilter === "L2" && p.team === "L2")) return false;
      if (!q) return true;
      return (p.name + " " + (p.region || "") + " " + (p.team || "")).toLowerCase().includes(q);
    });
  }, [people, query, regionFilter]);

  const grouped = useMemoA(() => {
    const buckets = {
      "APAC":  filtered.filter(p => p.region === "APAC"),
      "EMEA":  filtered.filter(p => p.region === "EMEA"),
      "LATAM": filtered.filter(p => p.region === "LATAM"),
      "L2":    filtered.filter(p => p.team === "L2" && (p.region === "L2" || true)).filter(p => p.team === "L2"),
    };
    // Avoid duplicates (L2 members may also have a region; show in L2 bucket only)
    buckets.APAC  = buckets.APAC.filter(p => p.team !== "L2");
    buckets.EMEA  = buckets.EMEA.filter(p => p.team !== "L2");
    buckets.LATAM = buckets.LATAM.filter(p => p.team !== "L2");
    return buckets;
  }, [filtered]);

  const updateShift = (name, patch) => {
    const person = people.find(p => p.name === name);
    const cur = person?.weekendShift || { start: "09:00", end: "17:00" };
    updatePerson(name, { weekendShift: { ...cur, ...patch } });
  };

  const applyRegionDefaults = () => {
    if (!confirm("Reset all weekend shift hours to the regional defaults?\n\nAPAC 00:00–08:00, EMEA 08:00–16:00, LATAM 16:00–24:00, L2 08:00–20:00")) return;
    setPeople(prev => prev.map(p => {
      const next = window.CSStore.withDefaults({ ...p });
      // Force-reset weekendShift to the regional default
      next.weekendShift = (p.team === "L2")
        ? { start: "08:00", end: "20:00" }
        : (
          p.region === "APAC"  ? { start: "00:00", end: "08:00" } :
          p.region === "EMEA"  ? { start: "08:00", end: "16:00" } :
          p.region === "LATAM" ? { start: "16:00", end: "24:00" } :
                                  { start: "09:00", end: "17:00" }
        );
      return next;
    }));
  };

  const REGION_FILTERS = ["All", "APAC", "EMEA", "LATAM", "L2"];

  return (
    <>
      <div className="adm-toolbar">
        <input
          className="adm-search"
          type="search"
          placeholder="Search by name…"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />
        <div className="adm-team-filter">
          {REGION_FILTERS.map(r => (
            <button key={r}
              className={regionFilter === r ? "is-active" : ""}
              onClick={() => setRegionFilter(r)}>{r}</button>
          ))}
        </div>
        <div className="adm-toolbar-actions">
          <button className="adm-btn adm-btn-ghost" onClick={applyRegionDefaults}>↺ Apply region defaults</button>
        </div>
      </div>

      <div className="adm-wh-info">
        <strong>All times in UTC.</strong> Default coverage windows match the spreadsheet:
        APAC <code>00:00–08:00</code>, EMEA <code>08:00–16:00</code>, LATAM <code>16:00–24:00</code>, L2 <code>08:00–20:00</code>.
        Override per-person below — these hours appear as bars on the Weekend Schedule timeline.
      </div>

      <div className="adm-wh-groups">
        {["APAC", "EMEA", "LATAM", "L2"].map(g => {
          const list = grouped[g];
          if (!list || list.length === 0) return null;
          return (
            <section key={g} className="adm-wh-group">
              <header className="adm-wh-group-head">
                <h3 className={`adm-wh-region adm-wh-region-${g.toLowerCase()}`}>{g}</h3>
                <span className="adm-wh-count">{list.length}</span>
              </header>
              <div className="adm-wh-grid">
                {list.map(p => (
                  <PersonShiftCard
                    key={p.name}
                    person={p}
                    onChange={(patch) => updateShift(p.name, patch)}
                  />
                ))}
              </div>
            </section>
          );
        })}
      </div>
    </>
  );
}

function PersonShiftCard({ person, onChange }) {
  const ws = person.weekendShift || { start: "09:00", end: "17:00" };
  const { startFrac, widthFrac } = computeFractions(ws.start, ws.end);

  return (
    <div className="adm-wh-card">
      <div className="adm-wh-card-name">
        <span className="mc-avatar mc-avatar-weekend">{person.name[0]}</span>
        <div>
          <div className="adm-wh-name">{person.name}</div>
          <div className="adm-wh-meta">{person.team}{person.region ? ` · ${person.region}` : ""} · {person.tz}</div>
        </div>
      </div>
      <div className="adm-wh-fields">
        <label>
          <span>Start</span>
          <input
            type="time"
            className="adm-input adm-input-mono"
            value={ws.start || ""}
            onChange={(e) => onChange({ start: e.target.value })}
          />
        </label>
        <span className="adm-wh-sep">→</span>
        <label>
          <span>End</span>
          <input
            type="time"
            className="adm-input adm-input-mono"
            value={ws.end || ""}
            onChange={(e) => onChange({ end: e.target.value })}
          />
        </label>
      </div>
      <MiniTimeline startFrac={startFrac} widthFrac={widthFrac} region={person.region || person.team} />
    </div>
  );
}

function MiniTimeline({ startFrac, widthFrac, region }) {
  const ticks = [0, 6, 12, 18, 24];
  return (
    <div className="adm-wh-mini">
      <div className="adm-wh-mini-track">
        <div
          className={`adm-wh-mini-bar adm-wh-bar-${(region || "").toLowerCase()}`}
          style={{ left: `${startFrac * 100}%`, width: `${widthFrac * 100}%` }}
        />
      </div>
      <div className="adm-wh-mini-axis">
        {ticks.map(h => (
          <span key={h} className="adm-wh-mini-tick" style={{ left: `${(h/24)*100}%` }}>
            {String(h).padStart(2, "0")}
          </span>
        ))}
      </div>
    </div>
  );
}

function computeFractions(start, end) {
  const s = parseTime(start);
  const e = parseTime(end);
  if (s == null || e == null) return { startFrac: 0, widthFrac: 0 };
  const startFrac = s / 24;
  let widthFrac = (e - s) / 24;
  if (widthFrac < 0) widthFrac += 1; // wrap past midnight
  return { startFrac, widthFrac };
}

function parseTime(t) {
  if (!t) return null;
  const m = /^(\d{1,2}):(\d{2})$/.exec(t);
  if (!m) return null;
  const h = +m[1], mi = +m[2];
  return h + mi / 60;
}

function Stat({ label, value, tone = "default" }) {
  return (
    <div className={`adm-stat adm-stat-${tone}`}>
      <div className="adm-stat-num">{value}</div>
      <div className="adm-stat-label">{label}</div>
    </div>
  );
}

/* ── Daily Call Leaders panel ─────────────────────────────── */
function LeadersPanel({ people, leadHistory: leadHistoryProp, setLeadHistory: setLeadHistoryProp }) {
  const today = window.CS_DATA?.meta?.today?.iso || new Date().toISOString().slice(0, 10);
  const [dateIso, setDateIso] = useStateA(today);
  const [localHistory, setLocalHistory] = useStateA(() => window.CSLeadHistory.load());
  const history = leadHistoryProp !== undefined ? leadHistoryProp : localHistory;
  const [flash, setFlash] = useStateA(null);
  const timeOff = window.CS_DATA?.timeOff || [];

  // updater(prev) → next; persists to wherever (parent or localStorage)
  const updateHistory = (updater) => {
    if (setLeadHistoryProp) {
      setLeadHistoryProp(updater);
    } else {
      setLocalHistory(prev => {
        const next = typeof updater === "function" ? updater(prev) : updater;
        try {
          localStorage.setItem("cs_lead_history_v1", JSON.stringify(next));
        } catch {}
        return next;
      });
    }
  };

  const SCOPES = window.CSLeadGen.SCOPES;

  const shiftDate = (days) => setDateIso(window.CSLeadGen.shiftDate(dateIso, days));

  const handlePick = (scope) => {
    const res = window.CSLeadGen.pickLead(scope, dateIso, people, timeOff, history);
    if (!res.name) {
      alert(`No one is available for ${scope} on ${dateIso}.`);
      return;
    }
    updateHistory(prev => ({ ...prev, [`${dateIso}__${scope}`]: res.name }));
    setFlash({ scope, reason: res.reason });
    setTimeout(() => setFlash(null), 2000);
  };

  const handleManual = (scope, name) => {
    updateHistory(prev => {
      const next = { ...prev };
      const key = `${dateIso}__${scope}`;
      if (name) next[key] = name;
      else delete next[key];
      return next;
    });
  };

  const handleClear = (scope) => {
    updateHistory(prev => {
      const next = { ...prev };
      delete next[`${dateIso}__${scope}`];
      return next;
    });
  };

  const resetAll = () => {
    if (!confirm("Reset the entire lead history? Manual overrides will be lost.")) return;
    updateHistory({ ...(window.CS_DATA?.leadsHistory || {}) });
  };

  // Last 7 days summary
  const recent = useMemoA(() => {
    const days = [];
    for (let i = -3; i <= 6; i++) {
      const d = window.CSLeadGen.shiftDate(dateIso, i);
      days.push(d);
    }
    return days;
  }, [dateIso]);

  return (
    <>
      <div className="adm-leaders-bar">
        <label className="adm-leaders-date">
          <span>Date</span>
          <input
            type="date"
            className="adm-input adm-input-mono"
            value={dateIso}
            onChange={(e) => setDateIso(e.target.value)}
          />
        </label>
        <div className="adm-leaders-nav">
          <button className="adm-btn adm-btn-ghost" onClick={() => shiftDate(-1)}>‹ Prev</button>
          <button className="adm-btn adm-btn-ghost" onClick={() => setDateIso(today)}>Today</button>
          <button className="adm-btn adm-btn-ghost" onClick={() => shiftDate(1)}>Next ›</button>
        </div>
        <div className="adm-toolbar-actions">
          <button className="adm-btn adm-btn-ghost" onClick={resetAll}>↺ Reset history</button>
        </div>
      </div>

      <div className="adm-leaders-cards">
        {SCOPES.map(scope => {
          const current = history[`${dateIso}__${scope}`] || null;
          const eligible = window.CSLeadGen.eligibleFor(scope, dateIso, people, timeOff, history);
          const allInScope = people.filter(p =>
            window.CSLeadGen.SCOPE_REGIONS[scope].has(p.region) &&
            (p.team === "L1" || p.team === "L2")
          );
          const skipped = allInScope.length - eligible.length;
          const isFlashing = flash?.scope === scope;
          const relaxed = isFlashing && flash.reason === "empty_relaxed";

          return (
            <section key={scope} className={`adm-leader-card ${isFlashing ? "is-flashing" : ""}`}>
              <header className="adm-leader-head">
                <div>
                  <div className="adm-leader-scope">{scope}</div>
                  <div className="adm-leader-date">{dateIso}</div>
                </div>
                {current && (
                  <button className="adm-leader-clear" onClick={() => handleClear(scope)} title="Clear assignment">✕</button>
                )}
              </header>

              <div className="adm-leader-current">
                {current ? (
                  <>
                    <span className="mc-avatar mc-avatar-lead adm-leader-avatar">{current[0]}</span>
                    <div className="adm-leader-name">
                      <div>{current}</div>
                      {relaxed && (
                        <div className="adm-leader-warn">
                          ⚠ Picked from relaxed pool (no strictly-eligible person)
                        </div>
                      )}
                    </div>
                  </>
                ) : (
                  <div className="adm-leader-empty">Not assigned</div>
                )}
              </div>

              <div className="adm-leader-actions">
                <button className="adm-btn adm-btn-primary adm-leader-pick" onClick={() => handlePick(scope)}>
                  🎲 {current ? "Re-pick" : "Pick"} random
                </button>
                <select
                  className="adm-input"
                  value={current || ""}
                  onChange={(e) => handleManual(scope, e.target.value)}
                >
                  <option value="">— manual override —</option>
                  {allInScope.map(p => (
                    <option key={p.name} value={p.name}>
                      {p.name}{eligible.find(e => e.name === p.name) ? "" : "  (ineligible)"}
                    </option>
                  ))}
                </select>
              </div>

              <div className="adm-leader-stats">
                <div>
                  <strong>{eligible.length}</strong>
                  <span>eligible</span>
                </div>
                <div>
                  <strong>{skipped}</strong>
                  <span>skipped</span>
                </div>
                <div>
                  <strong>{allInScope.length}</strong>
                  <span>in scope</span>
                </div>
              </div>

              {eligible.length > 0 && (
                <details className="adm-leader-details">
                  <summary>Pool ({eligible.length})</summary>
                  <div className="adm-leader-pool">
                    {eligible.map(p => (
                      <span key={p.name} className="adm-leader-chip">{p.name}</span>
                    ))}
                  </div>
                </details>
              )}
            </section>
          );
        })}
      </div>

      <section className="adm-leader-history">
        <h3>Recent assignments</h3>
        <div className="adm-history-grid">
          {recent.map(d => (
            <div key={d} className={`adm-history-day ${d === dateIso ? "is-active" : ""}`}>
              <div className="adm-history-date" onClick={() => setDateIso(d)}>{d}</div>
              {SCOPES.map(s => {
                const n = history[`${d}__${s}`];
                return (
                  <div key={s} className="adm-history-cell">
                    <span className="adm-history-scope">{s.replace("EMEA + APAC", "EU+AP")}</span>
                    <span className={`adm-history-name ${n ? "" : "is-empty"}`}>
                      {n || "—"}
                    </span>
                  </div>
                );
              })}
            </div>
          ))}
        </div>
      </section>
    </>
  );
}

window.AdminConsole = AdminConsole;
window.computeShiftFractions = computeFractions;
window.parseShiftTime = parseTime;
