"use client";

import { useEffect, useState } from "react";
import { ApiError, get, post, put } from "@/lib/api";
import { Badge, Field, Notice, Spinner } from "@/components/ui";

type ErgonodeStatus = {
  baseUrl: string;
  logAttribute: string;
  imageAttribute: string;
  language: string;
  graphqlApiKeySet: boolean;
  transport: string;
  configured: boolean;
};
type TestResult = { ok: boolean; transport?: string; detail?: string; error?: string };

export default function ErgonodeSettings() {
  const [data, setData] = useState<ErgonodeStatus | null>(null);
  const [baseUrl, setBaseUrl] = useState("");
  const [logAttribute, setLogAttribute] = useState("");
  const [imageAttribute, setImageAttribute] = useState("");
  const [language, setLanguage] = useState("");
  const [graphqlApiKey, setGraphqlApiKey] = useState("");
  const [errors, setErrors] = useState<string[]>([]);
  const [saved, setSaved] = useState(false);
  const [busy, setBusy] = useState(false);
  const [test, setTest] = useState<TestResult | null>(null);
  const [testBusy, setTestBusy] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);

  function hydrate(d: ErgonodeStatus) {
    setData(d);
    setBaseUrl(d.baseUrl);
    setLogAttribute(d.logAttribute);
    setImageAttribute(d.imageAttribute);
    setLanguage(d.language);
    setGraphqlApiKey(""); // never prefilled — write-only
  }

  useEffect(() => {
    get<ErgonodeStatus>("ergonode").then(hydrate).catch((e) => setLoadError((e as Error).message));
  }, []);

  if (loadError) return <Notice kind="error">Could not load Ergonode config: {loadError}</Notice>;
  if (!data) return <Spinner label="Loading Ergonode configuration…" />;

  const incomplete = !(baseUrl && (graphqlApiKey || data.graphqlApiKeySet));

  async function save(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setBusy(true);
    setSaved(false);
    setErrors([]);
    const payload: Record<string, string> = { baseUrl, logAttribute, imageAttribute, language };
    if (graphqlApiKey !== "") payload.graphqlApiKey = graphqlApiKey; // write-only
    try {
      hydrate(await put<ErgonodeStatus>("ergonode", payload));
      setSaved(true);
    } catch (err) {
      setErrors(err instanceof ApiError && err.errors.length ? err.errors : [(err as Error).message]);
    } finally {
      setBusy(false);
    }
  }

  async function runTest() {
    setTestBusy(true);
    setTest(null);
    try {
      setTest(await post<TestResult>("ergonode/test"));
    } catch (err) {
      setTest({ ok: false, error: (err as Error).message });
    } finally {
      setTestBusy(false);
    }
  }

  return (
    <section aria-labelledby="ergonode-h" className="space-y-6">
      <h2 id="ergonode-h" className="flex items-center gap-2 text-xl font-semibold text-slate-900">
        Ergonode connection
        <Badge kind="ok">GraphQL</Badge>
      </h2>
      <p className="-mt-4 text-sm text-slate-600">
        The product source/sink — the live Ergonode instance (digtag-staging). The integration uses the Ergonode
        {" "}<strong>GraphQL API</strong>; paste an API key <strong>with write access</strong> (created in Ergonode →
        System Settings → API keys) to connect. Changes apply without a redeploy.
      </p>

      {saved && <Notice kind="success">Ergonode configuration saved.</Notice>}
      {errors.length > 0 && <Notice kind="error"><ul className="list-disc pl-5">{errors.map((er, i) => <li key={i}>{er}</li>)}</ul></Notice>}
      {incomplete && (
        <Notice kind="info">A base URL and a GraphQL API key (with write access) are required before the connection works.</Notice>
      )}

      <form onSubmit={save} className="space-y-6">
        <div className="card grid gap-5 sm:grid-cols-2">
          <Field label="Base URL" htmlFor="erg-base" hint="e.g. https://digtag-staging.ergonode.cloud">
            <input id="erg-base" value={baseUrl} onChange={(e) => setBaseUrl(e.target.value)} className="input" autoComplete="off" />
          </Field>
          <Field label="Content language" htmlFor="erg-lang" hint="Instance language for reads/writes, e.g. en_GB or de_CH.">
            <input id="erg-lang" value={language} onChange={(e) => setLanguage(e.target.value)} className="input" autoComplete="off" />
          </Field>
          <Field label="ai-product-log attribute code" htmlFor="erg-log" hint="File-type attribute that holds the CSV.">
            <input id="erg-log" value={logAttribute} onChange={(e) => setLogAttribute(e.target.value)} className="input font-mono text-xs" autoComplete="off" />
          </Field>
          <Field label="Images attribute code" htmlFor="erg-img" hint="Gallery-type attribute that sourced/generated images are written to.">
            <input id="erg-img" value={imageAttribute} onChange={(e) => setImageAttribute(e.target.value)} className="input font-mono text-xs" autoComplete="off" />
          </Field>
          <Field
            label="GraphQL API key (X-API-KEY)"
            htmlFor="erg-gql"
            hint={
              data.graphqlApiKeySet
                ? "A key is stored. Leave blank to keep it."
                : "Create an API key WITH write access in Ergonode → System Settings → API keys, then paste it here."
            }
          >
            <input
              id="erg-gql"
              type="password"
              value={graphqlApiKey}
              onChange={(e) => setGraphqlApiKey(e.target.value)}
              placeholder={data.graphqlApiKeySet ? "•••••••• (set)" : "not set"}
              className="input"
              autoComplete="new-password"
            />
          </Field>
        </div>

        <p className="text-xs text-slate-500">
          Status: {data.configured ? <Badge kind="ok">configured</Badge> : <Badge kind="warn">incomplete</Badge>}{" "}
          · API key {data.graphqlApiKeySet ? "set" : "not set"}. The key is write-only — stored in the config store for the
          PoC; move it to the Digt secrets store in production.
        </p>

        <div className="flex flex-wrap gap-3">
          <button type="submit" className="btn-primary" disabled={busy}>{busy ? "Saving…" : "Save Ergonode connection"}</button>
          <button type="button" className="btn-secondary" onClick={runTest} disabled={testBusy}>{testBusy ? "Testing…" : "Test connection"}</button>
        </div>
      </form>

      {test && (
        <div className="card" aria-live="polite">
          <h3 className="mb-1 font-semibold text-slate-900">
            Connection test {test.ok ? <Badge kind="ok">OK</Badge> : <Badge kind="danger">failed</Badge>}
          </h3>
          <p className="text-sm text-slate-600">{test.detail || test.error}</p>
        </div>
      )}

      <Notice kind="info">
        Ergonode data operations — the <strong>attribute overview</strong> and the <strong>category-tree</strong> &amp;
        <strong> attribute</strong> imports — live under <strong>Services → Attributes</strong>.
      </Notice>
    </section>
  );
}
