/* Settings — the two agent-behaviour controls Madison's operations lead asked for.
   Client Relations owns them; every other role sees the page with the controls locked. */
const { useState: sS } = React;

/* A renewal is eligible for a follow-up when a condition is open, the party owes it
   externally, and nothing has been heard for at least the configured threshold. */
function eligibleAt(days) {
  const MD = window.MD; const AG = window.AG;
  return MD.renewals.filter((r) => {
    if (!MD.isActiveRenewal(r) || r.hold || r.suppressed) return false;
    return AG.openC(r).some((c) => !c.internal && c.lastAttempt !== null && c.lastAttempt >= days);
  });
}

/* A party is a pattern, not an accident, when it is behind on `threshold` renewals
   whose conditions opened inside the `window`. */
function repeatOffenders(threshold, windowDays) {
  const MD = window.MD; const AG = window.AG;
  const by = {};
  MD.renewals.forEach((r) => {
    if (!MD.isActiveRenewal(r)) return;
    AG.openC(r).forEach((c) => {
      if (c.age > windowDays) return;
      const who = c.owing === 'Client' ? r.account + ' (client)' : c.owing === 'Advisor' ? ((AG.advOf(r) || {}).name || 'Unknown advisor') + ' (advisor)' : c.owing;
      (by[who] = by[who] || { who, n: 0, oldest: 0, accounts: [] });
      by[who].n += 1;
      by[who].oldest = Math.max(by[who].oldest, c.age);
      if (by[who].accounts.indexOf(r.account) < 0) by[who].accounts.push(r.account);
    });
  });
  return Object.keys(by).map((k) => by[k]).filter((x) => x.n >= threshold).sort((a, b) => b.n - a.n);
}

function Stepper({ value, min, max, onChange, suffix, options }) {
  if (options) {
    return <div className="row" style={{ gap: 7 }}>
      {options.map((o) => <button key={o} className={'btn sm' + (value === o ? ' p' : '')} onClick={() => onChange(o)}>{o}{suffix ? ' ' + suffix : ''}</button>)}
    </div>;
  }
  const vals = [];
  for (let i = min; i <= max; i++) vals.push(i);
  return <div className="row" style={{ gap: 7, flexWrap: 'wrap' }}>
    <button className="btn sm" disabled={value <= min} onClick={() => onChange(value - 1)}><Icon n="minus" s={12} /></button>
    <span style={{ minWidth: 96, textAlign: 'center', fontSize: 19, fontWeight: 600, color: 'var(--text)', fontVariantNumeric: 'tabular-nums' }}>{value} {suffix}</span>
    <button className="btn sm" disabled={value >= max} onClick={() => onChange(value + 1)}><Icon n="plus" s={12} /></button>
    <span className="row" style={{ gap: 3, marginLeft: 6 }}>
      {vals.map((v) => <button key={v} onClick={() => onChange(v)} title={v + ' ' + suffix}
        style={{ width: 22, height: 22, borderRadius: 'var(--r-sm)', cursor: 'pointer', fontFamily: 'var(--ui)', fontSize: 11, fontWeight: 600,
          border: '1px solid ' + (v === value ? 'var(--blue)' : 'var(--line)'), background: v === value ? 'var(--blue)' : 'var(--surface)', color: v === value ? '#fff' : 'var(--text-muted)' }}>{v}</button>)}
    </span>
  </div>;
}

function Toggle({ on, onChange }) {
  return <button onClick={() => onChange(!on)} className="row" style={{ gap: 9, background: 'none', border: 'none', cursor: 'pointer', padding: 0, fontFamily: 'var(--ui)' }}>
    <span style={{ width: 38, height: 22, borderRadius: 999, background: on ? 'var(--blue)' : 'var(--surface-3)', border: '1px solid ' + (on ? 'var(--blue)' : 'var(--line-2)'), position: 'relative', transition: 'background .18s' }}>
      <span style={{ position: 'absolute', top: 2, left: on ? 18 : 2, width: 16, height: 16, borderRadius: 999, background: '#fff', transition: 'left .18s' }} />
    </span>
    <span style={{ fontSize: 13, fontWeight: 600, color: on ? 'var(--blue-deep)' : 'var(--text-muted)' }}>{on ? 'On' : 'Off'}</span>
  </button>;
}

