// Meeting Detail — the control center, with three layout variants

const MEETING_TABS = [
  { id: "summary",     label: "Summary",     icon: "info" },
  { id: "participants",label: "Participants",icon: "users" },
  { id: "agenda",      label: "Agenda",      icon: "list" },
  { id: "minutes",     label: "Minutes",     icon: "file-text" },
];

// ============================================================
// MEETING DETAIL — wrapper that picks layout
// ============================================================
const MeetingDetail = ({ navigate, meetingId, layout, openPresent }) => {
  const liveMeeting = useLiveMeeting(meetingId);
  if (!liveMeeting) return <div className="page">Meeting not found.</div>;
  if (layout === "split") return <MeetingDetailSplit navigate={navigate} m={liveMeeting} openPresent={openPresent}/>;
  if (layout === "single") return <MeetingDetailSingle navigate={navigate} m={liveMeeting} openPresent={openPresent}/>;
  return <MeetingDetailTabbed navigate={navigate} m={liveMeeting} openPresent={openPresent}/>;
};

// Live state — local in-memory clone we mutate during the session
const liveStateCache = new Map();
const meetingLiveChannel = "BroadcastChannel" in window ? new BroadcastChannel("council-meeting-live") : null;
const liveMeetingStorageKey = (id) => `council-meeting-live:${id}`;

function loadStoredLiveMeeting(id) {
  try {
    const stored = window.localStorage.getItem(liveMeetingStorageKey(id));
    return stored ? JSON.parse(stored) : null;
  } catch {
    return null;
  }
}

function storeLiveMeeting(m) {
  const payload = JSON.stringify(m);
  window.localStorage.setItem(liveMeetingStorageKey(m.id), payload);
  meetingLiveChannel?.postMessage({ type: "meeting-live-update", id: m.id, meeting: JSON.parse(payload) });
  window.dispatchEvent(new CustomEvent("meeting-live-update", { detail: { id: m.id } }));
}

function syncLiveMeetingFromPayload(id, meeting) {
  if (meeting) {
    liveStateCache.set(id, meeting);
    return;
  }

  const stored = loadStoredLiveMeeting(id);
  if (stored) {
    liveStateCache.set(id, stored);
  }
}

function getLiveMeeting(id) {
  if (!liveStateCache.has(id)) {
    const stored = loadStoredLiveMeeting(id);
    if (stored) {
      liveStateCache.set(id, stored);
    }
  }

  return liveStateCache.get(id) || getMeeting(id);
}

function useLiveMeeting(id) {
  const [, setTick] = React.useState(0);
  const cached = liveStateCache.get(id);
  if (id && !cached) {
    const orig = loadStoredLiveMeeting(id) || getMeeting(id);
    if (orig) liveStateCache.set(id, JSON.parse(JSON.stringify(orig)));
  }
  const m = liveStateCache.get(id);
  if (!m) return null;
  m.__update = (fn) => {
    fn(m);
    setTick(t => t + 1);
    storeLiveMeeting(m);
  };

  React.useEffect(() => {
    const onLocalUpdate = (event) => {
      if (event.detail?.id === id) {
        syncLiveMeetingFromPayload(id);
        setTick(t => t + 1);
      }
    };
    const onStorage = (event) => {
      if (event.key === liveMeetingStorageKey(id)) {
        syncLiveMeetingFromPayload(id);
        setTick(t => t + 1);
      }
    };
    const onMessage = (event) => {
      if (event.data?.type === "meeting-live-update" && event.data.id === id) {
        syncLiveMeetingFromPayload(id, event.data.meeting);
        setTick(t => t + 1);
      }
    };

    window.addEventListener("meeting-live-update", onLocalUpdate);
    window.addEventListener("storage", onStorage);
    meetingLiveChannel?.addEventListener("message", onMessage);

    return () => {
      window.removeEventListener("meeting-live-update", onLocalUpdate);
      window.removeEventListener("storage", onStorage);
      meetingLiveChannel?.removeEventListener("message", onMessage);
    };
  }, [id]);

  return m;
}

