// Access & permissions — the shared model for "this inbox is connected, but a
// couple of newer capabilities need a quick reconnect to switch on".
//
// Tone rules (from the brand): calm, never alarming. Missing access is framed as
// an *upgrade you can turn on*, not a security failure. Gold/cream — never red.
// Red is reserved for destructive/overdue elsewhere in the product.

// ---- Scope catalog -------------------------------------------------------
// `core` scopes are the base connection (always granted while connected).
// The rest are optional capabilities that may be off until the user reconnects.
const PERM_CATALOG = [
  { key:'read', core:true, icon:'mail-search', label:'Read inbox',
    short:'Finds bills, packages, events and tasks in your inbox',
    enables:'finding everything Zeranda organizes for you',
    offline:'Zeranda can’t see your inbox' },
  { key:'calendar', icon:'calendar', label:'Calendar sync',
    short:'Adds detected events to your calendar and checks for conflicts',
    enables:'adding events to your calendar and spotting clashes',
    offline:'Detected events stay here and aren’t added to your calendar' },
  { key:'send', icon:'send', label:'Send replies',
    short:'Sends the replies you approve, from your address',
    enables:'sending the replies you approve',
    offline:'Zeranda can draft replies but can’t send them for you' },
  { key:'contacts', icon:'users', label:'Contacts',
    short:'Recognizes people you know to label senders',
    enables:'naming the people behind your email',
    offline:'Senders show as plain email addresses' },
];
const ALL_SCOPES = PERM_CATALOG.map(p => p.key);
const OPTIONAL_SCOPES = PERM_CATALOG.filter(p => !p.core).map(p => p.key);
const PERM_BY_KEY = Object.fromEntries(PERM_CATALOG.map(p => [p.key, p]));

const PERM_ASSURANCES = [
  { icon:'shield-check', text:'Zeranda only ever uses the access you approve' },
  { icon:'eye-off',      text:'No raw email content is stored' },
  { icon:'unplug',       text:'You can turn any access off or disconnect anytime' },
];

const PROVIDER_META = {
  google:    { label:'Google',    cont:'Continue with Google' },
  microsoft: { label:'Microsoft', cont:'Continue with Microsoft' },
};
function ProviderLogo({ provider }) {
  const Logo = provider === 'microsoft' ? window.MsLogo : window.GoogleG;
  return Logo ? <Logo /> : <Icon name="mail" size={18} color="var(--fg-2)" />;
}

// ---- Tiny external store so reconnecting in one surface updates them all ----
// Permissions live on the account objects in ZD_DATA (single source of truth);
// any component can subscribe via usePermissions() and re-render on change.
const ZD_PERM = {
  _subs: new Set(),
  accounts() { return (window.ZD_DATA && window.ZD_DATA.settings.accounts) || []; },
  account(id) { return this.accounts().find(a => a.id === id); },
  primary() { return this.accounts().find(a => a.primary) || this.accounts()[0] || null; },
  granted(acc) { return (acc && acc.granted) || []; },
  has(scope, acc) { acc = acc || this.primary(); return this.granted(acc).includes(scope); },
  // optional scopes this account is still missing
  missing(acc) { acc = acc || this.primary(); const g = this.granted(acc); return OPTIONAL_SCOPES.filter(s => !g.includes(s)).map(s => PERM_BY_KEY[s]); },
  isFull(acc) { acc = acc || this.primary(); return this.missing(acc).length === 0; },
  // ---- user-controlled pause (separate from access scopes) -------------
  // A paused inbox keeps every approved scope, but Zeranda stops scanning it.
  // Resuming needs no reconnect — it's a switch, not a permission change.
  isPaused(acc) { acc = acc || this.primary(); return !!(acc && acc.paused); },
  pausedAccounts() { return this.accounts().filter(a => a.paused); },
  activeAccounts() { return this.accounts().filter(a => !a.paused); },
  anyPaused() { return this.accounts().some(a => a.paused); },
  allPaused() { const a = this.accounts(); return a.length > 0 && a.every(x => x.paused); },
  pause(id) { const a = this.account(id); if (a) { a.paused = true; this.emit(); } },
  resume(id) { const a = this.account(id); if (a) { a.paused = false; this.emit(); } },
  pauseAll() { this.accounts().forEach(a => { a.paused = true; }); this.emit(); },
  resumeAll() { this.accounts().forEach(a => { a.paused = false; }); this.emit(); },
  // 'paused' | 'limited' | 'full' — the at-a-glance state for chips & rings
  accessLevel(acc) { acc = acc || this.primary(); if (this.isPaused(acc)) return 'paused'; return this.isFull(acc) ? 'full' : 'limited'; },
  grant(id, scopes) {
    const a = this.account(id); if (!a) return;
    a.granted = [...new Set([...(a.granted || []), ...(scopes && scopes.length ? scopes : ALL_SCOPES)])];
    this.emit();
  },
  reconnect(id) { this.grant(id, ALL_SCOPES); },   // a full re-auth re-grants everything
  emit() { this._subs.forEach(f => { try { f(); } catch (e) {} }); },
  subscribe(fn) { this._subs.add(fn); return () => this._subs.delete(fn); },
};
function usePermissions() {
  const [, force] = useState(0);
  useEffect(() => ZD_PERM.subscribe(() => force(n => n + 1)), []);
  return ZD_PERM;
}

