"use client";

import { useEffect, useState } from "react";
import { useLocale, useTranslations } from "next-intl";
import type { EngineConfigField } from "@omniroute/open-sse/services/compression/engines/types";
import { EngineConfigForm } from "@/shared/components/compression/EngineConfigForm";

// ── Types ─────────────────────────────────────────────────────────────────

interface EngineEntry {
  id: string;
  name: string;
  description: string;
  icon: string;
  stackable: boolean;
  stackPriority: number;
  metadata: { description?: string; [key: string]: unknown };
  configSchema: EngineConfigField[];
}

// Engines whose detailed config has a dedicated sub-object in the compression
// settings store. The on/off + level for ALL engines now live in the panel
// (/dashboard/context/settings, the `engines` map); only these have a place to
// persist the extra per-engine fields edited on this page. session-dedup and ccr
// joined headroom in #8388 (they previously rendered a real, editable detail form
// with no Save affordance — edits vanished on reload). Other structural engines
// (lite, llmlingua, relevance) still have no dedicated sub-object — their page
// keeps the detail form + preview but has nothing extra to persist yet.
const SETTINGS_SUBOBJECT: Record<string, string> = {
  aggressive: "aggressive",
  ultra: "ultra",
  headroom: "headroom",
  "session-dedup": "sessionDedup",
  ccr: "ccr",
};

interface CompressionSettings {
  engines?: Record<string, { enabled?: boolean; level?: string }>;
  [key: string]: unknown;
}

interface Analytics {
  engineId: string;
  runs: number;
  tokensSaved: number;
  avgSavingsPercent: number;
  days: number;
}

interface PreviewDiffSegment {
  type?: string;
  value?: string;
  text?: string;
  content?: string;
  original?: string;
  compressed?: string;
  before?: string;
  after?: string;
}

interface PreviewResult {
  original?: string;
  compressed?: string;
  originalTokens: number;
  compressedTokens: number;
  savingsPct: number;
  diff?: PreviewDiffSegment[];
}

// ── Default preview sample ────────────────────────────────────────────────

const ENGINE_ICON_ALIASES: Record<string, string> = {
  brain: "psychology",
};

// ── Sub-components ────────────────────────────────────────────────────────

function StatCard({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex flex-col gap-0.5 rounded-lg border border-border bg-surface p-3">
      <span className="text-xs text-text-muted">{label}</span>
      <span className="text-lg font-semibold text-text">{value}</span>
    </div>
  );
}

function renderDiffSegment(
  segment: PreviewDiffSegment,
  index: number,
  translateLabel: (label: string) => string
) {
  const label = segment.type ?? "change";
  const text =
    segment.value ??
    segment.text ??
    segment.content ??
    [segment.original ?? segment.before, segment.compressed ?? segment.after]
      .filter(Boolean)
      .join(" → ") ??
    "";

  return (
    <div key={`${label}-${index}`} className="rounded border border-border bg-background p-2">
      <span className="mr-2 rounded bg-muted px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-text-muted">
        {translateLabel(label)}
      </span>
      <span className="whitespace-pre-wrap break-words text-text">{text}</span>
    </div>
  );
}

// ── Main component ────────────────────────────────────────────────────────