// ============================================================
// Shared header & action strip
// ============================================================
const MeetingHeader = ({ navigate, m, openPresent }) => {
  const toast = useToast();
  const startMeeting = () => m.__update(x => { x.status = "In Progress"; toast("Meeting started", "success"); });
  const completeMeeting = () => m.__update(x => { x.status = "Completed"; toast("Meeting completed", "success"); });

  return (
    <div className="page__header" style={{ alignItems: "flex-start" }}>
      <div className="page__title-block">
        <div className="row" style={{ gap: 8, marginBottom: 6, flexWrap: "wrap" }}>
          <span className="badge badge--outline mono">{m.no}</span>
          <TypeBadge type={m.type}/>
          <StatusPill status={m.status}/>
          <span className="muted" style={{ fontSize: 12.5 }}>· {fmtDateTime(m.date)} · <Icon name="map-pin" size={11}/> {m.location}</span>
        </div>
        <h1 className="page__title">{m.title}</h1>
        {m.notes && <p className="page__subtitle">{m.notes}</p>}
      </div>
      <div className="page__actions">
        <button className="btn" onClick={() => navigate({ name: "meeting-edit", id: m.id })}><Icon name="edit" size={14}/> Edit</button>
        <button className="btn"><Icon name="download" size={14}/> Export minutes</button>
        {m.status === "Scheduled" || m.status === "Draft" ? (
          <button className="btn btn--success" onClick={startMeeting}><Icon name="play" size={13}/> Start meeting</button>
        ) : m.status === "In Progress" ? (
          <>
            <button className="btn" onClick={openPresent}><Icon name="presentation" size={14}/> Present mode</button>
            <button className="btn btn--primary" onClick={completeMeeting}><Icon name="check" size={14}/> Complete meeting</button>
          </>
        ) : null}
      </div>
    </div>
  );
};

// ============================================================
// SECTION CONTENT (reusable across layouts)
// ============================================================
const SummarySection = ({ m, navigate }) => {
  const resolutions = m.agenda.filter(a => a.resolutionId).map(a => getResolution(a.resolutionId));
  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12, marginBottom: 16 }}>
      <div className="stat"><div className="stat__label">Agenda items</div><div className="stat__value">{m.agenda.length}</div></div>
      <div className="stat"><div className="stat__label">Participants</div><div className="stat__value">{m.participantIds.length}</div></div>
      <div className="stat"><div className="stat__label">Resolutions</div><div className="stat__value">{resolutions.length}</div></div>
      <div className="stat"><div className="stat__label">Quorum</div><div className="stat__value" style={{ color: "var(--success)" }}>Yes</div><div className="stat__delta">7 of 12 needed</div></div>
    </div>
  );
};