function SettingsScreen() {
  const app = useApp(); const MD = window.MD;
  const [days, setDays] = sS(MD.settings.escalation.days);
  const [rd, setRd] = sS({ ...MD.settings.repeatedDelay });
  const [log, setLog] = sS(MD.settingsLog.slice());
  const editable = can(app, 'settings');

  const record = (what, from, to) => {
    const entry = { at: new Date(MD.TODAY).toISOString(), who: app.user.name, what, from, to, why: 'Changed from Settings' };
    MD.settingsLog.unshift(entry);
    setLog(MD.settingsLog.slice());
  };

  const commitDays = (v) => {
    const from = days; setDays(v);
    MD.settings.escalation = { ...MD.settings.escalation, days: v, changedBy: app.user.name, changedAt: new Date(MD.TODAY).toISOString() };
    record('Escalation threshold', from + (from === 1 ? ' day' : ' days'), v + (v === 1 ? ' day' : ' days'));
    app.setToast('I will now wait ' + v + (v === 1 ? ' day' : ' days') + ' before drafting a follow-up', { sub: eligibleAt(v).length + ' renewals in the book meet that threshold today. Recorded with your name and the time.', ico: 'clock' });
  };
  const commitRd = (patch, what, from, to) => {
    const next = { ...rd, ...patch, changedBy: app.user.name, changedAt: new Date(MD.TODAY).toISOString() };
    setRd(next); MD.settings.repeatedDelay = next;
    record(what, from, to);
    const n = next.enabled ? repeatOffenders(next.threshold, next.window).length : 0;
    app.setToast(what + ' → ' + to, { sub: next.enabled ? n + (n === 1 ? ' party' : ' parties') + ' currently match that pattern.' : 'Repeated-delay alerts are off. Individual renewals still show their own conditions.', ico: next.enabled ? 'alert' : 'ban' });
  };

  const eligible = eligibleAt(days);
  const offenders = rd.enabled ? repeatOffenders(rd.threshold, rd.window) : [];

  return <div className="ag-canvas">
    <div className="ph"><div className="ph-row"><div className="grow">
      <h1>Settings</h1>
      <p className="sub">These two controls govern how I behave across the whole book, not on one renewal. Every change is recorded with a name and a time, and appears in the history below. <b>Only Client Relations can change them</b> — everyone else sees the same page with the controls locked.</p>
    </div><span className="ph-badge"><Icon n="user" s={14} />Client Relations controlled</span></div></div>

    {!editable ? <div className="note amber" style={{ marginBottom: 18 }}>
      <Icon n="lock" s={15} />
      <span>You are signed in as <b>{app.user.role}</b>. You can see exactly what these controls are set to and what they currently mean, but changing them is Client Relations' decision.</span>
    </div> : null}

    <div className="secwrap">
      <div className="sec"><span className="st">Escalation threshold</span><span className="snote">How patient I am before preparing a chase</span></div>
      <div className="dcard">
        <div className="acc" />
        <div className="grow" style={{ minWidth: 0 }}>
          <div className="dcard-b">
            <div className="dcard-h"><span className="who">How long I wait before drafting a follow-up</span></div>
            <div className="body">When a renewal has gone silent with a condition still open, I wait this long before preparing a chase. Set it too short and advisors get chased over nothing — a client who replied yesterday gets another reminder today. Set it too long and deadlines arrive with work still outstanding.</div>
            <div style={{ marginTop: 15 }}>
              <div className="eyebrow" style={{ marginBottom: 8 }}>Wait before following up</div>
              <Gated action="settings" label="Change threshold">
                <Stepper value={days} min={MD.settings.escalation.range[0]} max={MD.settings.escalation.range[1]} suffix={days === 1 ? 'day' : 'days'} onChange={commitDays} />
              </Gated>
              {!editable ? <div style={{ marginTop: 9, fontSize: 19, fontWeight: 600, color: 'var(--text)' }}>{days} {days === 1 ? 'day' : 'days'}</div> : null}
            </div>
            <div className="row" style={{ gap: 8, marginTop: 14, flexWrap: 'wrap' }}>
              <span className="chip"><i className="cd" />changed {rel(MD.settings.escalation.changedAt)} by {MD.settings.escalation.changedBy}</span>
              <span className="chip blue"><i className="cd" />{eligible.length} renewals eligible today</span>
            </div>
          </div>
          <div className="dbar">
            <span className="note" style={{ marginLeft: 0, textAlign: 'left' }}>
              <b>What this means right now.</b> At {days} {days === 1 ? 'day' : 'days'}, <b>{eligible.length} of {MD.renewals.filter((r) => MD.isActiveRenewal(r)).length} active renewals</b> have gone quiet long enough for me to prepare a follow-up.
              {days > MD.settings.escalation.range[0] ? ' At ' + (days - 1) + ' it would be ' + eligibleAt(days - 1).length + '.' : ''}
              {days < MD.settings.escalation.range[1] ? ' At ' + (days + 1) + ' it would be ' + eligibleAt(days + 1).length + '.' : ''}
            </span>
          </div>
        </div>
      </div>
    </div>

    <div className="secwrap">
      <div className="sec"><span className="st">Repeated-delay alerts</span><span className="snote">Patterns across renewals, not inside one</span></div>
      <div className={'dcard' + (rd.enabled ? '' : ' week')}>
        <div className="acc" />
        <div className="grow" style={{ minWidth: 0 }}>
          <div className="dcard-b">
            <div className="dcard-h"><span className="who">Tell me when the same party keeps holding things up</span></div>
            <div className="body">When one advisor, client, or internal team is behind on several renewals inside the same window, that is a pattern rather than a series of accidents. Without this, each delay sits inside its own renewal and nobody sees the shape of it. Salesforce notifications cannot look across renewals this way.</div>

            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit,minmax(196px,1fr))', gap: 16, marginTop: 16 }}>
              <div>
                <div className="eyebrow" style={{ marginBottom: 8 }}>Alerts</div>
                <Gated action="settings" label="Turn alerts on or off">
                  <Toggle on={rd.enabled} onChange={(v) => commitRd({ enabled: v }, 'Repeated-delay alerts', rd.enabled ? 'On' : 'Off', v ? 'On' : 'Off')} />
                </Gated>
                {!editable ? <div style={{ marginTop: 7, fontSize: 13, fontWeight: 600, color: rd.enabled ? 'var(--blue-deep)' : 'var(--text-muted)' }}>{rd.enabled ? 'On' : 'Off'}</div> : null}
              </div>
              <div>
                <div className="eyebrow" style={{ marginBottom: 8 }}>Delays before I flag it</div>
                <Gated action="settings" label="Change the trigger count">
                  <Stepper value={rd.threshold} options={[2, 3, 4, 5]} onChange={(v) => commitRd({ threshold: v }, 'Repeated-delay trigger', rd.threshold + ' delays', v + ' delays')} />
                </Gated>
                {!editable ? <div style={{ marginTop: 7, fontSize: 13, fontWeight: 600 }}>{rd.threshold} delays</div> : null}
              </div>
              <div>
                <div className="eyebrow" style={{ marginBottom: 8 }}>Counted over</div>
                <Gated action="settings" label="Change the window">
                  <Stepper value={rd.window} options={[14, 30, 60]} suffix="days" onChange={(v) => commitRd({ window: v }, 'Repeated-delay window', rd.window + ' days', v + ' days')} />
                </Gated>
                {!editable ? <div style={{ marginTop: 7, fontSize: 13, fontWeight: 600 }}>{rd.window} days</div> : null}
              </div>
            </div>

            <div className="row" style={{ gap: 8, marginTop: 14, flexWrap: 'wrap' }}>
              <span className="chip"><i className="cd" />changed {rel(rd.changedAt)} by {rd.changedBy}</span>
              {rd.enabled ? <span className={'chip ' + (offenders.length ? 'amber' : 'green')}><i className="cd" />{offenders.length} {offenders.length === 1 ? 'party matches' : 'parties match'} today</span>
                : <span className="chip"><i className="cd" />alerts off</span>}
            </div>

            <div style={{ marginTop: 16 }}>
              <div className="eyebrow" style={{ marginBottom: 8 }}>Who this would flag right now</div>
              {!rd.enabled ? <div className="note"><Icon n="ban" s={15} style={{ color: 'var(--text-muted)' }} /><span>Alerts are off, so I am not looking for patterns across renewals. Each delay still shows inside its own renewal.</span></div>
                : offenders.length ? <div style={{ border: '1px solid var(--line)', borderRadius: 'var(--r-md)', overflow: 'hidden' }}>
                  {offenders.slice(0, 6).map((o, i) => <div key={o.who} className="row" style={{ gap: 12, padding: '10px 13px', borderTop: i ? '1px solid var(--line)' : 'none' }}>
                    <span className="pill t-amber">{o.n}</span>
                    <span className="grow" style={{ minWidth: 0 }}>
                      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text)' }}>{o.who}</div>
                      <div className="xs dim" style={{ marginTop: 2 }}>{o.accounts.slice(0, 3).join(' · ')}{o.accounts.length > 3 ? ' · +' + (o.accounts.length - 3) + ' more' : ''}</div>
                    </span>
                    <span className="xs dim">oldest {o.oldest}d</span>
                  </div>)}
                  {offenders.length > 6 ? <div className="row" style={{ padding: '9px 13px', borderTop: '1px solid var(--line)', background: 'var(--surface-2)' }}>
                    <span className="sm mut">{offenders.length - 6} more {offenders.length - 6 === 1 ? 'party' : 'parties'} match this pattern</span>
                  </div> : null}
                </div>
                  : <div className="note"><Icon n="check" s={15} style={{ color: 'var(--green-deep)' }} /><span>Nobody currently meets this pattern — no single party is behind on {rd.threshold} or more renewals inside {rd.window} days. That is the outcome you want.</span></div>}
            </div>
          </div>
          <div className="dbar">
            <span className="note" style={{ marginLeft: 0, textAlign: 'left' }}>
              <b>What this means right now.</b> {rd.enabled
                ? offenders.length ? 'I would raise ' + offenders.length + ' pattern ' + (offenders.length === 1 ? 'alert' : 'alerts') + ' at ' + rd.threshold + ' delays inside ' + rd.window + ' days. Loosening to ' + (rd.threshold + 1) + ' would raise ' + repeatOffenders(rd.threshold + 1, rd.window).length + '.'
                  : 'No alert would be raised at these settings.'
                : 'Nothing is being watched across renewals while this is off.'}
            </span>
          </div>
        </div>
      </div>
    </div>

    <div className="secwrap">
      <div className="sec"><span className="st">Change history</span><span className="sn">{log.length}</span><span className="snote">Who changed what, and when</span></div>
      <div style={{ background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 'var(--r-lg)', overflow: 'hidden' }}>
        {log.map((e, i) => <div key={i} className="row" style={{ gap: 14, padding: '13px 18px', borderTop: i ? '1px solid var(--line)' : 'none', alignItems: 'flex-start' }}>
          <span style={{ width: 30, height: 30, borderRadius: 999, display: 'grid', placeItems: 'center', flex: '0 0 30px', background: e.who === 'System' ? 'var(--surface-3)' : 'var(--tint-blue)', color: e.who === 'System' ? 'var(--text-muted)' : 'var(--blue)' }}>
            <Icon n={e.who === 'System' ? 'activity' : 'user'} s={14} />
          </span>
          <div className="grow" style={{ minWidth: 0 }}>
            <div style={{ fontSize: 13.5, color: 'var(--text-2)' }}><b style={{ color: 'var(--text)' }}>{e.what}</b> {e.from} <Icon n="arrow-right" s={11} style={{ display: 'inline-block', verticalAlign: -1, color: 'var(--text-dim)' }} /> <b style={{ color: 'var(--text)' }}>{e.to}</b></div>
            <div className="xs dim" style={{ marginTop: 2 }}>{e.who} · {dt(e.at)}{e.why ? ' · ' + e.why : ''}</div>
          </div>
        </div>)}
      </div>
    </div>
  </div>;
}

Object.assign(window, { SettingsScreen, eligibleAt, repeatOffenders });