export function EngineConfigPage({ engineId }: { engineId: string }) {
  const locale = useLocale();
  const t = useTranslations("compressionEngineConfig");
  // ── Data state ──────────────────────────────────────────────────────────
  const [engine, setEngine] = useState<EngineEntry | null>(null);
  const [configState, setConfigState] = useState<Record<string, unknown>>({});
  const [analytics, setAnalytics] = useState<Analytics | null>(null);
  const [loadError, setLoadError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  // ── Preview state ───────────────────────────────────────────────────────
  const [previewText, setPreviewText] = useState(() => t("previewSample"));
  const [preview, setPreview] = useState<PreviewResult | null>(null);
  const [previewError, setPreviewError] = useState<string | null>(null);
  const [previewLoading, setPreviewLoading] = useState(false);

  // ── Action state ────────────────────────────────────────────────────────
  const [saveError, setSaveError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);

  // ── Initial load ────────────────────────────────────────────────────────
  useEffect(() => {
    let cancelled = false;

    async function load() {
      setLoading(true);
      setLoadError(null);

      // Fire the three independent reads in parallel — load time is the slowest
      // single request, not their sum. Each resolves to null on failure (fail-soft).
      const asJson = (r: Response) => (r.ok ? r.json() : null);
      const [enginesData, settingsData, analyticsData] = await Promise.all([
        fetch("/api/compression/engines")
          .then(asJson)
          .catch(() => null) as Promise<{ engines: EngineEntry[] } | null>,
        fetch("/api/settings/compression")
          .then(asJson)
          .catch(() => null) as Promise<CompressionSettings | null>,
        fetch(`/api/context/analytics/engine?engineId=${engineId}&days=7`)
          .then(asJson)
          .catch(() => null) as Promise<Analytics | null>,
      ]);

      let foundEngine: EngineEntry | null = null;
      if (enginesData) {
        foundEngine = enginesData.engines?.find((e) => e.id === engineId) ?? null;
      } else {
        setLoadError(t("loadFailed"));
      }

      // Detailed config lives in the engine's settings sub-object (when it has one);
      // the on/off + level moved to the panel. 404/null/missing = schema defaults.
      const subKey = SETTINGS_SUBOBJECT[engineId];
      const stored = subKey ? settingsData?.[subKey] : undefined;
      const currentConfig: Record<string, unknown> =
        stored && typeof stored === "object" ? (stored as Record<string, unknown>) : {};

      if (!cancelled) {
        if (analyticsData) setAnalytics(analyticsData);
        setEngine(foundEngine);
        // Seed configState from defaultValues then override with the stored sub-object.
        const defaults: Record<string, unknown> = {};
        for (const field of foundEngine?.configSchema ?? []) {
          defaults[field.key] = field.defaultValue;
        }
        setConfigState({ ...defaults, ...currentConfig });
        setLoading(false);
      }
    }

    void load();
    return () => {
      cancelled = true;
    };
  }, [engineId, t]);

  // ── Handlers ─────────────────────────────────────────────────────────────

  // Persist the engine's DETAILED config to its settings sub-object. The on/off +
  // level are owned by the panel (the `engines` map) and are NOT written here — so
  // this page never touches the deprecated /api/context/combos/default route.
  async function handleSave() {
    const subKey = SETTINGS_SUBOBJECT[engineId];
    if (!subKey) {
      // Structural engines have no detail store yet — nothing to persist this phase.
      setSaveError(null);
      return;
    }
    // Strip the `enabled` key — engine on/off is the panel's responsibility.
    const { enabled: _ignored, ...detail } = configState;
    void _ignored;
    setSaving(true);
    setSaveError(null);
    try {
      const res = await fetch("/api/settings/compression", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ [subKey]: detail }),
      });
      if (!res.ok) {
        setSaveError(t("saveFailed"));
      }
    } catch {
      setSaveError(t("saveFailed"));
    } finally {
      setSaving(false);
    }
  }

  async function handlePreview() {
    setPreviewLoading(true);
    setPreviewError(null);
    setPreview(null);
    try {
      // Pass the form's current detail (e.g. headroom.minRows) so preview honors
      // unsaved edits and the persisted sub-object after save (#8056).
      const detailConfig =
        engineId === "headroom"
          ? {
              headroom: {
                ...(typeof configState.minRows === "number"
                  ? { minRows: configState.minRows }
                  : {}),
              },
            }
          : engineId === "aggressive"
            ? { aggressive: { ...configState } }
            : engineId === "ultra"
              ? { ultra: { ...configState } }
              : undefined;
      const res = await fetch("/api/compression/preview", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          engineId,
          messages: [{ role: "user", content: previewText }],
          ...(detailConfig ? { config: detailConfig } : {}),
        }),
      });
      if (res.ok) {
        const data = (await res.json()) as PreviewResult;
        setPreview(data);
      } else {
        setPreviewError(t("previewFailed"));
      }
    } catch {
      setPreviewError(t("previewFailed"));
    } finally {
      setPreviewLoading(false);
    }
  }

  // ── Render ────────────────────────────────────────────────────────────────

  if (loading) {
    return (
      <div className="flex items-center justify-center p-12 text-text-muted text-sm">
        {t("loading")}
      </div>
    );
  }

  if (!engine) {
    return (
      <div className="p-6 text-sm text-text-muted">
        {loadError ?? t("engineNotFound", { engine: engineId })}
      </div>
    );
  }

  const engineNameKey = `engines.${engineId}.name`;
  const engineDescriptionKey = `engines.${engineId}.description`;
  const engineName = t.has(engineNameKey) ? t(engineNameKey) : engine.name;
  const rawSubtitle = engine.metadata?.description ?? engine.description;
  const subtitle = t.has(engineDescriptionKey) ? t(engineDescriptionKey) : rawSubtitle;
  const visibleConfigSchema = engine.configSchema
    .filter((field) => field.key !== "enabled")
    .map((field) => {
      const engineFieldPrefix = `engineFields.${engineId}.${field.key}`;
      const fieldPrefix = `fields.${field.key}`;
      const labelKey = t.has(`${engineFieldPrefix}.label`)
        ? `${engineFieldPrefix}.label`
        : `${fieldPrefix}.label`;
      const descriptionKey = t.has(`${engineFieldPrefix}.description`)
        ? `${engineFieldPrefix}.description`
        : `${fieldPrefix}.description`;

      return {
        ...field,
        label: t.has(labelKey) ? t(labelKey) : field.label,
        description:
          field.description && t.has(descriptionKey) ? t(descriptionKey) : field.description,
        options: field.options?.map((option) => {
          const optionKey = `options.${field.key}.${option.value}`;
          return { ...option, label: t.has(optionKey) ? t(optionKey) : option.label };
        }),
      };
    });
  // Only engines with a dedicated settings sub-object can persist their detail here.
  const persistable = Boolean(SETTINGS_SUBOBJECT[engineId]);

  return (
    <div className="flex flex-col gap-6 p-6 max-w-3xl">
      {/* ── Header ── */}
      <div className="flex flex-col gap-1">
        <div className="flex items-center gap-2">
          {engine.icon && (
            <span
              className="material-symbols-outlined text-[28px] leading-none text-text-muted"
              aria-hidden="true"
            >
              {ENGINE_ICON_ALIASES[engine.icon] || engine.icon}
            </span>
          )}
          <h1 className="text-2xl font-bold text-text">{engineName}</h1>
        </div>
        {subtitle && <p className="text-sm text-text-muted">{subtitle}</p>}
      </div>

      {loadError && (
        <p className="text-xs text-destructive border border-destructive/30 rounded px-3 py-2">
          {loadError}
        </p>
      )}

      {/* ── Panel pointer (on/off + level live there now) ── */}
      <div className="flex flex-col gap-1 rounded-lg border border-border bg-surface p-4">
        <p className="text-xs text-text-muted" data-testid="panel-pointer-notice">
          {t("panelPointerPrefix")}{" "}
          <a href="/dashboard/context/settings" className="underline hover:text-text">
            {t("compressionSettings")}
          </a>
          {t("panelPointerSuffix")}
        </p>
      </div>

      {/* ── Config form ── */}
      <div className="flex flex-col gap-3 rounded-lg border border-border bg-surface p-4">
        <h2 className="text-sm font-semibold text-text">{t("configuration")}</h2>
        {visibleConfigSchema.length > 0 ? (
          <EngineConfigForm
            schema={visibleConfigSchema}
            value={configState}
            onChange={setConfigState}
          />
        ) : (
          <p className="text-sm text-text-muted">{t("noAdditionalConfiguration")}</p>
        )}
        <div className="flex items-center gap-3 pt-1">
          {persistable ? (
            <button
              onClick={handleSave}
              disabled={saving}
              className="px-4 py-1.5 rounded bg-primary text-primary-foreground text-sm font-medium disabled:opacity-50"
            >
              {saving ? t("saving") : t("save")}
            </button>
          ) : (
            <p className="text-xs text-text-muted" data-testid="no-detail-store-notice">
              {t("globalSettingsOnly")}
            </p>
          )}
          {saveError && <p className="text-xs text-destructive">{saveError}</p>}
        </div>
      </div>

      {/* ── Live preview ── */}
      <div className="flex flex-col gap-3 rounded-lg border border-border bg-surface p-4">
        <h2 className="text-sm font-semibold text-text">{t("preview")}</h2>
        <textarea
          className="border border-border rounded px-3 py-2 text-sm text-text bg-background resize-y min-h-[80px]"
          value={previewText}
          onChange={(e) => setPreviewText(e.target.value)}
          aria-label={t("previewInput")}
        />
        <div className="flex items-center gap-3">
          <button
            onClick={handlePreview}
            disabled={previewLoading}
            className="px-4 py-1.5 rounded bg-primary text-primary-foreground text-sm font-medium disabled:opacity-50"
          >
            {previewLoading ? t("processing") : t("preview")}
          </button>
        </div>
        {previewError && <p className="text-xs text-destructive">{previewError}</p>}
        {preview && (
          <div className="flex flex-col gap-3 pt-1 text-sm">
            <div className="flex flex-wrap gap-4">
              <span className="text-text-muted">
                {t("originalTokens")}:{" "}
                <strong className="text-text">{preview.originalTokens}</strong>
              </span>
              <span className="text-text-muted">
                {t("compressedTokens")}:{" "}
                <strong className="text-text">{preview.compressedTokens}</strong>
              </span>
              <span className="text-text-muted">
                {t("savings")}:{" "}
                <strong className="text-primary">{preview.savingsPct.toFixed(1)}%</strong>
              </span>
            </div>
            <div className="grid gap-3 md:grid-cols-2">
              <div className="flex flex-col gap-1">
                <h3 className="text-xs font-semibold uppercase tracking-wide text-text-muted">
                  {t("original")}
                </h3>
                <pre className="max-h-72 overflow-auto rounded border border-border bg-background p-3 whitespace-pre-wrap break-words text-text">
                  {preview.original ?? ""}
                </pre>
              </div>
              <div className="flex flex-col gap-1">
                <h3 className="text-xs font-semibold uppercase tracking-wide text-text-muted">
                  {t("compressed")}
                </h3>
                <pre className="max-h-72 overflow-auto rounded border border-border bg-background p-3 whitespace-pre-wrap break-words text-text">
                  {preview.compressed ?? ""}
                </pre>
              </div>
            </div>
            {preview.diff && preview.diff.length > 0 && (
              <div className="flex flex-col gap-2" data-testid="compression-preview-diff">
                <h3 className="text-xs font-semibold uppercase tracking-wide text-text-muted">
                  {t("diff")}
                </h3>
                <div className="flex max-h-72 flex-col gap-2 overflow-auto rounded border border-border p-2">
                  {preview.diff.map((segment, index) =>
                    renderDiffSegment(segment, index, (label) => {
                      const key = `diffLabels.${label}`;
                      return t.has(key) ? t(key) : label;
                    })
                  )}
                </div>
              </div>
            )}
          </div>
        )}
      </div>

      {/* ── Analytics strip ── */}
      <div className="flex flex-col gap-3 rounded-lg border border-border bg-surface p-4">
        <h2 className="text-sm font-semibold text-text">{t("last7Days")}</h2>
        {analytics && analytics.runs === 0 ? (
          <p className="text-sm text-text-muted">{t("noDataYet")}</p>
        ) : analytics ? (
          <div className="grid grid-cols-3 gap-3">
            <StatCard label={t("runs")} value={analytics.runs.toLocaleString(locale)} />
            <StatCard
              label={t("tokensSaved")}
              value={analytics.tokensSaved.toLocaleString(locale)}
            />
            <StatCard
              label={t("averageSavings")}
              value={`${analytics.avgSavingsPercent.toFixed(1)}%`}
            />
          </div>
        ) : (
          <p className="text-sm text-text-muted">{t("noDataYet")}</p>
        )}
      </div>
    </div>
  );
}

export default EngineConfigPage;
