/* global React, Icon, API */
const { useEffect: useEffectSettings, useState: useStateSettings } = React;

/**
 * SettingsView — "Configurações" tab.
 *
 * Lê o schema declarativo do backend (`GET /api/settings/schema`) e gera
 * formulários para cada provider (mutual, mb, talkhub, otc). Salva via
 * `PUT /api/settings/:provider` e valida via `POST /api/settings/:provider/test`.
 *
 * Secrets (is_secret=true) são exibidos como fingerprint `••••XXXX (len=N)`
 * vindos do servidor; campos vazios significam "não trocar".
 */
const SettingsView = ({ onShowToast }) => {
  const [schema, setSchema] = useStateSettings(null);
  const [values, setValues] = useStateSettings({});       // server-side current
  const [drafts, setDrafts] = useStateSettings({});       // local edits per provider
  const [busy, setBusy] = useStateSettings({});           // {provider: bool}
  const [results, setResults] = useStateSettings({});     // last test result per provider
  const [diag, setDiag] = useStateSettings(null);

  const load = async () => {
    const [sc, st, dg] = await Promise.all([
      API.settingsSchema(), API.settingsAll(), API.diag(),
    ]);
    if (sc.ok) setSchema(sc.schema);
    if (st.ok) setValues(st.settings);
    if (dg) setDiag(dg);
    setDrafts({});
  };

  useEffectSettings(() => { load(); }, []);

  const draftFor = (provider) => drafts[provider] || {};
  const setDraftField = (provider, key, val) => {
    setDrafts((d) => ({ ...d, [provider]: { ...(d[provider] || {}), [key]: val } }));
  };

  const save = async (provider) => {
    const kv = draftFor(provider);
    if (Object.keys(kv).length === 0) {
      onShowToast && onShowToast("Nada para salvar", "info");
      return;
    }
    setBusy((b) => ({ ...b, [provider]: true }));
    const res = await API.settingsSave(provider, kv);
    setBusy((b) => ({ ...b, [provider]: false }));
    if (res.ok) {
      onShowToast && onShowToast(`${provider} salvo`, "check");
      await load();
    } else {
      onShowToast && onShowToast(res.error || "Falha ao salvar", "info");
    }
  };

  const test = async (provider) => {
    setBusy((b) => ({ ...b, [provider]: true }));
    const res = await API.settingsTest(provider);
    setBusy((b) => ({ ...b, [provider]: false }));
    setResults((r) => ({ ...r, [provider]: res }));
    onShowToast && onShowToast(
      res.ok ? `${provider}: conexão ok` : `${provider}: ${res.error || "falha"}`,
      res.ok ? "check" : "info",
    );
  };

  if (!schema) {
    return <div className="card"><div className="card-pad">Carregando configurações…</div></div>;
  }

  const renderProvider = (provider, ps) => {
    const current = values[provider] || {};
    const draft = draftFor(provider);
    const lastTest = results[provider];
    return (
      <div className="card mb-16" key={provider}>
        <div className="card-pad">
          <div className="row-between mb-12">
            <div>
              <h2 className="card-h2">{ps.title}</h2>
              <p className="card-sub" style={{margin: 0}}>{ps.description}</p>
            </div>
            <div className="row" style={{gap: 8}}>
              <button className="btn btn-ghost" style={{height: 36}} onClick={() => test(provider)} disabled={busy[provider]}>
                {busy[provider] ? "…" : "Testar conexão"}
              </button>
              <button className="btn btn-primary" style={{height: 36}} onClick={() => save(provider)} disabled={busy[provider] || Object.keys(draft).length === 0}>
                Salvar
              </button>
            </div>
          </div>

          {ps.fields.map((f) => {
            const cur = current[f.key];
            const draftVal = draft[f.key];
            const placeholder = f.secret
              ? (cur || "(não definido — preencha para definir)")
              : (cur ?? f.default ?? "");
            return (
              <div key={f.key} className="mb-12">
                <label className="label">
                  {f.label} {f.required && <span style={{color: "var(--red)"}}>*</span>}
                  <span style={{fontWeight: 400, color: "var(--ink-400)", fontSize: 11, marginLeft: 8}}>{f.key}</span>
                </label>
                <input
                  className="input"
                  type={f.secret ? "password" : "text"}
                  placeholder={placeholder}
                  value={draftVal ?? (f.secret ? "" : (cur ?? ""))}
                  onChange={(e) => setDraftField(provider, f.key, e.target.value)}
                  autoComplete="off"
                />
                {f.secret && cur && (
                  <div style={{fontSize: 11, color: "var(--ink-400)", marginTop: 4}}>Atual: <code>{cur}</code> · deixe vazio para manter</div>
                )}
              </div>
            );
          })}

          {lastTest && (
            <pre style={{marginTop: 12}}>{JSON.stringify(lastTest, null, 2)}</pre>
          )}
        </div>
      </div>
    );
  };

  return (
    <div>
      <div className="card mb-16">
        <div className="card-pad">
          <h2 className="card-h2">Status das integrações</h2>
          <p className="card-sub">Resultado do <code>/api/diag</code> em tempo real (Mutual auth, MB OAuth, MB tickers públicos, Postgres).</p>
          {diag && (
            <div className="market-row" style={{gridTemplateColumns: "repeat(4, 1fr)"}}>
              {Object.entries(diag.checks || {}).map(([k, v]) => (
                <div className="market-cell" key={k}>
                  <div className="l">{k.replace(/_/g, " ")}</div>
                  <div className="v" style={{color: v.ok ? "var(--green)" : "var(--red)"}}>
                    {v.ok ? "OK" : `${v.status || "fail"}`}
                  </div>
                  {!v.ok && v.error && <div style={{fontSize: 11, color: "var(--ink-400)", marginTop: 4}}>{v.error}</div>}
                </div>
              ))}
            </div>
          )}
          <button className="btn btn-ghost mt-12" style={{height: 36}} onClick={load}>
            <Icon.Refresh size={14} /> Recarregar
          </button>
        </div>
      </div>

      {Object.entries(schema).map(([provider, ps]) => renderProvider(provider, ps))}

      <div className="info info-amber">
        <span className="info-icon"><Icon.Alert /></span>
        <div>
          <b>Como funciona</b>
          As credenciais são persistidas em <code>provider_credentials</code> no Postgres
          (schema <code>microotc</code>) e sobrescrevem as variáveis de ambiente.
          Secrets aparecem só pelo fingerprint <code>••••últimos4 (len=N)</code>; deixe o
          campo em branco para manter o valor atual.
        </div>
      </div>
    </div>
  );
};

window.SettingsView = SettingsView;
