// AvailabilityGrid — modal showing (language × mode) availability for a pericope.
// State per cell: 'exists' (free, clickable), 'commission' (priced), 'unavail' (grayed).
// Deterministic per pericope so pricing stays stable between opens.

function AvailabilityGrid({ target, onClose, onOpen, onCommission }) {
  if (!target) return null;
  const w = window.useWallet ? window.useWallet() : null;
  const ref = target;

  const label = (ref.book || 'ref').toUpperCase() +
    ' ' + (ref.chap || '') +
    (ref.v1 ? ':' + ref.v1 : '') +
    (ref.v2 ? '–' + ref.v2 : '');

  // Target languages
  const LANGS = [
    { iso:'EN',  name:'English' },
    { iso:'ES',  name:'Spanish (LA)' },
    { iso:'CA',  name:'Catalan' },
    { iso:'PT',  name:'Portuguese (BR)' },
    { iso:'FR',  name:'French' },
    { iso:'DE',  name:'German' },
    { iso:'ZH',  name:'Mandarin (Simp.)' },
    { iso:'AR',  name:'Arabic (MSA)' },
    { iso:'SW',  name:'Swahili' },
    { iso:'ID',  name:'Indonesian' },
    { iso:'TL',  name:'Tagalog' },
    { iso:'QU',  name:'Quechua (Ayacucho)' },
  ];
  const MODES = [
    { code:'C', label:'Mode C',       note:'Readable translation' },
    { code:'B', label:'Mode B',       note:'Analytical apparatus' },
    { code:'D', label:'Mode D',       note:'Layered annotations' },
  ];

  // Deterministic hash per (ref × lang × mode)
  function h(s) {
    let x = 2166136261;
    for (let i=0;i<s.length;i++){ x ^= s.charCodeAt(i); x = Math.imul(x, 16777619); }
    return (x >>> 0) / 0xffffffff;
  }
  const key = (ref.book || '') + (ref.chap || '') + ':' + (ref.v1 || '');

  function cellState(lang, mode) {
    const r1 = h(key + '|' + lang.iso + '|' + mode.code + '|1');
    const r2 = h(key + '|' + lang.iso + '|' + mode.code + '|2');

    // Featured pericope: Rom 8:28 (whatever v1 parses) gets rich coverage
    const featured = ref.book === 'rom' && String(ref.chap) === '8';

    // Unavailable in very low-resource + Mode B
    if (mode.code === 'B' && ['QU','TL'].includes(lang.iso) && r1 > 0.55) return 'unavail';

    // Heuristic: EN/ES usually exist for Mode C, rarely missing
    if (mode.code === 'C') {
      if (['EN','ES','CA','FR','DE','PT'].includes(lang.iso)) return featured || r1 < 0.78 ? 'exists' : 'commission';
      return r1 < 0.35 ? 'exists' : 'commission';
    }
    if (mode.code === 'B') {
      if (lang.iso === 'EN') return featured || r1 < 0.72 ? 'exists' : 'commission';
      return r1 < 0.22 ? 'exists' : 'commission';
    }
    if (mode.code === 'D') {
      if (lang.iso === 'EN') return featured || r1 < 0.55 ? 'exists' : 'commission';
      return r2 < 0.15 ? 'exists' : 'commission';
    }
    return 'commission';
  }

  function cellDetail(lang, mode, state) {
    if (state === 'exists') return 'Open · free';
    if (state === 'unavail') return '— not yet planned';
    // Credit cost per pericope by mode — derived from API-cost × markup (1 cr = $0.10).
    // Mode C (readable translation) ≈ 2–3 cr · Mode B (full analysis) ≈ 11–13 cr · Mode D (layered) ≈ 5–7 cr.
    const base = { C: 2, B: 11, D: 5 }[mode.code] || 3;
    const r = Math.floor(h(lang.iso + mode.code) * 3);
    const credits = base + r;
    return credits + ' cr · ' + ({ C: '12h', B: '3–5d', D: '48h' }[mode.code]);
  }
  function cellCredits(lang, mode) {
    const base = { C: 2, B: 11, D: 5 }[mode.code] || 3;
    const r = Math.floor(h(lang.iso + mode.code) * 3);
    return base + r;
  }

  return React.createElement('div', {
    className: 'amos-modal-backdrop',
    onClick: onClose
  },
    React.createElement('div', {
      className: 'amos-modal',
      onClick: (e) => e.stopPropagation()
    },
      React.createElement('div', { className: 'amos-modal-head' },
        React.createElement('div', null,
          React.createElement('div', { className: 'mh-kicker' }, 'Commission · availability'),
          React.createElement('h3', null, 'What exists — what would be ', React.createElement('em', null, 'new')),
          React.createElement('div', { className: 'mh-sub' },
            'For ', React.createElement('b', null, label), ': green cells already exist in the library and open free; amber cells can be commissioned for the credit cost shown (1 credit = $0.10). Gray cells are not yet planned.'
          )
        ),
        React.createElement('button', { className: 'amos-icon-btn', onClick: onClose },
          window.I.x(16)
        )
      ),

      React.createElement('div', { className: 'avail-body' },
        React.createElement('table', { className: 'avail-table' },
          React.createElement('thead', null,
            React.createElement('tr', null,
              React.createElement('th', null, 'Target language'),
              ...MODES.map(m => React.createElement('th', { key: m.code, className: 'mode' },
                m.label,
                React.createElement('div', {
                  style: { font:'400 10px Roboto', letterSpacing:0, textTransform:'none', color:'rgba(6,31,39,.45)', marginTop:2 }
                }, m.note)
              ))
            )
          ),
          React.createElement('tbody', null,
            LANGS.map(l => React.createElement('tr', { key: l.iso },
              React.createElement('td', { className: 'lang-cell' },
                React.createElement('span', { className: 'iso' }, l.iso),
                l.name
              ),
              ...MODES.map(m => {
                const st = cellState(l, m);
                const detail = cellDetail(l, m, st);
                return React.createElement('td', { key: m.code, style: { textAlign:'center' } },
                  React.createElement('div', {
                    className: 'avail-cell ' + st,
                    onClick: (e) => {
                      e.stopPropagation();
                      if (st === 'exists') onOpen && onOpen({ ref, lang: l, mode: m });
                      else if (st === 'commission') {
                        const credits = cellCredits(l, m);
                        if (w) {
                          w.requestSpend({
                            credits,
                            label: label + ' · ' + l.name + ' · Mode ' + m.code,
                            description: m.note + ' in ' + l.name + '. Delivered as a library contribution visible to all readers.',
                            onConfirm: () => onCommission && onCommission({ ref, lang: l, mode: m, credits })
                          });
                        } else {
                          onCommission && onCommission({ ref, lang: l, mode: m, credits });
                        }
                      }
                    }
                  },
                    React.createElement('div', { className: 'top' },
                      st === 'exists' ? 'Exists ↗' :
                      st === 'commission' ? 'Commission' :
                      'Unavailable'
                    ),
                    React.createElement('div', { className: 'bot' }, detail)
                  )
                );
              })
            ))
          )
        )
      ),

      React.createElement('div', { className: 'avail-foot' },
        React.createElement('div', { className: 'af-legend' },
          React.createElement('span', { className: 'lg' }, React.createElement('span', { className: 'sw e' }), 'Exists'),
          React.createElement('span', { className: 'lg' }, React.createElement('span', { className: 'sw c' }), 'Commissionable'),
          React.createElement('span', { className: 'lg' }, React.createElement('span', { className: 'sw u' }), 'Unavailable'),
          w && React.createElement('span', { className: 'lg wallet-readout' },
            React.createElement('span', { className: 'sw cr' }),
            'Wallet: ', React.createElement('b', null, w.balance.toLocaleString(), ' cr')
          )
        ),
        React.createElement('div', null,
          'Prices shown in credits. Commissions become ',
          React.createElement('b', null, 'library contributions'),
          ' — visible to all readers.'
        )
      )
    )
  );
}
Object.assign(window, { AvailabilityGrid });
