// Notes & actions — every comment written on every brand, in one list.
// Who said what, on which brand, when, and what the next action is.
//
// Anything here can be cleared: an action is marked "done", a plain comment is
// marked "reviewed". Both move it out of Open, so the list is a real worklist
// rather than an ever-growing archive.

function NotesPage({ brands, currentUser, onUpdateBrand, onNavigate, onToast }) {
  const me = resolveTeamName(currentUser);
  const author = displayNameFor(currentUser);

  const [q,           setQ]           = usePersistentState('notes.q', '');
  const [status,      setStatus]      = usePersistentState('notes.status', 'open');   // open | cleared | all
  const [kind,        setKind]        = usePersistentState('notes.kind', 'all');      // all | actions | comments
  const [mine,        setMine]        = usePersistentState('notes.mine', false);
  const [author_,     setAuthorF]     = usePersistentState('notes.author', 'all');
  const [brandFilter, setBrandFilter] = usePersistentState('notes.brand', 'all');
  // Where the note came from. A bulk Excel import lands hundreds of historical
  // comments in the same list as this morning's notes; filtering by source lets
  // you clear the backlog in one go without touching hand-written notes.
  const [source,      setSource]      = usePersistentState('notes.source', 'all');
  const [confirm, confirmEl] = useConfirm();

  const all = React.useMemo(() => collectNotes(brands), [brands]);

  const authors = React.useMemo(
    // Grouped by the DISPLAYED name, so a note stored against an email and one
    // stored against the same person's name are one entry, not two.
    () => [...new Set(all.map((n) => authorLabel(n.author)).filter(Boolean))].sort(), [all]
  );
  const brandOptions = React.useMemo(
    () => [...new Set(all.map((n) => n.brandName).filter(Boolean))].sort(), [all]
  );

  const openItems   = all.filter((n) => !n.cleared);
  const openActions = openItems.filter((n) => n.isAction);

  const isMine = (n) => !!me && (
    authorLabel(n.author).toLowerCase() === me.toLowerCase() ||
    authorLabel(n.author).toLowerCase() === String(author).toLowerCase() ||
    n.actionOwner.toLowerCase() === me.toLowerCase() ||
    n.mentions.some((m) => m.toLowerCase() === me.toLowerCase())
  );

  const filtered = React.useMemo(() => {
    const s = q.trim().toLowerCase();
    return all.filter((n) => {
      if (status === 'open' && n.cleared) return false;
      if (status === 'cleared' && !n.cleared) return false;
      if (kind === 'actions' && !n.isAction) return false;
      if (kind === 'comments' && n.isAction) return false;
      if (mine && !isMine(n)) return false;
      if (author_ !== 'all' && authorLabel(n.author) !== author_) return false;
      if (source !== 'all' && n.source !== source) return false;
      if (brandFilter !== 'all' && n.brandName !== brandFilter) return false;
      if (s && !(
        n.text.toLowerCase().includes(s) ||
        n.brandName.toLowerCase().includes(s) ||
        authorLabel(n.author).toLowerCase().includes(s)
      )) return false;
      return true;
    });
  }, [all, q, status, kind, mine, author_, source, brandFilter, me, author]);

  // Clearing writes the whole notes array back for that brand, so batch by
  // brand rather than firing one save per note.
  const applyCleared = (rows, clear) => {
    const byBrand = new Map();
    rows.forEach((r) => {
      if (!!r.cleared === clear) return;                 // already in the target state
      if (!byBrand.has(r.brandId)) byBrand.set(r.brandId, []);
      byBrand.get(r.brandId).push(r.createdAt);
    });
    let touched = 0;
    byBrand.forEach((stamps, brandId) => {
      const brand = (brands || []).find((b) => b.id === brandId);
      if (!brand) return;
      let notes = Array.isArray(brand.notes) ? brand.notes : [];
      stamps.forEach((createdAt) => {
        notes = toggleNoteCleared(notes, createdAt, author);
        touched += 1;
      });
      onUpdateBrand(brandId, { notes });
    });
    return touched;
  };

  const toggleOne = (row) => {
    applyCleared([row], !row.cleared);
    const word = row.isAction ? 'action' : 'note';
    onToast && onToast(row.cleared ? `Re-opened this ${word}` : `Marked this ${word} ${row.isAction ? 'done' : 'reviewed'}`);
  };

  const clearAllShown = async () => {
    const target = filtered.filter((n) => !n.cleared);
    if (!target.length) { onToast && onToast('Nothing left to clear here'); return; }
    const srcLabel = source === 'all'
      ? null
      : (NOTE_SOURCES.find((s) => s.value === source) || {}).label;
    const actions = target.filter((n) => n.isAction).length;
    const ok = await confirm({
      title: `Clear ${target.length} item${target.length === 1 ? '' : 's'}?`,
      message: [
        srcLabel
          ? `Every open note currently listed — ${srcLabel.toLowerCase()} — is marked done or reviewed and moves out of Open.`
          : 'Everything currently listed is marked done or reviewed and moves out of Open.',
        actions ? `${actions} of them ${actions === 1 ? 'is an open action' : 'are open actions'}, not just a comment.` : '',
        'You can re-open any of it from the Cleared tab.',
      ].filter(Boolean).join(' '),
      confirmLabel: `Clear ${target.length}`,
    });
    if (!ok) return;
    const n = applyCleared(target, true);
    onToast && onToast(`Cleared ${n} item${n === 1 ? '' : 's'}`);
  };

  const exportCsv = () => {
    if (!filtered.length) { onToast && onToast('Nothing to export'); return; }
    downloadCsv(`ipsem-notes-${ipsemToday()}.csv`, filtered.map((n) => ({
      Date: n.createdAt ? String(n.createdAt).slice(0, 10) : '',
      Brand: n.brandName,
      Category: n.brandCategory,
      Tier: n.priority || '',
      Author: authorLabel(n.author),
      Source: (NOTE_SOURCES.find((s) => s.value === n.source) || {}).label || n.source,
      Note: n.text,
      Mentions: n.mentions.join('; '),
      Type: n.isAction ? 'Action' : 'Comment',
      Status: n.cleared ? (n.isAction ? 'Done' : 'Reviewed') : 'Open',
      'Action owner': n.actionOwner,
      'Cleared by': n.clearedBy,
      'Cleared on': n.clearedAt ? String(n.clearedAt).slice(0, 10) : '',
    })));
  };

  const clearFilters = () => {
    setQ(''); setStatus('open'); setKind('all'); setMine(false);
    setAuthorF('all'); setSource('all'); setBrandFilter('all');
  };
  const filtersActive = q || status !== 'open' || kind !== 'all' || mine ||
    author_ !== 'all' || source !== 'all' || brandFilter !== 'all';

  const openToClear = filtered.filter((n) => !n.cleared).length;
  const sourceCounts = React.useMemo(() => {
    const c = { app: 0, import: 0 };
    openItems.forEach((n) => { c[n.source] = (c[n.source] || 0) + 1; });
    return c;
  }, [all]);


  return (
    <div className="page page-cap">
      <SectionHeader
        eyebrow="Workspace"
        title="Notes & actions"
        sub="Every comment written on every brand. Tick things off as you deal with them — actions get marked done, comments get marked reviewed — so what is left is what still needs you."
        right={
          <>
            <button
              className="btn"
              onClick={clearAllShown}
              disabled={!openToClear}
              title={source === 'all'
                ? 'Mark every open item currently listed done or reviewed'
                : `Mark every open ${((NOTE_SOURCES.find((s) => s.value === source) || {}).label || '').toLowerCase()} note done or reviewed`}
            >
              <window.I.check size={14} />
              {source === 'all' ? 'Clear all shown' : 'Clear this source'}
              {openToClear ? <span className="mono text-xs">{'· '}{openToClear}</span> : null}
            </button>
            <button className="btn" onClick={exportCsv} disabled={!filtered.length}>
              <window.I.download size={14} />
              Export CSV
            </button>
          </>
        }
      />

      {/* Summary tiles */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: 12, marginBottom: 14 }}>
        <NoteStat label="Open items" value={openItems.length} icon="inbox" accent={openItems.length > 0} />
        <NoteStat label="Open actions" value={openActions.length} icon="bolt" accent={openActions.length > 0} />
        <NoteStat label="Cleared" value={all.length - openItems.length} icon="check" />
        <NoteStat label={me ? 'Open, mine' : 'Total comments'}
          value={me ? openItems.filter(isMine).length : all.length} icon="at" />
      </div>

      {/* Filters */}
      <Card style={{ marginBottom: 14 }}>
        <div className="row gap-2" style={{ flexWrap: 'wrap', alignItems: 'center' }}>
          <div className="field grow" style={{ minWidth: 200 }}>
            <window.I.search size={14} stroke="var(--ink-3)" />
            <input placeholder="Search notes, brands or people…" value={q} onChange={(e) => setQ(e.target.value)} />
            {q ? (
              <button className="btn btn-icon btn-ghost" onClick={() => setQ('')} title="Clear"><window.I.x size={13} /></button>
            ) : null}
          </div>
          <div className="toggle-group">
            <button className={status === 'open' ? 'is-active' : ''} onClick={() => setStatus('open')}>
              Open ({openItems.length})
            </button>
            <button className={status === 'cleared' ? 'is-active' : ''} onClick={() => setStatus('cleared')}>
              Cleared ({all.length - openItems.length})
            </button>
            <button className={status === 'all' ? 'is-active' : ''} onClick={() => setStatus('all')}>All</button>
          </div>
          <div className="toggle-group">
            <button className={kind === 'all' ? 'is-active' : ''} onClick={() => setKind('all')}>Everything</button>
            <button className={kind === 'actions' ? 'is-active' : ''} onClick={() => setKind('actions')}>Actions</button>
            <button className={kind === 'comments' ? 'is-active' : ''} onClick={() => setKind('comments')}>Comments</button>
          </div>
          <label className="row gap-1 text-xs" style={{ cursor: me ? 'pointer' : 'not-allowed', alignItems: 'center', opacity: me ? 1 : 0.5 }}
                 title={me ? 'Written by me, owned by me, or tagging me' : 'Set your name in your profile first'}>
            <input type="checkbox" checked={mine} disabled={!me} onChange={(e) => setMine(e.target.checked)} />
            Only mine
          </label>
          <select value={author_} onChange={(e) => setAuthorF(e.target.value)} className="field" style={{ height: 32, padding: '0 8px', fontSize: 12.5 }}>
            <option value="all">All authors</option>
            {authors.map((a) => <option key={a} value={a}>{a}</option>)}
          </select>
          <select
            value={source}
            onChange={(e) => setSource(e.target.value)}
            className="field"
            style={{ height: 32, padding: '0 8px', fontSize: 12.5 }}
            title="Notes written here, or loaded in bulk from the Weekly Brand Review workbook"
          >
            {NOTE_SOURCES.map((s) => (
              <option key={s.value} value={s.value}>
                {s.label}{s.value !== 'all' && sourceCounts[s.value] ? ` (${sourceCounts[s.value]} open)` : ''}
              </option>
            ))}
          </select>
          <select value={brandFilter} onChange={(e) => setBrandFilter(e.target.value)} className="field" style={{ height: 32, padding: '0 8px', fontSize: 12.5, maxWidth: 200 }}>
            <option value="all">All brands</option>
            {brandOptions.map((b) => <option key={b} value={b}>{b}</option>)}
          </select>
          {filtersActive ? (
            <button className="btn btn-sm btn-ghost" onClick={clearFilters}>Reset</button>
          ) : null}
        </div>
        <div className="text-xs text-3" style={{ marginTop: 8 }}>
          Showing {filtered.length} of {all.length} comment{all.length === 1 ? '' : 's'}.
        </div>
      </Card>

      {filtered.length === 0 ? (
        <Card>
          <div className="empty">
            {all.length === 0 ? (
              <>
                <div style={{ fontWeight: 600, color: 'var(--ink)' }}>No notes yet.</div>
                <div className="text-sm" style={{ marginTop: 6, maxWidth: 460, marginInline: 'auto', lineHeight: 1.6 }}>
                  Open any brand and write one — the Notes panel sits under the brand header on Research, Match, Contacts and Draft.
                </div>
                <button className="btn btn-sm btn-primary" style={{ marginTop: 12 }} onClick={() => onNavigate('research')}>
                  Open Brand Research
                  <window.I.arrowRight size={12} />
                </button>
              </>
            ) : status === 'open' && !filtersActive ? (
              <>
                <window.I.check size={24} stroke="var(--positive)" />
                <div style={{ marginTop: 8, fontWeight: 600, color: 'var(--ink)' }}>Nothing open.</div>
                <div className="text-sm" style={{ marginTop: 6 }}>
                  Everything written has been dealt with. Cleared items are still on the <strong>Cleared</strong> tab.
                </div>
                <button className="btn btn-sm" style={{ marginTop: 12 }} onClick={() => setStatus('cleared')}>
                  Show cleared
                </button>
              </>
            ) : (
              <>
                <div style={{ fontWeight: 600, color: 'var(--ink)' }}>No notes match these filters.</div>
                <div className="text-sm" style={{ marginTop: 6 }}>
                  {all.length} note{all.length === 1 ? '' : 's'} exist in total.
                </div>
                <button className="btn btn-sm" style={{ marginTop: 12 }} onClick={clearFilters}>
                  Reset filters
                </button>
              </>
            )}
          </div>
        </Card>
      ) : (
        <div className="col gap-2">
          {filtered.map((n) => (
            <Card
              key={n.key}
              style={{
                borderColor: n.cleared ? 'var(--hairline)'
                  : n.isAction ? 'var(--attention)' : 'var(--hairline)',
                opacity: n.cleared ? 0.72 : 1,
              }}
            >
              <div className="row gap-3" style={{ alignItems: 'flex-start', flexWrap: 'wrap' }}>
                <Avatar initials={initialsFor(authorLabel(n.author))} size={30} />
                <div className="grow" style={{ minWidth: 220 }}>
                  <div className="row gap-2" style={{ alignItems: 'center', flexWrap: 'wrap' }}>
                    <span className="text-sm" style={{ fontWeight: 600 }}>{authorLabel(n.author)}</span>
                    <span className="text-xs text-3">on</span>
                    <button
                      className="text-sm"
                      onClick={() => onNavigate('research', n.brandId)}
                      style={{ background: 'transparent', border: 0, padding: 0, cursor: 'pointer', color: 'var(--accent)', fontWeight: 600 }}
                    >
                      {n.brandName}
                    </button>
                    {n.priority ? <PriorityPill priority={n.priority} /> : null}
                    {n.source === 'import' ? (
                      <Pill kind="neutral" style={{ fontSize: 10 }} title="Loaded from the Weekly Brand Review workbook, not written here">
                        Imported
                      </Pill>
                    ) : null}
                    {n.isAction ? (
                      <Pill kind={n.cleared ? 'positive' : 'attention'}>
                        {n.cleared ? 'Done' : 'Next action'}{n.actionOwner ? ` · ${n.actionOwner}` : ''}
                      </Pill>
                    ) : n.cleared ? (
                      <Pill kind="positive">Reviewed{n.clearedBy ? ` · ${n.clearedBy}` : ''}</Pill>
                    ) : null}
                    <TimeStamp iso={n.createdAt} className="right text-xs text-3 mono" />
                  </div>
                  <div className="text-sm text-2" style={{ marginTop: 6, lineHeight: 1.55 }}>
                    <MentionText text={n.text} />
                  </div>
                  <div className="row gap-2" style={{ marginTop: 10, flexWrap: 'wrap', alignItems: 'center' }}>
                    <button
                      className={`btn btn-sm ${n.cleared ? '' : 'btn-primary'}`}
                      onClick={() => toggleOne(n)}
                      title={n.cleared ? 'Put this back on the open list' : 'Clear this off your list'}
                    >
                      <window.I.check size={12} />
                      {n.cleared ? 'Re-open' : (n.isAction ? 'Mark done' : 'Mark reviewed')}
                    </button>
                    <button className="btn btn-sm" onClick={() => onNavigate('research', n.brandId)}>
                      Open brand
                      <window.I.arrowRight size={12} />
                    </button>
                    {n.mentions.length ? (
                      <span className="text-xs text-3 row gap-1">
                        <window.I.at size={11} stroke="var(--ink-3)" />
                        {n.mentions.join(', ')}
                      </span>
                    ) : null}
                    {n.cleared && n.clearedAt ? (
                      <span className="text-xs text-3">· cleared {String(n.clearedAt).slice(0, 10)}</span>
                    ) : null}
                    {n.brandCategory ? <span className="text-xs text-3">· {n.brandCategory}</span> : null}
                  </div>
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}
      {confirmEl}
    </div>
  );
}

function NoteStat({ label, value, icon, accent }) {
  const Ico = icon && window.I[icon];
  return (
    <div className="card card-pad" style={{ padding: '12px 14px', borderColor: accent ? 'var(--attention)' : undefined }}>
      <div className="row" style={{ justifyContent: 'space-between', marginBottom: 4 }}>
        <span className="eyebrow" style={{ fontSize: 10 }}>{label}</span>
        {Ico ? <Ico size={13} stroke={accent ? 'var(--attention)' : 'var(--ink-3)'} /> : null}
      </div>
      <span className="mono" style={{ fontSize: 22, fontWeight: 500 }}>{value}</span>
    </div>
  );
}

window.NotesPage = NotesPage;
