// vault.jsx — «خزنة الابتكار» Innovation Vault: owner-only sealed registry for patent disclosures
// DB-A (confidential): the disclosure payload, stored encoded at rest.
// DB-B (registry):    fingerprint + SHA-256 + trusted timestamp + PoAS metrics — what the owner manages.

const VAULT_KEY_STORE = 'ibtikar_vault_key_v1';
const VAULT_OPEN = 'ibtikar_vault_open';

/* ---------- crypto helpers ---------- */
async function sha256Hex(str) {
  try {
    const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));
    return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('');
  } catch (e) {
    // deterministic fallback (non-secure contexts) — FNV-1a x4 lanes
    let out = '';
    for (let lane = 0; lane < 8; lane++) {
      let h = 2166136261 ^ lane;
      for (let i = 0; i < str.length; i++) { h ^= str.charCodeAt(i); h = Math.imul(h, 16777619); }
      out += (h >>> 0).toString(16).padStart(8, '0');
    }
    return out;
  }
}
function b64enc(str) {
  const bytes = new TextEncoder().encode(str);
  let bin = '';
  for (let i = 0; i < bytes.length; i += 4096) bin += String.fromCharCode.apply(null, bytes.subarray(i, i + 4096));
  return btoa(bin);
}
function b64dec(b64) {
  const bin = atob(b64);
  const bytes = new Uint8Array(bin.length);
  for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
  return new TextDecoder().decode(bytes);
}

/* ---------- PoAS metrics derived deterministically from the sealed hash (owner can override) ---------- */
function metricsFromHash(hex) {
  const n = (i) => parseInt(hex.slice(i, i + 2), 16) / 255;
  return { INV: +(7 + n(0) * 2.8).toFixed(1), INN: +(7.5 + n(2) * 2).toFixed(1) };
}
function synergyScore(INV, INN) { return +(((INV + INN) / 2)).toFixed(2); }

/* ---------- seal a disclosure → vault entry ---------- */
async function sealDisclosure(rec, override, prev) {
  const pick = (v) => (v == null ? '' : (typeof v === 'object' ? (v.ar || v.en || '') : v));
  const concept = {
    kind: rec.kind || 'idea',
    title: rec.title || '',
    author: rec.inventors || rec.name || '',
    field: pick(rec.field) || pick(rec.category) || pick(rec.dept),
    abstract: rec.abstract || rec.solution || '',
    novelty: rec.novelty || rec.impact || '',
    problem: rec.challenge || '',
    stage: pick(rec.stage),
    files: (rec.files || []).map(f => f.name || ''),
  };
  const conceptJson = JSON.stringify(concept, Object.keys(concept).sort());
  const preHash = await sha256Hex(conceptJson);
  const base = override || (prev && prev.metrics) || metricsFromHash(preHash);
  const score = synergyScore(base.INV, base.INN);
  const full = await sha256Hex(JSON.stringify({ inventor: concept.author, idea: conceptJson, score }));
  const ver = prev ? +(prev.version + 0.1).toFixed(1) : 1.0;
  return {
    ref: rec.ref,
    kind: rec.kind || 'idea',
    fingerprint: `PoAS-v1::${full.slice(0, 10).toUpperCase()}::Score:${score}`,
    hash: full,
    conceptHash: preHash,
    sealedAt: new Date().toISOString(),
    version: ver,
    metrics: base,
    score,
    cipher: b64enc(conceptJson),
    prevHash: prev ? prev.hash : null,
  };
}
async function verifySeal(entry) {
  const conceptJson = b64dec(entry.cipher);
  const preHash = await sha256Hex(conceptJson);
  const concept = JSON.parse(conceptJson);
  const full = await sha256Hex(JSON.stringify({ inventor: concept.author || concept.inventors || '', idea: conceptJson, score: entry.score }));
  return preHash === entry.conceptHash && full === entry.hash;
}

