// Integrations — configure + test external API connections.
// Talks to /api/integrations. Secrets are masked on display; new values are
// accepted on save, mask placeholders (••••abcd) are preserved server-side.

function IntegrationsScreen() {
  const [list, setList] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [openSlug, setOpenSlug] = React.useState(null);
  const [toast, setToast] = React.useState(null);

  async function reload() {
    setLoading(true);
    const r = await fetch('/api/integrations', { credentials: 'same-origin' });
    if (r.status === 403) {
      setLoading(false);
      return;
    }
    const j = await r.json().catch(() => ({ integrations: [] }));
    setList(j.integrations || []);
    setLoading(false);
  }
  React.useEffect(() => { reload(); }, []);

  const current = list.find(i => i.slug === openSlug);

  const iconFor = {
    wordpress:   <IntegIco.wordpress/>,
    woocommerce: <IntegIco.woo/>,
    anthropic:   <IntegIco.anthropic/>,
    superfaktura:<IntegIco.invoice/>,
    goodwe:      <IntegIco.sun/>,
    clickup:     <IntegIco.task/>,
    smtp:        <Ico.mail/>,
  };

  const statusChip = (s) => {
    const map = {
      connected:      <span className="chip green dot">Pripojené</span>,
      configured:     <span className="chip amber dot">Nastavené · netestované</span>,
      error:          <span className="chip red dot">Chyba</span>,
      not_connected:  <span className="chip gray dot">Nepripojené</span>,
    };
    return map[s] || map.not_connected;
  };

  return (
    <AppShell active="integrations" crumbs={['Administrácia', 'Integrácie']}>
      {toast && <Toast kind={toast.kind} onClose={() => setToast(null)}>{toast.text}</Toast>}

      <div className="page-head">
        <div>
          <h1>Integrácie</h1>
          <p>API kľúče a prepojenia na externé systémy. Tajné polia sú šifrované pri uložení.</p>
        </div>
        <div className="page-head-actions">
          <button className="btn" onClick={reload}><Ico.upload/>Obnoviť</button>
        </div>
      </div>

      {loading ? (
        <div className="muted">Načítavam…</div>
      ) : list.length === 0 ? (
        <div className="card" style={{padding:20}}>
          <div className="muted">Nemáte oprávnenie na zobrazenie integrácií, alebo ešte nič nie je nastavené.</div>
        </div>
      ) : (
        <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(280px, 1fr))', gap:12}}>
          {list.map(i => (
            <button
              key={i.slug}
              onClick={() => setOpenSlug(i.slug)}
              className="mod-tile"
              style={{textAlign:'left', cursor:'pointer', background:'#fff', border:'1px solid var(--border)', color:'inherit', font:'inherit'}}
            >
              <div className="hstack">
                <div className="mod-ico">{iconFor[i.slug] || <Ico.sparkles/>}</div>
                <div style={{flex:1, minWidth:0}}>
                  <h4>{i.label}</h4>
                  <div className="small muted" style={{marginTop:2}}>{statusChip(i.status)}</div>
                </div>
                <Ico.chevRight style={{color:'var(--ink-400)'}}/>
              </div>
              <p style={{margin:0}}>{i.description}</p>
              {i.last_sync && (
                <div className="small muted">Naposledy úspešne: {new Date(i.last_sync * 1000).toLocaleString('sk-SK')}</div>
              )}
            </button>
          ))}
        </div>
      )}

      {current && (
        <IntegrationModal
          integration={current}
          onClose={() => setOpenSlug(null)}
          onSaved={() => { reload(); }}
          notify={(kind, text) => setToast({ kind, text })}
        />
      )}
    </AppShell>
  );
}

