"use client";

import { useState, useEffect, useCallback } from "react";
import { useTranslations } from "next-intl";
import { Card } from "@/shared/components";

interface QdrantSettings {
  enabled: boolean;
  host: string;
  port: number;
  collection: string;
  embeddingModel: string;
  hasApiKey: boolean;
  apiKeyMasked: string | null;
}

interface EmbeddingModelOption {
  value: string;
  label: string;
}

export default function QdrantConfigCard() {
  const t = useTranslations("memory");
  const [qdrant, setQdrant] = useState<QdrantSettings>({
    enabled: false,
    host: "",
    port: 6333,
    collection: "omniroute_memory",
    embeddingModel: "openai/text-embedding-3-small",
    hasApiKey: false,
    apiKeyMasked: null,
  });
  const [apiKeyInput, setApiKeyInput] = useState("");
  const [saving, setSaving] = useState(false);
  const [saveStatus, setSaveStatus] = useState<"" | "saved" | "error">("");
  const [health, setHealth] = useState<{ ok: boolean; latencyMs: number; error?: string } | null>(
    null,
  );
  const [checking, setChecking] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [searching, setSearching] = useState(false);
  const [searchResults, setSearchResults] = useState<
    Array<{ id: string; score: number; payload?: Record<string, unknown> }>
  >([]);
  const [cleanupLoading, setCleanupLoading] = useState(false);
  const [cleanupMsg, setCleanupMsg] = useState("");
  const [embeddingOptions, setEmbeddingOptions] = useState<EmbeddingModelOption[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    Promise.all([
      fetch("/api/settings/qdrant").then((r) => (r.ok ? r.json() : null)),
      fetch("/api/settings/qdrant/embedding-models").then((r) => (r.ok ? r.json() : null)),
    ])
      .then(([qdrantData, embeddingData]) => {
        if (qdrantData) {
          setQdrant(qdrantData);
          setApiKeyInput("");
        }
        if (embeddingData?.models) {
          setEmbeddingOptions(embeddingData.models);
        }
      })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, []);

  const save = useCallback(
    async (updates: Partial<QdrantSettings> & { apiKey?: string }) => {
      const prev = qdrant;
      const next = { ...qdrant, ...updates };
      setQdrant(next);
      setSaving(true);
      setSaveStatus("");
      try {
        const body: Record<string, unknown> = {
          enabled: next.enabled,
          host: next.host,
          port: next.port,
          collection: next.collection,
          embeddingModel: next.embeddingModel,
        };
        if (updates.apiKey !== undefined) body.apiKey = updates.apiKey;
        const res = await fetch("/api/settings/qdrant", {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(body),
        });
        if (res.ok) {
          const data = await res.json().catch(() => next);
          setQdrant(data);
          setApiKeyInput("");
          setSaveStatus("saved");
          setTimeout(() => setSaveStatus(""), 2000);
        } else {
          setQdrant(prev);
          setSaveStatus("error");
        }
      } catch {
        setQdrant(prev);
        setSaveStatus("error");
      } finally {
        setSaving(false);
      }
    },
    [qdrant],
  );

  const checkHealth = useCallback(async () => {
    setChecking(true);
    try {
      const res = await fetch("/api/settings/qdrant/health");
      if (res.ok) setHealth(await res.json());
      else setHealth({ ok: false, latencyMs: 0, error: "HTTP error" });
    } catch (e) {
      setHealth({
        ok: false,
        latencyMs: 0,
        error: e instanceof Error ? e.message : String(e),
      });
    } finally {
      setChecking(false);
    }
  }, []);

  const runSearch = useCallback(async () => {
    const q = searchQuery.trim();
    if (!q) return;
    setSearching(true);
    setSearchResults([]);
    try {
      const res = await fetch("/api/settings/qdrant/search", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ query: q, topK: 5 }),
      });
      const data = await res.json().catch(() => null);
      if (res.ok && data?.ok) {
        setSearchResults(Array.isArray(data.results) ? data.results : []);
      }
    } catch {
      setSearchResults([]);
    } finally {
      setSearching(false);
    }
  }, [searchQuery]);

  const runCleanup = useCallback(async () => {
    setCleanupLoading(true);
    setCleanupMsg("");
    try {
      const res = await fetch("/api/settings/qdrant/cleanup", { method: "POST" });
      const data = await res.json().catch(() => null);
      if (res.ok && data?.ok) {
        setCleanupMsg(t("qdrant.cleanupSuccess", { count: data.deletedCount ?? 0 }));
      } else {
        setCleanupMsg(t("qdrant.cleanupFailed"));
      }
    } catch {
      setCleanupMsg(t("qdrant.cleanupFailed"));
    } finally {
      setCleanupLoading(false);
    }
  }, [t]);

  if (loading) {
    return (
      <Card>
        <div className="text-sm text-text-muted">{t("loading")}</div>
      </Card>
    );
  }

  return (
    <Card>
      <div className="flex items-center gap-3 mb-5">
        <div className="p-2 rounded-lg bg-emerald-500/10 text-emerald-500 shrink-0">
          <span className="material-symbols-outlined text-[20px]" aria-hidden="true">
            database
          </span>
        </div>
        <div className="flex-1 min-w-0">
          <h3 className="text-sm font-semibold text-text-main">{t("qdrant.title")}</h3>
          <p className="text-xs text-text-muted">{t("qdrant.description")}</p>
        </div>
        <span
          className={`inline-flex items-center gap-1.5 text-xs font-medium ${
            qdrant.enabled
              ? health?.ok
                ? "text-emerald-500"
                : "text-red-500"
              : "text-text-muted"
          }`}
        >
          <span
            className={`inline-block w-2.5 h-2.5 rounded-full ${
              qdrant.enabled ? (health?.ok ? "bg-emerald-500" : "bg-red-500") : "bg-border"
            }`}
          />
          {qdrant.enabled
            ? health?.ok
              ? t("qdrant.statusActive")
              : t("qdrant.statusError")
            : t("qdrant.statusDisabled")}
        </span>
      </div>

      {/* Enable toggle + test connection */}
      <div className="flex items-center justify-between p-4 rounded-lg bg-surface/30 border border-border/30 mb-4">
        <div>
          <p className="text-sm font-medium">{t("qdrant.enableLabel")}</p>
          <p className="text-xs text-text-muted mt-0.5">{t("qdrant.enableDesc")}</p>
        </div>
        <div className="flex items-center gap-2">
          <button
            data-testid="qdrant-test-connection"
            onClick={checkHealth}
            disabled={checking || saving}
            className="px-3 h-8 text-xs font-medium rounded-lg bg-white/5 border border-border/60 hover:bg-white/10 disabled:opacity-50 transition-colors"
          >
            {checking ? t("qdrant.testing") : t("qdrant.testConnection")}
          </button>
          <button
            data-testid="qdrant-enabled-switch"
            onClick={() => save({ enabled: !qdrant.enabled })}
            disabled={saving}
            role="switch"
            aria-checked={qdrant.enabled}
            className={`relative w-11 h-6 rounded-full transition-colors ${
              qdrant.enabled ? "bg-emerald-500" : "bg-border"
            }`}
          >
            <span
              className={`absolute top-1 left-1 w-4 h-4 bg-white rounded-full transition-transform ${
                qdrant.enabled ? "translate-x-5" : "translate-x-0"
              }`}
            />
          </button>
        </div>
      </div>

      {health && (
        <div
          className={`mb-4 text-xs font-medium flex items-center gap-1 ${health.ok ? "text-emerald-500" : "text-red-500"}`}
        >
          <span className="material-symbols-outlined text-[14px]">
            {health.ok ? "check_circle" : "error"}
          </span>
          {health.ok
            ? t("qdrant.healthOk", { latencyMs: health.latencyMs })
            : (health.error ?? t("qdrant.healthError"))}
        </div>
      )}

      {saveStatus === "saved" && (
        <div className="mb-4 text-xs font-medium text-emerald-500 flex items-center gap-1">
          <span className="material-symbols-outlined text-[14px]">check_circle</span>
          {t("qdrant.saved")}
        </div>
      )}
      {saveStatus === "error" && (
        <div className="mb-4 text-xs font-medium text-red-500">{t("qdrant.saveError")}</div>
      )}

      <div className="grid grid-cols-1 md:grid-cols-2 gap-3 mb-4">
        <div className="p-3 rounded-lg bg-surface/30 border border-border/30">
          <label className="text-xs font-medium block mb-1.5">Host</label>
          <input
            value={qdrant.host}
            onChange={(e) => setQdrant((s) => ({ ...s, host: e.target.value }))}
            placeholder="http://127.0.0.1"
            className="w-full px-3 py-2 rounded-lg bg-background border border-border text-sm font-mono focus:outline-none focus:ring-1 focus:ring-emerald-500"
          />
        </div>
        <div className="p-3 rounded-lg bg-surface/30 border border-border/30">
          <label className="text-xs font-medium block mb-1.5">{t("qdrant.portLabel")}</label>
          <input
            value={qdrant.port}
            type="number"
            onChange={(e) =>
              setQdrant((s) => ({ ...s, port: Math.max(1, Math.min(65535, Number(e.target.value) || 1)) }))
            }
            placeholder="6333"
            className="w-full px-3 py-2 rounded-lg bg-background border border-border text-sm font-mono focus:outline-none focus:ring-1 focus:ring-emerald-500"
          />
        </div>
        <div className="p-3 rounded-lg bg-surface/30 border border-border/30">
          <label className="text-xs font-medium block mb-1.5">Collection</label>
          <input
            value={qdrant.collection}
            onChange={(e) => setQdrant((s) => ({ ...s, collection: e.target.value }))}
            placeholder="omniroute_memory"
            className="w-full px-3 py-2 rounded-lg bg-background border border-border text-sm font-mono focus:outline-none focus:ring-1 focus:ring-emerald-500"
          />
        </div>
        <div className="p-3 rounded-lg bg-surface/30 border border-border/30">
          <label className="text-xs font-medium block mb-1.5">
            {t("qdrant.embeddingModelLabel")}
          </label>
          {embeddingOptions.length > 0 && (
            <select
              value=""
              onChange={(e) => {
                if (e.target.value) setQdrant((s) => ({ ...s, embeddingModel: e.target.value }));
              }}
              className="w-full px-3 py-2 rounded-lg bg-background border border-border text-sm mb-2 focus:outline-none focus:ring-1 focus:ring-emerald-500"
            >
              <option value="">{t("qdrant.quickSelectModel")}</option>
              {embeddingOptions.map((opt) => (
                <option key={opt.value} value={opt.value}>
                  {opt.value}
                </option>
              ))}
            </select>
          )}
          <input
            value={qdrant.embeddingModel}
            onChange={(e) => setQdrant((s) => ({ ...s, embeddingModel: e.target.value }))}
            placeholder="openai/text-embedding-3-small"
            className="w-full px-3 py-2 rounded-lg bg-background border border-border text-sm font-mono focus:outline-none focus:ring-1 focus:ring-emerald-500"
          />
        </div>
        <div className="p-3 rounded-lg bg-surface/30 border border-border/30 md:col-span-2">
          <label className="text-xs font-medium block mb-1.5">
            API Key ({t("qdrant.optional")}){" "}
            {qdrant.hasApiKey && qdrant.apiKeyMasked ? (
              <span className="text-text-muted font-mono">{qdrant.apiKeyMasked}</span>
            ) : null}
          </label>
          <div className="flex gap-2">
            <input
              type="password"
              value={apiKeyInput}
              onChange={(e) => setApiKeyInput(e.target.value)}
              placeholder={
                qdrant.hasApiKey ? t("qdrant.apiKeyKeepPlaceholder") : t("qdrant.apiKeyOptional")
              }
              className="flex-1 px-3 py-2 rounded-lg bg-background border border-border text-sm font-mono focus:outline-none focus:ring-1 focus:ring-emerald-500"
            />
            {qdrant.hasApiKey && (
              <button
                onClick={() => save({ apiKey: "" })}
                disabled={saving}
                className="px-3 py-2 text-sm font-medium rounded-lg bg-white/5 border border-border/60 hover:bg-white/10 disabled:opacity-50"
              >
                {t("qdrant.removeApiKey")}
              </button>
            )}
            <button
              onClick={() =>
                save(apiKeyInput.trim() ? { apiKey: apiKeyInput } : {})
              }
              disabled={saving}
              className="px-4 py-2 text-sm font-medium rounded-lg bg-emerald-500 text-white hover:bg-emerald-600 disabled:opacity-50"
            >
              {saving ? t("saving") : t("save")}
            </button>
          </div>
        </div>
      </div>

      {/* Search test */}
      <div className="p-4 rounded-lg bg-surface/30 border border-border/30 mb-3">
        <p className="text-sm font-medium mb-2">{t("qdrant.searchTestTitle")}</p>
        <div className="flex gap-2">
          <input
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            placeholder={t("qdrant.searchPlaceholder")}
            onKeyDown={(e) => e.key === "Enter" && runSearch()}
            className="flex-1 px-3 py-2 rounded-lg bg-background border border-border text-sm focus:outline-none focus:ring-1 focus:ring-emerald-500"
          />
          <button
            data-testid="qdrant-search-test"
            onClick={runSearch}
            disabled={searching || !searchQuery.trim()}
            className="px-4 py-2 text-sm font-medium rounded-lg bg-white/5 border border-border/60 hover:bg-white/10 disabled:opacity-50"
          >
            {searching ? t("qdrant.searching") : t("qdrant.search")}
          </button>
        </div>
        {searchResults.length > 0 && (
          <div className="mt-3 space-y-2">
            {searchResults.map((r) => (
              <div
                key={r.id}
                className="p-2 rounded bg-background/40 border border-border/40 flex items-center justify-between"
              >
                <span className="text-xs font-mono text-text-muted truncate">{r.id}</span>
                <span className="text-xs font-mono text-emerald-400 shrink-0">
                  {r.score.toFixed(4)}
                </span>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Cleanup */}
      <div className="p-4 rounded-lg bg-surface/30 border border-border/30">
        <div className="flex items-center justify-between">
          <div>
            <p className="text-sm font-medium">{t("qdrant.cleanupTitle")}</p>
            <p className="text-xs text-text-muted mt-0.5">{t("qdrant.cleanupDesc")}</p>
          </div>
          <button
            data-testid="qdrant-cleanup"
            onClick={runCleanup}
            disabled={cleanupLoading}
            className="px-4 py-2 text-sm font-medium rounded-lg bg-white/5 border border-border/60 hover:bg-white/10 disabled:opacity-50"
          >
            {cleanupLoading ? t("qdrant.cleaning") : t("qdrant.cleanNow")}
          </button>
        </div>
        {cleanupMsg && <p className="mt-2 text-xs text-text-muted">{cleanupMsg}</p>}
      </div>
    </Card>
  );
}