// ---- Calm reconnect notice (the reusable "heads up, easily fixed" strip) ----
// variant: 'banner' (page top) | 'inline' (inside a card) | 'panel' (inside a modal)
function AccessNotice({ icon = 'sparkles', title, children, ctaLabel = 'Reconnect', ctaIcon = 'refresh-cw',
  onCta, secondaryLabel, onSecondary, variant = 'banner', tone = 'gold' }) {
  const icColor = tone === 'slate' ? 'var(--fg-2)' : 'var(--gold-700)';
  return (
    <div className={`access-notice an-${variant} ant-${tone}`}>
      <span className="an-ic"><Icon name={icon} size={variant === 'banner' ? 21 : 18} color={icColor} /></span>
      <div className="an-body">
        <div className="an-title">{title}</div>
        {children && <div className="an-text">{children}</div>}
      </div>
      <div className="an-acts">
        {secondaryLabel && <button className="btn btn-ghost an-sec" onClick={onSecondary}>{secondaryLabel}</button>}
        {onCta && <button className="btn btn-primary" onClick={onCta}><Icon name={ctaIcon} size={15} />{ctaLabel}</button>}
      </div>
    </div>
  );
}

// ---- At-a-glance access state chip (account menu, settings) ----
function AccessLevelChip({ level, size = 'sm' }) {
  const MAP = {
    full:    { cls:'full',    icon:'shield-check', label:'Full access', color:'var(--green-600)' },
    limited: { cls:'limited', icon:'sparkles',     label:'Limited',     color:'var(--gold-700)' },
    paused:  { cls:'paused',  icon:'pause',        label:'Paused',      color:'var(--fg-3)' },
  };
  const m = MAP[level] || MAP.full;
  return <span className={`alv alv-${m.cls} ${size === 'lg' ? 'alv-lg' : ''}`}><Icon name={m.icon} size={12} color={m.color} />{m.label}</span>;
}

// ---- Global "syncing paused" banner (app-wide, calm/neutral tone) ----
// Pausing is a deliberate user choice, never an error — so this is slate, not
// gold (reconnect) or red (destructive). Shown atop every screen while any
// inbox is paused; resuming is one click and needs no re-auth.
function SyncStatusBanner({ go }) {
  const perm = usePermissions();
  const paused = perm.pausedAccounts();
  if (paused.length === 0) return null;
  const all = perm.allPaused();
  const names = paused.map(a => a.nickname || a.email).join(', ');
  return (
    <div className="screen-inner sync-banner-wrap">
      <AccessNotice variant="banner" tone="slate" icon="pause"
        title={all ? 'Syncing is paused' : `${paused.length} ${paused.length > 1 ? 'inboxes' : 'inbox'} paused`}
        ctaLabel={all ? 'Resume syncing' : 'Resume all'} ctaIcon="play" onCta={() => perm.resumeAll()}
        secondaryLabel="Manage inboxes" onSecondary={() => go && go('settings')}>
        {all
          ? 'Zeranda is paused for your inboxes right now, so bills, packages, events and tasks won’t update. Your connection and data stay safe — resume anytime to pick up where you left off.'
          : `Zeranda is paused for ${names}. Your other inboxes are still syncing normally. Resume anytime — no reconnect needed.`}
      </AccessNotice>
    </div>
  );
}

// ---- One permission row (used in settings detail + reconnect modal) ----
// mode: 'status' (settings — on/off) | 'add' (modal — turning on) | 'on' (modal — already on)
function PermRow({ perm, mode = 'status', granted, highlight }) {
  const on = mode === 'on' || (mode === 'status' && granted);
  const adding = mode === 'add';
  const cls = adding ? (highlight ? 'add hl' : 'add') : on ? 'on' : 'off';
  const icColor = adding || (!on && mode === 'status') ? 'var(--gold-700)' : on ? 'var(--green-600)' : 'var(--fg-4)';
  return (
    <div className={`perm-row ${cls}`}>
      <span className="perm-ic"><Icon name={perm.icon} size={17} color={on ? 'var(--green-600)' : icColor} /></span>
      <div className="perm-meta">
        <div className="perm-l">
          {perm.label}
          {perm.core && <span className="perm-core">Required</span>}
          {highlight && <span className="perm-need">Needed now</span>}
        </div>
        <div className="perm-s">{(mode === 'status' && !granted) ? perm.offline : perm.short}</div>
      </div>
      <span className={`perm-state ${adding ? 'add' : on ? 'on' : 'off'}`}>
        {adding ? <><Icon name="plus" size={13} /> Turn on</>
          : on ? <><Icon name="check" size={13} /> On</>
          : 'Off'}
      </span>
    </div>
  );
}

