/* P.E.S.T Web App — Votes (custom polls, quorum, %, runtime, past votes) */
function voteTotals(v) {
  const total = Object.values(v.tally || {}).reduce((a, b) => a + b, 0);
  return total;
}
function fmtLeft(ms) {
  if (ms <= 0) return "ended";
  const d = Math.floor(ms / 86400000);
  const h = Math.floor((ms % 86400000) / 3600000);
  if (d > 0) return d + "d " + h + "h left";
  const m = Math.floor((ms % 3600000) / 60000);
  return h + "h " + m + "m left";
}
function voteOutcome(v, eligible) {
  const total = voteTotals(v);
  const quorum = total >= v.threshold;
  let winner = null, max = -1;
  v.options.forEach((o) => { const c = v.tally[o.id] || 0; if (c > max) { max = c; winner = o; } });
  const passed = quorum && winner && winner.id === v.options[0].id;
  return { total, quorum, winner, passed };
}

function VoteCard({ v }) {
  const store = useStore();
  const eligible = store.members.length;
  const total = voteTotals(v);
  const myChoice = store.myVotes[v.id];
  const expired = v.closed || v.endsAt <= Date.now();
  const revealed = !!myChoice || expired;
  const out = voteOutcome(v, eligible);

  const stateChip = v.closed || expired
    ? (out.passed ? <span className="vc-state passed">Passed</span> : <span className="vc-state failed">{out.quorum ? "Rejected" : "No quorum"}</span>)
    : <span className="vc-state live">● Live</span>;

  const cast = (optId) => {
    if (revealed) return;
    store.castVote(v.id, optId);
    toast("Vote cast");
  };

  return (
    <div className="card vote-card cut">
      <div className="vc-head">
        <div style={{ minWidth: 0 }}>
          <h3>{v.title}</h3>
          <div className="vc-desc">{v.desc}</div>
        </div>
        {stateChip}
      </div>

      <div className="vc-meta">
        <span><b>{total}</b> / {eligible} votes</span>
        <span>Threshold <b>{v.threshold}</b></span>
        <span><window.AIcon.clock style={{ width: 12, height: 12, verticalAlign: -2 }} /> {v.closed || expired ? "Ended " + window.timeAgo(v.endsAt) : fmtLeft(v.endsAt - Date.now())}</span>
      </div>

      <div className="vc-quorum">
        <div className="quorum-bar">
          <div className="qf" style={{ width: Math.min(100, (total / eligible) * 100) + "%" }}></div>
          <div className="qt" style={{ left: Math.min(100, (v.threshold / eligible) * 100) + "%" }}></div>
        </div>
        <div className="quorum-row">
          <span>Quorum {out.quorum ? "reached" : "not reached"}</span>
          <span><b>{Math.round((total / eligible) * 100)}%</b> turnout</span>
        </div>
      </div>

      <div className="vc-options">
        {v.options.map((o) => {
          const c = v.tally[o.id] || 0;
          const pct = total > 0 ? Math.round((c / total) * 100) : 0;
          const chosen = myChoice === o.id;
          const isWinner = revealed && out.winner && out.winner.id === o.id;
          return (
            <button key={o.id} className={"vc-opt" + (chosen ? " chosen" : "")} onClick={() => cast(o.id)} disabled={revealed}>
              {revealed && <span className="fill" style={{ width: pct + "%" }}></span>}
              <span className="vo-row">
                <span className="vo-label">
                  {revealed ? (isWinner ? <window.AIcon.check style={{ width: 15, height: 15, color: "var(--c-cyan)" }} /> : null) : <window.AIcon.vote style={{ width: 15, height: 15 }} />}
                  {o.label}{chosen && <span className="vo-votes">· your vote</span>}
                </span>
                {revealed
                  ? <span className="vo-pct">{pct}% <span className="vo-votes">({c})</span></span>
                  : <span className="vo-votes">vote</span>}
              </span>
            </button>
          );
        })}
      </div>

      <div className="vote-foot">
        {revealed
          ? (myChoice ? <span className="voted-tag"><window.AIcon.check /> You voted · {v.options.find((o) => o.id === myChoice)?.label}</span> : <span className="vo-votes" style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--tx-faint)" }}>Voting closed</span>)
          : <span className="vo-votes" style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--tx-faint)" }}>Pick an option to cast your vote</span>}
        {store.user.isAdmin && !v.closed && (
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn btn-sm btn-ghost" onClick={() => { store.closeVote(v.id); toast("Vote closed"); }}>Close</button>
            <button className="btn btn-sm btn-danger" onClick={() => { if (confirm("Delete this vote?")) { store.deleteVote(v.id); toast("Vote deleted"); } }}><window.AIcon.trash /></button>
          </div>
        )}
      </div>
    </div>
  );
}