const ParticipantsSection = ({ m }) => {
  const [presence, setPresence] = React.useState(() => {
    const out = {};
    m.participantIds.forEach(id => out[id] = m.status === "Completed" ? "present" : (Math.random() > 0.2 ? "present" : "absent"));
    return out;
  });
  const present = Object.values(presence).filter(s => s === "present").length;

  return (
    <div className="card">
      <div className="card__header">
        <h3 className="card__title">Attendance</h3>
        <span className="card__sub">{present} present · {m.participantIds.length - present} absent · Quorum: <span style={{ color: "var(--success)", fontWeight: 600 }}>Met</span></span>
        <div className="card__actions">
          <button className="btn btn--sm"><Icon name="plus" size={12}/> Add participant</button>
        </div>
      </div>
      <div className="card__body card__body--flush">
        <table className="tbl">
          <thead><tr>
            <th>Name</th><th style={{ width: 200 }}>Section</th><th style={{ width: 130 }}>Role</th><th style={{ width: 130 }}>Presence</th>
          </tr></thead>
          <tbody>
            {m.participantIds.map(id => {
              const p = getParticipant(id);
              const isPresent = presence[id] === "present";
              return (
                <tr key={id}>
                  <td><div className="row" style={{ gap: 10 }}><Avatar p={p}/><div className="tbl__primary">{p.name}</div></div></td>
                  <td className="muted" style={{ fontSize: 12.5 }}>{p.section}</td>
                  <td><span className="badge badge--neutral badge--sm">{p.role}</span></td>
                  <td>
                    <button className={`toggle-pill ${isPresent ? "toggle-pill--on" : ""}`}
                            onClick={() => setPresence({ ...presence, [id]: isPresent ? "absent" : "present" })}>
                      <span className="toggle-pill__dot"/>
                      {isPresent ? "Present" : "Absent"}
                    </button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
};

const MinutesSection = ({ m }) => {
  const resolutions = m.agenda.filter(a => a.resolutionId).map(a => getResolution(a.resolutionId));
  const [generalNotes, setGeneralNotes] = React.useState(m.minutes.generalNotes);
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      <div className="card">
        <div className="card__header">
          <h3 className="card__title">Meeting minutes</h3>
          <span className="card__sub">Auto-compiled from agenda activity</span>
          <div className="card__actions">
            <button className="btn btn--sm"><Icon name="download" size={12}/> Export PDF</button>
            <button className="btn btn--sm"><Icon name="download" size={12}/> Export DOCX</button>
          </div>
        </div>
        <div className="card__body" style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <div className="field">
            <label className="field__label">General meeting notes</label>
            <textarea className="textarea" rows={4} value={generalNotes} onChange={e => { setGeneralNotes(e.target.value); m.__update(x => x.minutes.generalNotes = e.target.value); }} placeholder="Opening, attendance, quorum confirmation, closing remarks…"/>
            <span className="field__hint">Auto-saved · last edited just now</span>
          </div>

          <div>
            <div style={{ fontSize: 12, fontWeight: 600, color: "var(--muted)", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 8 }}>Agenda activity</div>
            {m.agenda.length === 0 ? <Empty icon="list" title="No agenda items" text="Activity will be summarised here once items are added."/> : m.agenda.map((a, i) => {
              const p = getPaper(a.paperId);
              return (
                <div key={i} style={{ padding: "10px 0", borderTop: i === 0 ? "0" : "1px solid var(--border-soft)" }}>
                  <div className="row" style={{ gap: 8, marginBottom: 4 }}>
                    <span className="badge badge--neutral mono badge--sm">{i + 1}</span>
                    <span style={{ fontWeight: 500 }}>{p?.title}</span>
                    <span style={{ marginLeft: "auto" }}><StatusPill status={a.status}/></span>
                  </div>
                  {a.debateNotes && <div style={{ fontSize: 13, color: "var(--ink-soft)", marginLeft: 6, marginBottom: 4 }}>{a.debateNotes}</div>}
                  {a.vote && <div style={{ marginLeft: 6 }}><VoteResultPill vote={a.vote}/></div>}
                </div>
              );
            })}
          </div>

          {resolutions.length > 0 && (
            <div>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--muted)", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 8 }}>Resolutions passed</div>
              <ol style={{ margin: 0, paddingLeft: 18, fontSize: 13.5, lineHeight: 1.6 }}>
                {resolutions.map(r => <li key={r.id}><span className="mono muted" style={{ fontSize: 11.5 }}>{r.id}</span> · {r.summary}</li>)}
              </ol>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

// ============================================================
// AGENDA SECTION (the heart of the page)
// ============================================================
const AgendaSection = ({ m, openPresent }) => {
  const [activeIdx, setActiveIdx] = React.useState(() => {
    const i = m.agenda.findIndex(a => ["Debating", "Ready for vote"].includes(a.status));
    return i >= 0 ? i : 0;
  });
  const [showAddPaper, setShowAddPaper] = React.useState(false);
  const isLive = m.status === "In Progress";

  return (
    <div className="card">
      <div className="card__header">
        <h3 className="card__title">Agenda</h3>
        <span className="card__sub">{m.agenda.length} item{m.agenda.length === 1 ? "" : "s"} · Drag to reorder</span>
        <div className="card__actions">
          {isLive && <button className="btn btn--sm" onClick={openPresent}><Icon name="presentation" size={12}/> Present</button>}
          <button className="btn btn--sm" onClick={() => setShowAddPaper(true)}><Icon name="plus" size={12}/> Add council paper</button>
        </div>
      </div>
      <div className="card__body" style={{ background: "#fafbfc" }}>
        {m.agenda.length === 0 ? (
          <Empty icon="list" title="Agenda is empty"
                 text="Pick a submitted council paper to begin building this meeting's agenda."
                 action={<button className="btn btn--primary btn--sm" onClick={() => setShowAddPaper(true)}><Icon name="plus" size={12}/> Add council paper</button>}/>
        ) : m.agenda.map((a, i) => (
          <AgendaItemCard key={i} item={a} idx={i} m={m}
                          isActive={activeIdx === i}
                          onActivate={() => setActiveIdx(i)}
                          isLive={isLive}/>
        ))}
      </div>

      {showAddPaper && <AddPaperToAgendaModal m={m} onClose={() => setShowAddPaper(false)}/>}
    </div>
  );
};

const AgendaItemCard = ({ item, idx, m, isActive, onActivate, isLive }) => {
  const p = getPaper(item.paperId);
  const sub = getParticipant(p?.submittedBy);
  const resolution = item.resolutionId ? getResolution(item.resolutionId) : null;
  const expanded = isActive;
  const toast = useToast();

  const setStatus = (s) => m.__update(x => { x.agenda[idx].status = s; });
  const createResolution = () => m.__update(x => {
    const id = `R-${(89 + idx).toString().padStart(3, "0")}`;
    x.agenda[idx].resolutionId = id;
    x.agenda[idx].status = "Resolved";
    if (!getResolution(id)) {
      RESOLUTIONS.unshift({
        id, summary: p.title, text: `The Council resolves to ${p.title.toLowerCase()}.`,
        enforcingParty: p.section, paperId: p.id, meetingId: m.id,
        vote: x.agenda[idx].vote, passedDate: new Date().toISOString().slice(0,10),
      });
    }
    toast(`Resolution ${id} created`, "success");
  });

  return (
    <div className={`agenda-item ${isActive ? "agenda-item--active" : ""} ${item.status === "Resolved" ? "agenda-item--resolved" : ""}`}>
      <div className="agenda-item__head" onClick={onActivate}>
        <span className="drag-handle"></span>
        <div className="agenda-item__num">
          {item.status === "Resolved" ? <Icon name="check" size={13}/> : idx + 1}
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="agenda-item__title">{p?.title}</div>
          <div className="tbl__sub" style={{ display: "flex", gap: 8, alignItems: "center", marginTop: 2 }}>
            <span className="mono">{p?.id}</span>
            <span>·</span>
            <Avatar p={sub} size="sm"/>
            <span>{sub?.name}</span>
            <span>·</span>
            <span>{p?.section}</span>
            {p?.attachments?.length > 0 && <><span>·</span><span><Icon name="paperclip" size={11}/> {p.attachments.length}</span></>}
          </div>
        </div>
        <StatusPill status={item.status}/>
        {item.vote && <VoteResultPill vote={item.vote}/>}
        <Icon name={expanded ? "chevron-down" : "chevron-right"} size={14}/>
      </div>

      {expanded && (
        <div className="agenda-item__body">
          <div style={{ fontSize: 13, color: "var(--ink-soft)", lineHeight: 1.55, marginBottom: 14 }}>
            {p?.description}
          </div>

          {p?.attachments?.length > 0 && (
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 14 }}>
              {p.attachments.map((a, j) => <Attachment key={j} a={a}/>)}
            </div>
          )}

          {/* Live runtime controls */}
          <div style={{ background: "white", border: "1px solid var(--border)", borderRadius: 8, padding: 12, marginTop: 4 }}>
            <RuntimeControls item={item} idx={idx} m={m} isLive={isLive}
                             onStatus={setStatus} onResolve={createResolution}/>
          </div>

          {resolution && (
            <div style={{ marginTop: 12, padding: 12, background: "var(--success-bg)", border: "1px solid #aedcc1", borderRadius: 8 }}>
              <div className="row" style={{ gap: 8, marginBottom: 6 }}>
                <Icon name="gavel" size={14} style={{ color: "var(--success)" }}/>
                <strong>Resolution {resolution.id}</strong>
                <span className="badge badge--brand badge--sm" style={{ marginLeft: "auto" }}><Icon name="tag" size={10}/> {resolution.enforcingParty}</span>
              </div>
              <div style={{ fontSize: 13, fontFamily: "var(--font-serif)", lineHeight: 1.55 }}>{resolution.text}</div>
            </div>
          )}
        </div>
      )}
    </div>
  );
};

// Runtime controls — debate / vote / resolve
const RuntimeControls = ({ item, idx, m, isLive, onStatus, onResolve }) => {
  const [debateNote, setDebateNote] = React.useState(item.debateNotes);
  const votingParticipantIds = React.useMemo(() => {
    return m.participantIds.filter(participantId => getParticipant(participantId)?.role !== "Secretariat");
  }, [m.participantIds]);

  const [votesByParticipant, setVotesByParticipant] = React.useState(() => {
    const initial = {};
    item.vote?.responses?.forEach(response => {
      initial[response.participantId] = response.choice;
    });
    return initial;
  });

  const voteSummary = React.useMemo(() => {
    return votingParticipantIds.reduce((summary, participantId) => {
      const choice = votesByParticipant[participantId];
      if (choice === "for") summary.for += 1;
      if (choice === "against") summary.against += 1;
      if (choice === "abstain") summary.abstain += 1;
      return summary;
    }, { for: 0, against: 0, abstain: 0 });
  }, [votingParticipantIds, votesByParticipant]);

  const recordedVotes = voteSummary.for + voteSummary.against + voteSummary.abstain;
  const allVotesRecorded = recordedVotes === votingParticipantIds.length;

  const buildVote = (choices) => {
    const summary = votingParticipantIds.reduce((result, participantId) => {
      const choice = choices[participantId];
      if (choice === "for") result.for += 1;
      if (choice === "against") result.against += 1;
      if (choice === "abstain") result.abstain += 1;
      return result;
    }, { for: 0, against: 0, abstain: 0 });

    return {
      ...summary,
      responses: votingParticipantIds
        .filter(participantId => choices[participantId])
        .map(participantId => ({
          participantId,
          choice: choices[participantId],
        })),
    };
  };

  const submitVotes = (choices) => {
    const vote = buildVote(choices);

    m.__update(x => {
      x.agenda[idx].vote = vote;
      x.agenda[idx].status = vote.responses.length === votingParticipantIds.length ? "Voted" : "Ready for vote";
    });
  };

  const setParticipantVote = (participantId, choice) => {
    const next = {
      ...votesByParticipant,
      [participantId]: choice,
    };

    setVotesByParticipant(next);
    submitVotes(next);
  };

  const markRemainingAbstain = () => {
    const next = { ...votesByParticipant };

    votingParticipantIds.forEach(participantId => {
      if (!next[participantId]) {
        next[participantId] = "abstain";
      }
    });

    setVotesByParticipant(next);
    submitVotes(next);
  };

  const blocked = !isLive && item.status === "Pending debate";

  if (item.status === "Resolved") {
    return (
      <div className="row" style={{ gap: 10, color: "var(--success)" }}>
        <Icon name="check-circle" size={16}/>
        <strong>This item has been resolved.</strong>
        <span className="muted" style={{ fontSize: 12 }}>Voted: For {item.vote?.for} · Against {item.vote?.against} · Abstain {item.vote?.abstain}</span>
      </div>
    );
  }

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      {blocked && (
        <div className="row" style={{ gap: 8, padding: 8, background: "var(--bg-sunken)", borderRadius: 6, fontSize: 12.5, color: "var(--muted)" }}>
          <Icon name="lock" size={12}/>
          Start the meeting to enable debate and voting controls.
        </div>
      )}

      {/* Step 1: Debate */}
      <div>
        <div className="row" style={{ gap: 8, marginBottom: 6 }}>
          <span style={{ fontSize: 11.5, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em", color: "var(--muted)" }}>1 · Debate</span>
          {item.status === "Pending debate" && (
            <button className="btn btn--sm" disabled={blocked} onClick={() => onStatus("Debating")}>
              <Icon name="play" size={12}/> Open debate
            </button>
          )}
          {item.status === "Debating" && (
            <span className="badge badge--warning badge--dot">Debating now</span>
          )}
        </div>
        <textarea className="textarea" rows={2} placeholder="Capture key debate points…"
                  value={debateNote}
                  onChange={e => { setDebateNote(e.target.value); m.__update(x => x.agenda[idx].debateNotes = e.target.value); }}/>
      </div>

      {/* Step 2: Vote */}
      <div>
        <div className="row" style={{ gap: 8, marginBottom: 6 }}>
          <span style={{ fontSize: 11.5, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em", color: "var(--muted)" }}>2 · Vote</span>
          {item.status === "Debating" && (
            <button className="btn btn--sm" onClick={() => onStatus("Ready for vote")}><Icon name="vote" size={12}/> Move to vote</button>
          )}
        </div>
        <div className="vote-rollcall">
          <div className="vote-rollcall__summary">
            <span className="vote-summary__seg vote-summary__seg--for">For {voteSummary.for}</span>
            <span className="vote-summary__seg vote-summary__seg--against">Against {voteSummary.against}</span>
            <span className="vote-summary__seg vote-summary__seg--abstain">Abstain {voteSummary.abstain}</span>
          </div>

          <div className="vote-rollcall__list">
            {votingParticipantIds.map(participantId => {
              const participant = getParticipant(participantId);
              return (
                <ParticipantVoteRow
                  key={participantId}
                  participant={participant}
                  choice={votesByParticipant[participantId]}
                  disabled={!["Ready for vote", "Voted"].includes(item.status) || !isLive}
                  onChange={choice => setParticipantVote(participantId, choice)}
                />
              );
            })}
          </div>
        </div>
        <div className="row" style={{ marginTop: 8, gap: 8 }}>
          <span className="muted" style={{ fontSize: 12 }}>
            {recordedVotes} of {votingParticipantIds.length} votes submitted live
          </span>
          {["Ready for vote", "Voted"].includes(item.status) && (
            <button className="btn btn--sm" disabled={!isLive || allVotesRecorded} onClick={markRemainingAbstain}>
              Mark remaining abstain
            </button>
          )}
          <span className="muted" style={{ marginLeft: "auto", fontSize: 12 }}>
            {allVotesRecorded ? "Voting complete" : "Selections submit immediately"}
          </span>
        </div>
      </div>

      {/* Step 3: Resolution */}
      <div>
        <div className="row" style={{ gap: 8, marginBottom: 6 }}>
          <span style={{ fontSize: 11.5, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em", color: "var(--muted)" }}>3 · Resolution</span>
          {item.status === "Voted" && item.vote?.for > item.vote?.against && (
            <button className="btn btn--sm btn--success" onClick={onResolve}><Icon name="gavel" size={12}/> Create resolution</button>
          )}
          {item.status === "Voted" && item.vote?.for <= item.vote?.against && (
            <span className="badge badge--danger badge--dot">Rejected — no resolution</span>
          )}
          {item.status !== "Voted" && (
            <span className="muted" style={{ fontSize: 12 }}>Available after vote is recorded</span>
          )}
        </div>
      </div>
    </div>
  );
};

const ParticipantVoteRow = ({ participant, choice, disabled, onChange }) => {
  return (
    <div className="vote-rollcall__row">
      <div className="vote-rollcall__person">
        <Avatar p={participant} size="sm"/>
        <div>
          <div className="vote-rollcall__name">{participant?.name}</div>
          <div className="vote-rollcall__meta">{participant?.role} · {participant?.section}</div>
        </div>
      </div>
      <div className="vote-rollcall__choices">
        {[
          ["for", "For", "success"],
          ["against", "Against", "danger"],
          ["abstain", "Abstain", "neutral"],
        ].map(([value, label, tone]) => (
          <button
            key={value}
            type="button"
            disabled={disabled}
            className={`vote-choice vote-choice--${tone} ${choice === value ? "vote-choice--active" : ""}`}
            onClick={() => onChange(value)}
          >
            {label}
          </button>
        ))}
      </div>
    </div>
  );
};

// Add paper to agenda dialog
const AddPaperToAgendaModal = ({ m, onClose }) => {
  const eligible = PAPERS.filter(p => p.status === "Submitted" && !m.agenda.some(a => a.paperId === p.id));
  const [chosen, setChosen] = React.useState(new Set());
  const toast = useToast();
  return (
    <Modal title="Add council paper to agenda" size="lg" onClose={onClose}
      footer={<>
        <span className="muted" style={{ marginRight: "auto", fontSize: 12.5 }}>{chosen.size} selected</span>
        <button className="btn" onClick={onClose}>Cancel</button>
        <button className="btn btn--primary" disabled={chosen.size === 0} onClick={() => {
          m.__update(x => {
            chosen.forEach(id => x.agenda.push({ paperId: id, status: "Pending debate", debateNotes: "", vote: null, resolutionId: null }));
          });
          toast(`${chosen.size} paper${chosen.size === 1 ? "" : "s"} added to agenda`, "success");
          onClose();
        }}>
          Add {chosen.size || ""} to agenda
        </button>
      </>}
    >
      {eligible.length === 0 ? (
        <Empty icon="file-text" title="No eligible papers" text="All submitted papers are already on this agenda."/>
      ) : (
        <div style={{ maxHeight: 400, overflow: "auto", border: "1px solid var(--border)", borderRadius: 6 }}>
          <table className="tbl">
            <tbody>
              {eligible.map(p => (
                <tr key={p.id} onClick={() => {
                  const next = new Set(chosen);
                  next.has(p.id) ? next.delete(p.id) : next.add(p.id);
                  setChosen(next);
                }}>
                  <td style={{ width: 32 }}><input type="checkbox" checked={chosen.has(p.id)} readOnly/></td>
                  <td>
                    <div className="row" style={{ gap: 6, marginBottom: 2 }}>
                      <span className="badge badge--outline mono badge--sm">{p.id}</span>
                      <span className="muted" style={{ fontSize: 11.5 }}>{p.section}</span>
                    </div>
                    <div className="tbl__primary">{p.title}</div>
                    <div className="tbl__sub" style={{ maxWidth: 540, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{p.description}</div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </Modal>
  );
};

// ============================================================
// LAYOUT 1 — Tabbed (default)
// ============================================================
const MeetingDetailTabbed = ({ navigate, m, openPresent }) => {
  const [tab, setTab] = React.useState("agenda");
  return (
    <div className="page" data-screen-label={`Meeting ${m.no}`}>
      <MeetingHeader navigate={navigate} m={m} openPresent={openPresent}/>
      <div className="subnav">
        {MEETING_TABS.map(t => (
          <button key={t.id} className={`tab ${tab === t.id ? "tab--active" : ""}`} onClick={() => setTab(t.id)}>
            <Icon name={t.icon} size={13}/> {t.label}
          </button>
        ))}
      </div>
      {tab === "summary" && <><SummarySection m={m} navigate={navigate}/><MeetingSummaryDetails m={m}/></>}
      {tab === "participants" && <ParticipantsSection m={m}/>}
      {tab === "agenda" && <AgendaSection m={m} openPresent={openPresent}/>}
      {tab === "minutes" && <MinutesSection m={m}/>}
    </div>
  );
};

// ============================================================
// LAYOUT 2 — Single column (long scroll, all sections stacked)
// ============================================================
const MeetingDetailSingle = ({ navigate, m, openPresent }) => {
  return (
    <div className="page" data-screen-label={`Meeting ${m.no}`}>
      <MeetingHeader navigate={navigate} m={m} openPresent={openPresent}/>
      <SummarySection m={m} navigate={navigate}/>
      <h2 style={{ fontSize: 16, margin: "12px 0 10px" }}>Participants</h2>
      <ParticipantsSection m={m}/>
      <h2 style={{ fontSize: 16, margin: "20px 0 10px" }}>Agenda</h2>
      <AgendaSection m={m} openPresent={openPresent}/>
      <h2 style={{ fontSize: 16, margin: "20px 0 10px" }}>Minutes</h2>
      <MinutesSection m={m}/>
    </div>
  );
};

// ============================================================
// LAYOUT 3 — Split pane (agenda left, sidebar right)
// ============================================================
const MeetingDetailSplit = ({ navigate, m, openPresent }) => {
  return (
    <div className="page" data-screen-label={`Meeting ${m.no}`}>
      <MeetingHeader navigate={navigate} m={m} openPresent={openPresent}/>
      <SummarySection m={m} navigate={navigate}/>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 380px", gap: 16, alignItems: "flex-start" }}>
        <AgendaSection m={m} openPresent={openPresent}/>
        <div style={{ display: "flex", flexDirection: "column", gap: 16, position: "sticky", top: 72 }}>
          <ParticipantsSection m={m}/>
          <MeetingSummaryDetails m={m}/>
        </div>
      </div>
      <div style={{ marginTop: 20 }}>
        <h2 style={{ fontSize: 16, margin: "0 0 10px" }}>Minutes</h2>
        <MinutesSection m={m}/>
      </div>
    </div>
  );
};

const MeetingSummaryDetails = ({ m }) => (
  <div className="card">
    <div className="card__header"><h3 className="card__title">Meeting details</h3></div>
    <div className="card__body" style={{ display: "flex", flexDirection: "column", gap: 12, fontSize: 13 }}>
      <DetailRow label="Meeting #" value={<span className="mono">{m.no}</span>}/>
      <DetailRow label="Type" value={<TypeBadge type={m.type}/>}/>
      <DetailRow label="Date & time" value={fmtDateTime(m.date)}/>
      <DetailRow label="Location" value={m.location}/>
      <DetailRow label="Status" value={<StatusPill status={m.status}/>}/>
      {m.notes && <DetailRow label="Notes" value={<span style={{ fontSize: 13, color: "var(--ink-soft)" }}>{m.notes}</span>}/>}
    </div>
  </div>
);

// ============================================================
// PRESENT MODE — fullscreen, projection-friendly
// ============================================================
const PresentMode = ({ m, onClose }) => {
  const [, setTick] = React.useState(0);
  const liveMeeting = getLiveMeeting(m.id) || m;
  const initialIdx = Math.max(0, liveMeeting.agenda.findIndex(a => ["Debating","Ready for vote","Pending debate"].includes(a.status)));
  const [idx, setIdx] = React.useState(initialIdx >= 0 ? initialIdx : 0);
  const item = liveMeeting.agenda[idx];
  const p = item ? getPaper(item.paperId) : null;
  const sub = p ? getParticipant(p.submittedBy) : null;

  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowRight") setIdx(i => Math.min(liveMeeting.agenda.length - 1, i + 1));
      if (e.key === "ArrowLeft") setIdx(i => Math.max(0, i - 1));
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [liveMeeting.agenda.length, onClose]);

  React.useEffect(() => {
    const onLiveUpdate = (event) => {
      if (event.detail?.id === m.id) {
        syncLiveMeetingFromPayload(m.id);
        setTick(t => t + 1);
      }
    };
    const onStorage = (event) => {
      if (event.key === liveMeetingStorageKey(m.id)) {
        syncLiveMeetingFromPayload(m.id);
        setTick(t => t + 1);
      }
    };
    const onMessage = (event) => {
      if (event.data?.type === "meeting-live-update" && event.data.id === m.id) {
        syncLiveMeetingFromPayload(m.id, event.data.meeting);
        setTick(t => t + 1);
      }
    };

    window.addEventListener("meeting-live-update", onLiveUpdate);
    window.addEventListener("storage", onStorage);
    meetingLiveChannel?.addEventListener("message", onMessage);

    return () => {
      window.removeEventListener("meeting-live-update", onLiveUpdate);
      window.removeEventListener("storage", onStorage);
      meetingLiveChannel?.removeEventListener("message", onMessage);
    };
  }, [m.id]);

  if (!item) return null;
  const total = liveMeeting.agenda.length;
  const votingParticipantIds = liveMeeting.participantIds.filter(participantId => getParticipant(participantId)?.role !== "Secretariat");
  const voteResponses = item.vote?.responses ?? [];
  const voteGroups = {
    for: voteResponses.filter(response => response.choice === "for").map(response => getParticipant(response.participantId)).filter(Boolean),
    against: voteResponses.filter(response => response.choice === "against").map(response => getParticipant(response.participantId)).filter(Boolean),
    abstain: voteResponses.filter(response => response.choice === "abstain").map(response => getParticipant(response.participantId)).filter(Boolean),
  };
  const submittedVotes = voteResponses.length;
  const votePercent = votingParticipantIds.length ? Math.round((submittedVotes / votingParticipantIds.length) * 100) : 0;
  const voteOutcome = item.vote
    ? item.vote.for > item.vote.against
      ? "Motion leading"
      : item.vote.for < item.vote.against
        ? "Motion trailing"
        : "Tied"
    : "Awaiting votes";

  return (
    <div className="present">
      <div className="present__topbar">
        <span className="present__title">{liveMeeting.title}</span>
        <span className="present__meta">{liveMeeting.no} · {fmtDateTime(liveMeeting.date)} · {liveMeeting.location}</span>
        <div style={{ flex: 1 }}/>
        <span className="present__meta">{idx + 1} / {total}</span>
        <button className="btn btn--ghost present__close" style={{ color: "white", borderColor: "rgba(255,255,255,0.2)" }} onClick={onClose}>
          <Icon name="x" size={14}/> Exit present
        </button>
      </div>

      <div className="present__body">
        <div className="present__card">
          <div className="present__num">Agenda item {idx + 1} of {total} · {p.id} · {p.section}</div>
          <h2 className="present__paper-title">{p.title}</h2>
          <p className="present__paper-desc">{p.description}</p>

          <div style={{ marginTop: 28, display: "flex", gap: 12, flexWrap: "wrap" }}>
            <span className="badge badge--neutral" style={{ background: "rgba(255,255,255,0.06)", color: "#c8d2e3", border: "1px solid rgba(255,255,255,0.12)" }}>
              <Icon name="users" size={11}/> Submitted by {sub?.name}
            </span>
            <span className="badge badge--neutral" style={{ background: "rgba(255,255,255,0.06)", color: "#c8d2e3", border: "1px solid rgba(255,255,255,0.12)" }}>
              <StatusPill status={item.status} dot={false}/>
            </span>
            {p.attachments?.length > 0 && (
              <span className="badge badge--neutral" style={{ background: "rgba(255,255,255,0.06)", color: "#c8d2e3", border: "1px solid rgba(255,255,255,0.12)" }}>
                <Icon name="paperclip" size={11}/> {p.attachments.length} attachment{p.attachments.length === 1 ? "" : "s"}
              </span>
            )}
          </div>

          {(item.status === "Ready for vote" || item.status === "Voted" || item.status === "Resolved") && (
            <div className="present__vote-board">
              <div className="present__vote-head">
                <div>
                  <div className="present__vote-kicker">Live vote</div>
                  <div className="present__vote-outcome">{voteOutcome}</div>
                </div>
                <div className="present__vote-progress">
                  <span>{submittedVotes} of {votingParticipantIds.length} submitted</span>
                  <div className="present__vote-progress-track">
                    <div className="present__vote-progress-fill" style={{ width: `${votePercent}%` }}/>
                  </div>
                </div>
              </div>

              <div className="present__vote">
                <PresentVoteColumn label="For" count={item.vote?.for ?? 0} members={voteGroups.for} tone="for"/>
                <PresentVoteColumn label="Against" count={item.vote?.against ?? 0} members={voteGroups.against} tone="against"/>
                <PresentVoteColumn label="Abstain" count={item.vote?.abstain ?? 0} members={voteGroups.abstain} tone="abstain"/>
              </div>
            </div>
          )}
        </div>
      </div>

      <div className="present__footer">
        <button className="btn btn--ghost" style={{ color: "white", borderColor: "rgba(255,255,255,0.2)" }} onClick={() => setIdx(i => Math.max(0, i - 1))}>
          <Icon name="chevron-left" size={14}/> Previous
        </button>
        <div className="present__progress">
          <div className="present__progress-track">
            <div className="present__progress-fill" style={{ width: `${((idx+1)/total)*100}%` }}/>
          </div>
        </div>
        <span style={{ fontSize: 12 }}>Use ← → to navigate · Esc to exit</span>
        <button className="btn btn--ghost" style={{ color: "white", borderColor: "rgba(255,255,255,0.2)" }} onClick={() => setIdx(i => Math.min(total - 1, i + 1))}>
          Next <Icon name="chevron-right" size={14}/>
        </button>
      </div>
    </div>
  );
};

const PresentVoteColumn = ({ label, count, members, tone }) => (
  <div className={`present__vote-cell present__vote-cell--${tone}`}>
    <div className="present__vote-label">{label}</div>
    <div className="present__vote-count">{count}</div>
    <div className="present__vote-members">
      {members.length === 0 ? (
        <div className="present__vote-empty">No votes yet</div>
      ) : members.map(member => (
        <div key={member.id} className="present__vote-member">
          <span>{member.name}</span>
          <small>{member.section}</small>
        </div>
      ))}
    </div>
  </div>
);

Object.assign(window, { MeetingDetail, PresentMode, getLiveMeeting });
