import { useEffect, useMemo, useState } from "react";
import type { FormEvent } from "react";
import { authorizedHeaders, authTokenFromStorage, jsonHeaders, api } from "./api";

type PublicWebhook = {
  id: string;
  label: string;
  description?: string;
  method: string;
  required_roles: string[];
  confirmation_required: boolean;
};

type RunResult =
  | { kind: "idle" }
  | { kind: "running" }
  | { kind: "success"; responseStatus: number | null; runId: string }
  | { kind: "error"; message: string };

type WebhookFormTabProps = {
  webhookId: string;
  sessionId: string;
  onBack: () => void;
};

const labelsEn = {
  title: "Run webhook",
  description: "Description",
  requiredRoles: "Required roles",
  confirmation: "Requires confirmation",
  method: "Method",
  payload: "Payload (optional JSON)",
  payloadHelp: "These fields are merged with the backend template. Available variables: {user}, {session}, {message}.",
  run: "Run",
  running: "Running...",
  resultOk: "Webhook executed",
  resultErr: "Failed to execute",
  httpStatus: "HTTP",
  runId: "Audit ID",
  back: "Back to chat",
  notFound: "Webhook not found or insufficient permissions",
  loading: "Loading webhook...",
  user: "User",
  session: "Session",
};

const detectLanguage = (): "en" => "en";

const WebhookFormTabInner = ({ webhookId, sessionId, onBack }: WebhookFormTabProps) => {
  const [labels] = useState(() => labelsEn);
  const [webhook, setWebhook] = useState<PublicWebhook | null>(null);
  const [payload, setPayload] = useState("{}");
  const [result, setResult] = useState<RunResult>({ kind: "idle" });
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    void (async () => {
      try {
        const data = await api<{ items: PublicWebhook[] }>("/api/webhooks");
        const found = data.items.find((item) => item.id === webhookId);
        if (!found) {
          setError(labels.notFound);
          return;
        }
        setWebhook(found);
      } catch (err) {
        console.error(err);
        setError(labels.notFound);
      }
    })();
  }, [webhookId, labels.notFound]);

  const submit = async (event: FormEvent) => {
    event.preventDefault();
    if (!webhook) return;

    if (webhook.confirmation_required) {
      const ok = window.confirm(`Run ${webhook.label}?`);
      if (!ok) return;
    }

    let parsed: Record<string, unknown> = {};
    if (payload.trim().length > 0) {
      try {
        const value = JSON.parse(payload);
        if (value && typeof value === "object" && !Array.isArray(value)) {
          parsed = value as Record<string, unknown>;
        }
      } catch {
        setResult({ kind: "error", message: "Payload is not valid JSON" });
        return;
      }
    }

    setResult({ kind: "running" });
    try {
      const response = await fetch(`/api/webhooks/${webhook.id}/run`, {
        method: "POST",
        headers: jsonHeaders(),
        body: JSON.stringify({
          sessionId,
          confirmed: true,
          lastUserMessage: undefined,
          payload: parsed,
        }),
      });
      if (!response.ok) {
        const detail = await response.text().catch(() => "");
        throw new Error(`http_${response.status}: ${detail.slice(0, 200)}`);
      }
      const body = (await response.json()) as { id: string; response_status: number | null };
      setResult({ kind: "success", responseStatus: body.response_status, runId: body.id });
    } catch (err) {
      console.error(err);
      const message = err instanceof Error ? err.message : "error";
      setResult({ kind: "error", message });
    }
  };

  const tokenInfo = useMemo(() => {
    const t = authTokenFromStorage();
    return t ? `${t.slice(0, 12)}…` : labels.notFound;
  }, [labels.notFound]);

  if (error) {
    return (
      <main className="formTab error">
        <h1>{labels.title}</h1>
        <p className="muted">{error}</p>
        <button type="button" onClick={onBack}>{labels.back}</button>
      </main>
    );
  }

  if (!webhook) {
    return (
      <main className="formTab loading">
        <h1>{labels.title}</h1>
        <p className="muted">{labels.loading}</p>
      </main>
    );
  }

  return (
    <main className="formTab">
      <header className="formTabHeader">
        <div>
          <small>SIC</small>
          <h1>{webhook.label}</h1>
        </div>
        <button type="button" onClick={onBack}>{labels.back}</button>
      </header>

      <dl className="formTabMeta">
        {webhook.description ? (
          <div>
            <dt>{labels.description}</dt>
            <dd>{webhook.description}</dd>
          </div>
        ) : null}
        <div>
          <dt>{labels.method}</dt>
          <dd><code>{webhook.method}</code></dd>
        </div>
        <div>
          <dt>{labels.requiredRoles}</dt>
          <dd>{webhook.required_roles.join(", ")}</dd>
        </div>
        <div>
          <dt>{labels.confirmation}</dt>
          <dd>{webhook.confirmation_required ? "Yes" : "No"}</dd>
        </div>
        <div>
          <dt>{labels.session}</dt>
          <dd><code>{sessionId.slice(0, 8)}…</code></dd>
        </div>
        <div>
          <dt>{labels.user}</dt>
          <dd><code>{tokenInfo}</code></dd>
        </div>
      </dl>

      <form onSubmit={submit} className="formTabForm">
        <label>
          <span>{labels.payload}</span>
          <textarea
            onChange={(e) => setPayload(e.target.value)}
            rows={8}
            spellCheck={false}
            value={payload}
          />
        </label>
        <small className="muted">{labels.payloadHelp}</small>
        <button
          className="formTabRun"
          disabled={result.kind === "running"}
          type="submit"
        >
          {result.kind === "running" ? labels.running : labels.run}
        </button>
      </form>

      {result.kind === "success" ? (
        <section className="formTabResult success">
          <strong>{labels.resultOk}</strong>
          <small>{labels.httpStatus}: {result.responseStatus ?? "—"}</small>
          <small>{labels.runId}: <code>{result.runId}</code></small>
        </section>
      ) : null}
      {result.kind === "error" ? (
        <section className="formTabResult error">
          <strong>{labels.resultErr}</strong>
          <small>{result.message}</small>
        </section>
      ) : null}
    </main>
  );
};

// Read query params helper for the main App.
export const getWebhookFormTabParams = () => {
  const params = new URLSearchParams(window.location.search);
  const webhook = params.get("webhook");
  const session = params.get("session");
  if (!webhook || !session) return null;
  return { webhookId: webhook, sessionId: session };
};

const WebhookFormTab = WebhookFormTabInner;
export default WebhookFormTab;
export type { WebhookFormTabProps };