// Full status list for an account (Settings → review access).
function PermissionList({ account }) {
  const perm = usePermissions();
  const granted = perm.granted(account);
  return (
    <div className="perm-list">
      {PERM_CATALOG.map(p => <PermRow key={p.key} perm={p} mode="status" granted={granted.includes(p.key)} />)}
    </div>
  );
}

// ---- The centerpiece: reconnect / re-consent flow ----
// Reusable from Settings, Calendar and Tasks. Shows OUR plain-language summary of
// what's being switched on, a familiar "Continue with <provider>" action, then a
// reassuring confirmation. (Not a recreation of any provider's consent screen.)
function ReconnectModal({ account, highlight = [], reason, onClose, onDone }) {
  const perm = usePermissions();
  const [phase, setPhase] = useState('review');     // review | connecting | done
  const [enabled, setEnabled] = useState([]);       // scopes switched on (snapshot for the done screen)
  const meta = PROVIDER_META[account.provider] || PROVIDER_META.google;
  const granted = perm.granted(account);
  const grantedPerms = PERM_CATALOG.filter(p => granted.includes(p.key));
  const turningOn = PERM_CATALOG.filter(p => !granted.includes(p.key));

  const connect = () => {
    setEnabled(turningOn);
    setPhase('connecting');
    setTimeout(() => { perm.reconnect(account.id); setPhase('done'); }, 1300);
  };
  const finish = () => { onDone && onDone(); onClose && onClose(); };

  return (
    <div className="modal-scrim" onClick={phase === 'connecting' ? undefined : onClose}>
      <div className="modal reconnect-modal zd-scroll" onClick={e => e.stopPropagation()}>
        {phase !== 'connecting' && <button className="modal-x" onClick={onClose} aria-label="Close"><Icon name="x" size={18} /></button>}

        {phase === 'review' && (
          <React.Fragment>
            <div className="modal-body">
              <div className="rc-provider">
                <span className="rc-logo"><ProviderLogo provider={account.provider} /></span>
                <div className="rc-prov-meta">
                  <div className="rc-prov-name">{meta.label} account</div>
                  <div className="rc-prov-email">{account.email}</div>
                </div>
                <span className="rc-prov-status"><span className="dot" /> Connected</span>
              </div>

              <h3>Reconnect to turn {turningOn.length > 1 ? 'these on' : 'this on'}</h3>
              <div className="msub">
                {account.email} stays connected and secure. Reconnecting only adds the access below{reason ? `, ${reason}` : ''} — you can turn it off anytime.
              </div>

              {turningOn.length > 0 && (
                <React.Fragment>
                  <div className="rc-grp-l">Turning on</div>
                  <div className="perm-list tight">
                    {turningOn.map(p => <PermRow key={p.key} perm={p} mode="add" highlight={highlight.includes(p.key)} />)}
                  </div>
                </React.Fragment>
              )}
              {grantedPerms.length > 0 && (
                <React.Fragment>
                  <div className="rc-grp-l muted">Already on — staying the same</div>
                  <div className="perm-list tight">
                    {grantedPerms.map(p => <PermRow key={p.key} perm={p} mode="on" />)}
                  </div>
                </React.Fragment>
              )}

              <div className="rc-assure">
                {PERM_ASSURANCES.map(a => (
                  <div className="rc-assure-row" key={a.text}><Icon name={a.icon} size={14} color="var(--fg-3)" /><span>{a.text}</span></div>
                ))}
              </div>
            </div>
            <div className="modal-foot rc-foot">
              <button className="btn btn-ghost" onClick={onClose}>Not now</button>
              <button className="btn btn-primary rc-continue" onClick={connect}>
                <span className="rc-btn-logo"><ProviderLogo provider={account.provider} /></span>{meta.cont}
              </button>
            </div>
          </React.Fragment>
        )}

        {phase === 'connecting' && (
          <div className="rc-center">
            <div className="rc-spinner" />
            <div className="rc-center-t">Securely reconnecting…</div>
            <div className="rc-center-s">Confirming access with {meta.label} for {account.email}</div>
          </div>
        )}

        {phase === 'done' && (
          <div className="rc-center">
            <span className="rc-done-ic"><Icon name="check" size={30} color="var(--green-600)" /></span>
            <div className="rc-center-t">You’re all set</div>
            <div className="rc-center-s">
              {enabled.map(p => p.label).join(' and ')} {enabled.length > 1 ? 'are' : 'is'} now on for {account.email}.
            </div>
            <div className="rc-done-list">
              {enabled.map(p => <span className="rc-done-chip" key={p.key}><Icon name="check" size={13} color="var(--green-600)" /> {p.label}</span>)}
            </div>
            <button className="btn btn-primary rc-done-btn" onClick={finish}><Icon name="check" size={16} /> Done</button>
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, {
  PERM_CATALOG, OPTIONAL_SCOPES, ALL_SCOPES, PERM_BY_KEY, PROVIDER_META,
  ZD_PERM, usePermissions, AccessNotice, AccessLevelChip, SyncStatusBanner, PermRow, PermissionList, ReconnectModal, ProviderLogo,
});