function IntegrationModal({ integration, onClose, onSaved, notify }) {
  const [values, setValues] = React.useState(() => {
    const init = {};
    for (const f of integration.fields) {
      // start blank for secret fields so user sees they can overwrite, and with current value for others
      init[f.key] = f.secret ? '' : (f.value || '');
    }
    return init;
  });
  const [busy, setBusy] = React.useState(null);
  const [testResult, setTestResult] = React.useState(null);

  function setField(k, v) {
    setValues(prev => ({ ...prev, [k]: v }));
    setTestResult(null);
  }

  async function save() {
    setBusy('save');
    // For secret fields left empty, omit from payload → backend preserves existing.
    const payload = {};
    for (const f of integration.fields) {
      if (f.secret && !values[f.key]) continue;
      payload[f.key] = values[f.key];
    }
    const r = await fetch(`/api/integrations/${integration.slug}`, {
      method: 'PATCH',
      credentials: 'same-origin',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ fields: payload }),
    });
    const j = await r.json().catch(() => ({}));
    setBusy(null);
    if (r.ok) {
      notify('success', 'Uložené.');
      onSaved();
    } else {
      notify('error', j.error || 'Nepodarilo sa uložiť.');
    }
  }

  async function test() {
    setBusy('test');
    setTestResult(null);
    // Save first so backend has the new values to test against
    const payload = {};
    for (const f of integration.fields) {
      if (f.secret && !values[f.key]) continue;
      payload[f.key] = values[f.key];
    }
    const save = await fetch(`/api/integrations/${integration.slug}`, {
      method: 'PATCH', credentials: 'same-origin',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ fields: payload }),
    });
    if (!save.ok) {
      setBusy(null);
      setTestResult({ ok: false, error: 'Nepodarilo sa uložiť pred testom.' });
      return;
    }
    const r = await fetch(`/api/integrations/${integration.slug}/test`, {
      method: 'POST', credentials: 'same-origin',
    });
    const j = await r.json().catch(() => ({ ok: false, error: 'Chyba servera' }));
    setBusy(null);
    setTestResult(j);
    if (j.ok) onSaved();
  }

  async function disconnect() {
    if (!confirm(`Odpojiť ${integration.label}? Uložené API údaje sa zmažú.`)) return;
    setBusy('disc');
    await fetch(`/api/integrations/${integration.slug}/disconnect`, {
      method: 'POST', credentials: 'same-origin',
    });
    setBusy(null);
    notify('success', 'Odpojené.');
    onSaved();
    onClose();
  }

  return (
    <Modal
      title={integration.label}
      width={560}
      onClose={onClose}
      footer={
        <>
          {integration.status !== 'not_connected' && (
            <button className="btn btn-danger btn-sm" onClick={disconnect} disabled={!!busy} style={{marginRight:'auto'}}>
              Odpojiť
            </button>
          )}
          <button className="btn" onClick={onClose} disabled={!!busy}>Zavrieť</button>
          <button className="btn btn-sm" onClick={test} disabled={!!busy}>
            {busy === 'test' ? 'Testujem…' : 'Otestovať spojenie'}
          </button>
          <button className="btn btn-primary btn-sm" onClick={save} disabled={!!busy}>
            {busy === 'save' ? 'Ukladám…' : 'Uložiť'}
          </button>
        </>
      }
    >
      <div className="small muted" style={{marginBottom:12}}>{integration.description}</div>

      {testResult && (
        <div className="auth-alert"
          style={testResult.ok
            ? {background:'var(--green-100)', color:'#135e37', borderColor:'rgba(42,157,95,0.3)'}
            : {}}
          role="alert">
          {testResult.ok ? <Ico.check/> : <Ico.dots/>}
          <span>{testResult.ok ? (testResult.message || 'Spojenie je platné.') : (testResult.error || 'Test zlyhal.')}</span>
        </div>
      )}

      <div className="vstack" style={{gap:12}}>
        {integration.fields.map(f => (
          <div key={f.key} className="field">
            <label>{f.label}{f.required && <span style={{color:'var(--red-500)'}}> *</span>}</label>
            <input
              className="input"
              type={f.type === 'password' ? 'password' : f.type}
              value={values[f.key] ?? ''}
              onChange={e => setField(f.key, e.target.value)}
              placeholder={f.secret && f.has_value ? f.value : (f.placeholder || '')}
              autoComplete={f.type === 'password' ? 'new-password' : 'off'}
              spellCheck="false"
            />
            {f.secret && f.has_value && (
              <div className="small muted">Uložená hodnota: <span className="mono">{f.value}</span>. Pre zmenu zadajte novú.</div>
            )}
            {f.help && <div className="small muted">{f.help}</div>}
          </div>
        ))}
      </div>
    </Modal>
  );
}

// Brand / concept icons for integration tiles. Kept small, stroke-only where possible.
const IntegIco = {
  wordpress: (p={}) => <svg {...p} width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2c3 3 4 6 4 10s-1 7-4 10M12 2c-3 3-4 6-4 10s1 7 4 10"/></svg>,
  woo:       (p={}) => <svg {...p} width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 8h16l-2 9H6l-1-5H2"/><circle cx="9" cy="20" r="1.2"/><circle cx="16" cy="20" r="1.2"/></svg>,
  anthropic: (p={}) => <svg {...p} width="22" height="22" viewBox="0 0 24 24" fill="currentColor"><path d="M13.5 3h3l5 18h-3l-1.2-4.4h-6.6L9.5 21h-3zm-1.1 8 2.6 0 -1.3-4.8zM3 3h3v18H3z"/></svg>,
  invoice:   (p={}) => <svg {...p} width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M6 2h10l4 4v16H6z"/><path d="M9 10h6M9 14h6M9 18h4"/></svg>,
  sun:       (p={}) => <svg {...p} width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>,
  task:      (p={}) => <svg {...p} width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="m8 12 3 3 5-6"/></svg>,
};

Object.assign(window, { IntegrationsScreen });