function Votes() {
  const store = useStore();
  const [tab, setTab] = useState("active");
  const [creating, setCreating] = useState(false);
  const now = Date.now();
  const active = store.votes.filter((v) => !v.closed && v.endsAt > now);
  const past = store.votes.filter((v) => v.closed || v.endsAt <= now);
  const list = tab === "active" ? active : past;

  return (
    <div>
      <div className="page-head">
        <div className="eyebrow">Governance</div>
        <h1>Hive <span className="grad-text">votes</span></h1>
        <p className="sub">Custom polls decided by the Core. One vote per member · {store.members.length} eligible voters.</p>
      </div>

      <div className="vote-tabs">
        <button className={"chip" + (tab === "active" ? " on" : "")} onClick={() => setTab("active")}>Active · {active.length}</button>
        <button className={"chip" + (tab === "past" ? " on" : "")} onClick={() => setTab("past")}>Past · {past.length}</button>
        <div style={{ flex: 1 }}></div>
        {store.user.isAdmin && <button className="btn btn-sm btn-primary" onClick={() => setCreating(true)}><window.AIcon.plus /> New vote</button>}
      </div>

      {list.length === 0
        ? <div className="empty-note">No {tab} votes.</div>
        : <div className="vote-list">{list.map((v) => <VoteCard key={v.id} v={v} />)}</div>}

      {creating && <CreateVoteModal onClose={() => setCreating(false)} />}
    </div>
  );
}

function CreateVoteModal({ onClose }) {
  const store = useStore();
  const [title, setTitle] = useState("");
  const [desc, setDesc] = useState("");
  const [options, setOptions] = useState(["Approve", "Reject"]);
  const [threshold, setThreshold] = useState(Math.ceil(store.members.length / 2) + 1);
  const [days, setDays] = useState(3);

  useEffect(() => {
    const k = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", k);
    return () => window.removeEventListener("keydown", k);
  }, []);

  const setOpt = (i, val) => setOptions((o) => o.map((x, k) => k === i ? val : x));
  const addOpt = () => setOptions((o) => o.length < 6 ? [...o, ""] : o);
  const delOpt = (i) => setOptions((o) => o.length > 2 ? o.filter((_, k) => k !== i) : o);

  const save = () => {
    if (!title.trim()) { toast("Add a title", "err"); return; }
    const opts = options.map((l) => l.trim()).filter(Boolean);
    if (opts.length < 2) { toast("Add at least 2 options", "err"); return; }
    const id = title.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 24) + "-" + Math.random().toString(36).slice(2, 5);
    const vote = {
      id, title: title.trim(), desc: desc.trim(),
      options: opts.map((l, i) => ({ id: "o" + i + "-" + Math.random().toString(36).slice(2, 5), label: l })),
      tally: {}, threshold: Number(threshold) || 1,
      createdAt: Date.now(), endsAt: Date.now() + (Number(days) || 1) * 86400000, closed: false,
    };
    store.addVote(vote);
    toast("Vote created");
    onClose();
  };

  return (
    <div className="modal-back" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>New vote</h3>
          <button className="icon-x" onClick={onClose}><window.AIcon.close /></button>
        </div>
        <div className="modal-body">
          <div className="form-row">
            <div className="field"><label>Title</label><input className="input" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="What are we deciding?" /></div>
            <div className="field"><label>Description</label><textarea className="input" value={desc} onChange={(e) => setDesc(e.target.value)} placeholder="Context for voters." /></div>
            <div className="field">
              <label>Options</label>
              <div className="opt-builder">
                {options.map((o, i) => (
                  <div className="opt-builder-row" key={i}>
                    <input className="input" value={o} onChange={(e) => setOpt(i, e.target.value)} placeholder={"Option " + (i + 1)} />
                    <button className="del" onClick={() => delOpt(i)} disabled={options.length <= 2} title="Remove"><window.AIcon.close /></button>
                  </div>
                ))}
                {options.length < 6 && <button className="btn btn-sm btn-ghost" onClick={addOpt}><window.AIcon.plus /> Add option</button>}
              </div>
            </div>
            <div className="form-2">
              <div className="field"><label>Threshold (votes)</label><input className="input mono" type="number" min="1" max={store.members.length} value={threshold} onChange={(e) => setThreshold(e.target.value)} /></div>
              <div className="field"><label>Runtime (days)</label><input className="input mono" type="number" min="1" max="60" value={days} onChange={(e) => setDays(e.target.value)} /></div>
            </div>
            <div className="form-actions">
              <button className="btn btn-primary btn-block" onClick={save}><window.AIcon.check /> Create vote</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

window.Votes = Votes;