/* ---------- the vault panel (rendered inside the owners' admin only) ---------- */
function InnovationVault({ t, L, data, save, auth }) {
  const toast = useToast();
  const hasKey = !!localStorage.getItem(VAULT_KEY_STORE);
  const [unlocked, setUnlocked] = React.useState(() => sessionStorage.getItem(VAULT_OPEN) === '1');
  const [sel, setSel] = React.useState(null);
  const [tab, setTab] = React.useState('all');
  const [showLog, setShowLog] = React.useState(false);

  const patents = (data.submissions && data.submissions.patents) || [];
  const ideas = (data.submissions && data.submissions.ideas) || [];
  const all = [...patents.map(p => ({ ...p, kind: 'patent' })), ...ideas.map(i => ({ ...i, kind: 'idea' }))];
  const vault = data.vault || {};
  const log = data.vaultLog || [];
  const who = (auth && auth.user) ? L(auth.user.name) : '—';

  const writeVault = React.useCallback((mutate) => {
    const next = structuredClone(data);
    next.vault = { ...(next.vault || {}) };
    next.vaultLog = (next.vaultLog || []).slice();
    mutate(next);
    save(next);
  }, [data, save]);

  const addLog = (next, action, ref) => {
    next.vaultLog.unshift({ at: new Date().toISOString(), who, action, ref: ref || '—' });
    next.vaultLog = next.vaultLog.slice(0, 60);
  };

  // auto-seal any disclosure that arrived without a seal
  React.useEffect(() => {
    if (!unlocked) return;
    const missing = patents.filter(p => !vault[p.ref]);
    if (!missing.length) return;
    let dead = false;
    (async () => {
      const entries = [];
      for (const p of missing) entries.push(await sealDisclosure({ ...p, kind: 'patent' }));
      if (dead) return;
      writeVault(next => { entries.forEach(e => { next.vault[e.ref] = e; }); addLog(next, 'seal', entries.map(e => e.ref).join(', ')); });
    })();
    return () => { dead = true; };
  }, [unlocked, patents.length]);

  // convert any submission (idea or patent) into a sealed fingerprint on demand
  const sealNow = React.useCallback(async (subs) => {
    const list = Array.isArray(subs) ? subs : [subs];
    const entries = [];
    for (const s of list) entries.push(await sealDisclosure(s, null, vault[s.ref] || null));
    writeVault(next => { entries.forEach(e => { next.vault[e.ref] = e; }); addLog(next, 'seal', entries.map(e => e.ref).join(', ')); });
    toast(t('vlt_sealed_ok'));
    return entries[0];
  }, [vault, writeVault]);

  const sealedRows = all.map(p => ({ p, s: vault[p.ref] })).filter(x => x.s)
    .filter(x => tab === 'all' || x.p.kind === tab)
    .sort((a, b) => b.s.score - a.s.score);
  const unsealed = all.filter(p => !vault[p.ref]).filter(x => tab === 'all' || x.kind === tab);
  const rows = sealedRows;
  const top = rows[0];
  const last = rows.reduce((m, r) => (!m || r.s.sealedAt > m ? r.s.sealedAt : m), null);

  const exportRegistry = (withCipher) => {
    const payload = {
      exportedAt: new Date().toISOString(), by: who,
      db: withCipher ? 'A · confidential' : 'B · registry',
      entries: rows.map(({ p, s }) => withCipher ? s : { ref: s.ref, fingerprint: s.fingerprint, hash: s.hash, sealedAt: s.sealedAt, version: s.version, metrics: s.metrics, score: s.score, inventor: p.inventors }),
    };
    const a = document.createElement('a');
    a.href = URL.createObjectURL(new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' }));
    a.download = `innovation-vault-${withCipher ? 'A' : 'B'}-${new Date().toISOString().slice(0, 10)}.json`;
    a.click(); URL.revokeObjectURL(a.href);
    writeVault(next => addLog(next, withCipher ? 'export-A' : 'export-B'));
    toast(t('vlt_exported'));
  };

  if (!unlocked) return <VaultLock t={t} L={L} hasKey={hasKey} onOpen={() => { sessionStorage.setItem(VAULT_OPEN, '1'); setUnlocked(true); }} />;

  return (
    <div className="card card-pad vault-panel">
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 14, flexWrap: 'wrap' }}>
        <div>
          <div className="eyebrow" style={{ color: 'var(--gold)' }}><Icon.lock s={15} /> {t('vlt_title')}</div>
          <p className="muted" style={{ fontSize: 13.5, marginTop: 8, maxWidth: 620, lineHeight: 1.6 }}>{t('vlt_sub')}</p>
        </div>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <button className="btn btn-ghost btn-sm" onClick={() => setShowLog(true)}><Icon.clock s={15} /> {t('vlt_log')}</button>
          <button className="btn btn-dark btn-sm" onClick={() => { sessionStorage.removeItem(VAULT_OPEN); setUnlocked(false); }}><Icon.lock s={15} /> {t('vlt_lock')}</button>
        </div>
      </div>

      <div className="vault-stats">
        {[[rows.length, t('vlt_assets')], [top ? top.s.score : '—', t('vlt_top')], [last ? new Date(last).toISOString().slice(0, 10) : '—', t('vlt_last')]].map(([v, k], i) => (
          <div key={i} className="vault-stat"><b>{v}</b><span>{k}</span></div>
        ))}
      </div>

      {/* filter by kind */}
      <div className="tabs" style={{ marginTop: 16 }}>
        {[['all', t('vlt_tab_all')], ['idea', t('vault_ideas')], ['patent', t('vault_patents')]].map(([k, lbl]) => (
          <button key={k} className={`tab ${tab === k ? 'on' : ''}`} onClick={() => setTab(k)}>{lbl}</button>
        ))}
      </div>

      {/* not-yet-sealed submissions — one click turns any of them into a fingerprint */}
      {unsealed.length > 0 && (
        <div className="vault-pending">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
            <div className="eyebrow" style={{ color: 'var(--mint)' }}><Icon.spark s={14} /> {t('vlt_unsealed')} · {unsealed.length}</div>
            <button className="btn btn-primary btn-sm" onClick={() => sealNow(unsealed)}><Icon.lock s={15} /> {t('vlt_seal_all')}</button>
          </div>
          <div style={{ display: 'grid', gap: 8, marginTop: 12 }}>
            {unsealed.map(u => (
              <div key={u.ref} className="vault-pending-row">
                <span className={`badge ${u.kind === 'patent' ? 'gold' : 'mint'}`} style={{ flex: 'none' }}>{u.ref}</span>
                <b style={{ flex: 1, minWidth: 0, fontSize: 14.5, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{u.title || '—'}</b>
                <button className="btn btn-ghost btn-sm" style={{ flex: 'none' }} onClick={() => sealNow(u)}><Icon.hash s={14} /> {t('vlt_convert')}</button>
              </div>
            ))}
          </div>
        </div>
      )}

      {rows.length === 0 ? (
        <p className="muted center" style={{ padding: '28px 0', fontSize: 14.5 }}>{t('vlt_empty')}</p>
      ) : (
        <div style={{ display: 'grid', gap: 10, marginTop: 18 }}>
          {rows.map(({ p, s }, i) => (
            <button key={s.ref} className="card vault-row" onClick={() => setSel({ p, s })}>
              <span className="vault-rank">{i + 1}</span>
              <div style={{ flex: 1, minWidth: 0, textAlign: 'start' }}>
                <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
                  <b style={{ fontSize: 15 }}>{p.title || '—'}</b>
                  <span className={`badge ${p.kind === 'patent' ? 'gold' : 'mint'}`} style={{ fontSize: 11 }}>{p.kind === 'patent' ? t('vault_patents') : t('vault_ideas')}</span>
                </div>
                <div className="seal-code" dir="ltr" style={{ marginTop: 5 }}>{s.fingerprint}</div>
                <div className="muted" style={{ fontSize: 12, marginTop: 5 }}>{p.inventors || p.name || '—'} · {new Date(s.sealedAt).toISOString().replace('T', ' ').slice(0, 19)} UTC · v{s.version.toFixed(1)}</div>
              </div>
              <span className={`badge ${s.score >= 9 ? 'mint' : s.score >= 8 ? 'gold' : 'purple'}`} style={{ flex: 'none' }}>{s.score}</span>
            </button>
          ))}
        </div>
      )}

      <div style={{ display: 'flex', gap: 10, marginTop: 20, flexWrap: 'wrap' }}>
        <button className="btn btn-ghost btn-sm" onClick={() => exportRegistry(false)} disabled={!rows.length}><Icon.layers s={15} /> {t('vlt_exp_b')}</button>
        <button className="btn btn-dark btn-sm" onClick={() => exportRegistry(true)} disabled={!rows.length}><Icon.shield s={15} /> {t('vlt_exp_a')}</button>
      </div>

      <Modal open={!!sel} onClose={() => setSel(null)} max={660}>
        {sel && <VaultEntry t={t} L={L} entry={sel} onClose={() => setSel(null)}
          onLog={(action) => writeVault(next => addLog(next, action, sel.s.ref))}
          onReseal={async (m) => {
            const fresh = await sealDisclosure(sel.p, m, sel.s);
            writeVault(next => { next.vault[fresh.ref] = fresh; addLog(next, 'reseal v' + fresh.version.toFixed(1), fresh.ref); });
            setSel({ p: sel.p, s: fresh });
            toast(t('vlt_resealed'));
          }} />}
      </Modal>

      <Modal open={showLog} onClose={() => setShowLog(false)} max={560}>
        <div className="card-pad" style={{ padding: 28 }}>
          <div className="eyebrow"><Icon.clock s={15} /> {t('vlt_log')}</div>
          {log.length === 0 ? <p className="muted" style={{ marginTop: 16, fontSize: 14 }}>{t('vlt_log_empty')}</p> : (
            <div style={{ marginTop: 14, display: 'grid', gap: 0, maxHeight: 380, overflow: 'auto' }}>
              {log.map((l, i) => (
                <div key={i} style={{ padding: '10px 0', borderBottom: '1px solid var(--line)', display: 'flex', justifyContent: 'space-between', gap: 12, fontSize: 13 }}>
                  <span><b>{l.who}</b> · {l.action}{l.ref !== '—' ? ` · ${l.ref}` : ''}</span>
                  <span className="muted" style={{ flex: 'none' }} dir="ltr">{new Date(l.at).toISOString().replace('T', ' ').slice(0, 16)}</span>
                </div>
              ))}
            </div>
          )}
        </div>
      </Modal>
    </div>
  );
}

/* ---------- lock screen: create or enter the vault key ---------- */
function VaultLock({ t, L, hasKey, onOpen }) {
  const [k1, setK1] = React.useState('');
  const [k2, setK2] = React.useState('');
  const [err, setErr] = React.useState(null);

  const submit = async (e) => {
    e.preventDefault();
    if (!hasKey) {
      if (k1.length < 6) return setErr(t('vlt_err_short'));
      if (k1 !== k2) return setErr(t('vlt_err_match'));
      localStorage.setItem(VAULT_KEY_STORE, await sha256Hex('ibtikar::' + k1));
      return onOpen();
    }
    const h = await sha256Hex('ibtikar::' + k1);
    if (h !== localStorage.getItem(VAULT_KEY_STORE)) return setErr(t('vlt_err_key'));
    onOpen();
  };

  return (
    <form className="card card-pad vault-locked" onSubmit={submit}>
      <div className="vault-lock-badge"><Icon.lock s={26} /></div>
      <div className="eyebrow" style={{ justifyContent: 'center', color: 'var(--gold)' }}>{t('vlt_title')}</div>
      <h3 style={{ fontSize: 22, marginTop: 10 }}>{hasKey ? t('vlt_locked') : t('vlt_setup')}</h3>
      <p className="muted" style={{ fontSize: 13.5, marginTop: 10, lineHeight: 1.65, maxWidth: 460, marginInline: 'auto' }}>{hasKey ? t('vlt_locked_d') : t('vlt_setup_d')}</p>
      <div style={{ display: 'grid', gap: 12, maxWidth: 340, margin: '20px auto 0' }}>
        <input className="input" type="password" value={k1} onChange={e => { setK1(e.target.value); setErr(null); }} placeholder={t('vlt_key')} autoComplete="new-password" />
        {!hasKey && <input className="input" type="password" value={k2} onChange={e => { setK2(e.target.value); setErr(null); }} placeholder={t('vlt_key2')} autoComplete="new-password" />}
        {err && <div className="login-err"><Icon.shield s={15} /> {err}</div>}
        <button className="btn btn-primary" disabled={!k1}><Icon.lock s={16} /> {hasKey ? t('vlt_open') : t('vlt_create')}</button>
        {hasKey && <button type="button" className="btn btn-ghost btn-sm" onClick={() => { if (confirm(t('vlt_reset_q'))) { localStorage.removeItem(VAULT_KEY_STORE); location.reload(); } }}>{t('vlt_forgot')}</button>}
      </div>
    </form>
  );
}

/* ---------- one sealed asset ---------- */
function VaultEntry({ t, L, entry, onClose, onLog, onReseal }) {
  const { p, s } = entry;
  const [plain, setPlain] = React.useState(null);
  const [check, setCheck] = React.useState(null);
  const [m, setM] = React.useState(s.metrics);
  const [copied, setCopied] = React.useState(false);
  React.useEffect(() => { setPlain(null); setCheck(null); setM(s.metrics); }, [s.hash]);

  const reveal = () => { setPlain(JSON.parse(b64dec(s.cipher))); onLog('decrypt'); };
  const verify = async () => { setCheck(await verifySeal(s) ? 'ok' : 'bad'); onLog('verify'); };
  const copy = () => { copyText(s.fingerprint); setCopied(true); setTimeout(() => setCopied(false), 1600); };
  const dirty = m.INV !== s.metrics.INV || m.INN !== s.metrics.INN;

  const meta = [
    [t('vlt_f_hash'), s.hash],
    [t('vlt_f_time'), new Date(s.sealedAt).toISOString().replace('T', ' ').slice(0, 19) + ' UTC'],
    [t('vlt_f_ver'), 'v' + s.version.toFixed(1) + (s.prevHash ? ` · ${t('vlt_prev')} ${s.prevHash.slice(0, 8)}` : '')],
  ];

  return (
    <div className="card-pad" style={{ padding: 30 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
        <div>
          <div className="badge gold" style={{ marginBottom: 8 }}><Icon.lock s={13} /> {s.ref}</div>
          <h3 style={{ fontSize: 21 }}>{p.title || '—'}</h3>
          <div className="muted" style={{ fontSize: 13, marginTop: 4 }}>{p.inventors || p.name || '—'}</div>
        </div>
        <button className="btn btn-dark btn-sm" onClick={onClose} style={{ padding: 8 }}><Icon.x s={16} /></button>
      </div>

      <div className="seal-hero">
        <FingerprintGlyph code={s.fingerprint} size={78} />
        <div style={{ minWidth: 0, flex: 1 }}>
          <div className="muted" style={{ fontSize: 12 }}>{t('vlt_f_fp')}</div>
          <div className="seal-code big" dir="ltr">{s.fingerprint}</div>
          <div style={{ display: 'flex', gap: 8, marginTop: 10, flexWrap: 'wrap' }}>
            <button className="btn btn-dark btn-sm" onClick={copy}>{copied ? <><Icon.check s={14} /> {t('copied')}</> : <><Icon.layers s={14} /> {t('copy')}</>}</button>
            <button className="btn btn-primary btn-sm" onClick={() => { window.printSealCertificate(p, s, L); onLog('pdf'); }}><Icon.book s={14} /> {t('vlt_pdf')}</button>
            <button className="btn btn-ghost btn-sm" onClick={verify}><Icon.shield s={14} /> {t('vlt_verify')}</button>
          </div>
          {check && <div className={check === 'ok' ? 'cloud-msg ok' : 'cloud-msg err'} style={{ marginTop: 10 }}>{check === 'ok' ? <><Icon.check s={15} /> {t('vlt_ok')}</> : <><Icon.shield s={15} /> {t('vlt_bad')}</>}</div>}
        </div>
      </div>

      {meta.map(([k, v], i) => (
        <div key={i} style={{ padding: '11px 0', borderBottom: '1px solid var(--line)' }}>
          <div className="muted" style={{ fontSize: 12.5, marginBottom: 3 }}>{k}</div>
          <div className="seal-code" dir="ltr" style={{ wordBreak: 'break-all' }}>{v}</div>
        </div>
      ))}

      <p className="muted" style={{ fontSize: 12.5, lineHeight: 1.65, marginTop: 12 }}>{t('vlt_pdf_d')}</p>

      <div style={{ marginTop: 18 }}>
        <div className="eyebrow"><Icon.target s={14} /> {t('vlt_metrics')}</div>
        <div className="grid g2" style={{ marginTop: 12 }}>
          {[['INV', t('vlt_inv')], ['INN', t('vlt_inn')]].map(([k, lbl]) => (
            <label key={k} className="field">
              <span style={{ fontSize: 13.5, fontWeight: 600 }}>{lbl} · <span dir="ltr" className="seal-code" style={{ display: 'inline' }}>{m[k].toFixed(1)}</span></span>
              <input className="poas-range" type="range" min="1" max="10" step="0.1" value={m[k]} onChange={e => setM(x => ({ ...x, [k]: +e.target.value }))} />
            </label>
          ))}
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 14, gap: 12, flexWrap: 'wrap' }}>
          <div className="chip on"><Icon.spark s={15} /> {t('vlt_score')} {synergyScore(m.INV, m.INN)}</div>
          <button className="btn btn-primary btn-sm" disabled={!dirty} onClick={() => onReseal(m)}><Icon.shield s={15} /> {t('vlt_reseal')}</button>
        </div>
      </div>

      <div style={{ marginTop: 20 }}>
        <div className="eyebrow"><Icon.lock s={14} /> {t('vlt_cipher')}</div>
        {!plain ? (
          <>
            <pre className="cloud-sql cipher" dir="ltr">{s.cipher}</pre>
            <button className="btn btn-ghost btn-sm" style={{ marginTop: 10 }} onClick={reveal}><Icon.eye s={15} /> {t('vlt_decrypt')}</button>
          </>
        ) : (
          <div style={{ marginTop: 8 }}>
            {[[t('pf_field'), plain.field], [t('f_challenge'), plain.problem], [t('pf_abstract'), plain.abstract], [t('pf_novel'), plain.novelty], [t('pf_stage'), plain.stage]].filter(([, v]) => v).map(([k, v], i) => (
              <div key={i} style={{ padding: '11px 0', borderBottom: '1px solid var(--line)' }}>
                <div className="muted" style={{ fontSize: 12.5, marginBottom: 3 }}>{k}</div>
                <div style={{ fontSize: 14.5, lineHeight: 1.6, whiteSpace: 'pre-wrap' }}>{v}</div>
              </div>
            ))}
            <button className="btn btn-dark btn-sm" style={{ marginTop: 12 }} onClick={() => setPlain(null)}><Icon.lock s={15} /> {t('vlt_hide')}</button>
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { InnovationVault, VaultLock, VaultEntry, sealDisclosure, verifySeal, sha256Hex, b64enc, b64dec, synergyScore, metricsFromHash });
