import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  getServiceConfigs, addServiceConfig, editServiceConfig, deleteServiceConfig,
  type ServiceConfig, type SaveServiceConfigInput, type ServiceConfigEntry,
} from "../../lib/commands";

const SYSTEM_CATEGORIES = [
  { value: "database", label: "数据库", color: "bg-blue-100 text-blue-700 border-blue-200" },
  { value: "storage", label: "存储", color: "bg-green-100 text-green-700 border-green-200" },
  { value: "web", label: "Web 服务", color: "bg-purple-100 text-purple-700 border-purple-200" },
  { value: "monitoring", label: "监控", color: "bg-orange-100 text-orange-700 border-orange-200" },
  { value: "mq", label: "消息队列", color: "bg-pink-100 text-pink-700 border-pink-200" },
  { value: "cache", label: "缓存", color: "bg-cyan-100 text-cyan-700 border-cyan-200" },
  { value: "custom", label: "自定义", color: "bg-gray-100 text-gray-600 border-gray-200" },
];

const DOCKER_CATEGORIES = [
  { value: "portal", label: "管理面板", color: "bg-indigo-100 text-indigo-700 border-indigo-200" },
  { value: "app", label: "应用", color: "bg-blue-100 text-blue-700 border-blue-200" },
  { value: "database", label: "数据库", color: "bg-emerald-100 text-emerald-700 border-emerald-200" },
  { value: "monitoring", label: "监控", color: "bg-orange-100 text-orange-700 border-orange-200" },
  { value: "network", label: "网络", color: "bg-cyan-100 text-cyan-700 border-cyan-200" },
  { value: "custom", label: "自定义", color: "bg-gray-100 text-gray-600 border-gray-200" },
];

type ScopeType = "system" | "docker";

function getCategoriesForScope(scope: ScopeType) {
  return scope === "docker" ? DOCKER_CATEGORIES : SYSTEM_CATEGORIES;
}

const ALL_CATEGORIES = [...SYSTEM_CATEGORIES, ...DOCKER_CATEGORIES];

function getCategoryStyle(cat?: string) {
  return ALL_CATEGORIES.find((c) => c.value === cat)?.color ?? "bg-gray-100 text-gray-600 border-gray-200";
}
function getCategoryLabel(cat?: string) {
  return ALL_CATEGORIES.find((c) => c.value === cat)?.label ?? "自定义";
}

function CopyBtn({ value }: { value: string }) {
  const [copied, setCopied] = useState(false);
  const handleCopy = async () => {
    await navigator.clipboard.writeText(value);
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };
  return (
    <button onClick={handleCopy}
      className="shrink-0 px-1.5 py-0.5 rounded text-[11px] border border-gray-200 text-gray-400 hover:text-blue-500 hover:border-blue-300 hover:bg-blue-50 transition-colors">
      {copied ? "已复制" : "复制"}
    </button>
  );
}

// ── 模态框表单 ────────────────────────────────────────────────────────────────

function ServiceConfigModal({ initial, onSave, onClose, saving, scope }: {
  initial?: ServiceConfig;
  onSave: (input: SaveServiceConfigInput) => void;
  onClose: () => void;
  saving: boolean;
  scope: ScopeType;
}) {
  const categories = getCategoriesForScope(scope);
  const [name, setName] = useState(initial?.name ?? "");
  const [category, setCategory] = useState(initial?.category ?? categories[0].value);
  const [entries, setEntries] = useState<ServiceConfigEntry[]>(() => {
    try { return initial?.config_data ? JSON.parse(initial.config_data) : [{ key: "", value: "" }]; }
    catch { return [{ key: "", value: "" }]; }
  });

  const addEntry = () => setEntries((p) => [...p, { key: "", value: "" }]);
  const removeEntry = (i: number) => setEntries((p) => p.filter((_, idx) => idx !== i));
  const updateEntry = (i: number, field: keyof ServiceConfigEntry, val: string) =>
    setEntries((p) => p.map((e, idx) => idx === i ? { ...e, [field]: val } : e));

  const handleSubmit = () => {
    if (!name.trim()) return;
    const validEntries = entries.filter((e) => e.key.trim() || e.value.trim());
    onSave({
      name: name.trim(),
      category,
      scope,
      config_data: JSON.stringify(validEntries),
    });
  };

  const isEdit = !!initial;

  return (
    <div className="fixed inset-0 bg-black/30 z-50 flex items-center justify-center" onClick={onClose}>
      <div className="bg-white rounded-xl border border-gray-200 shadow-xl w-[620px] max-h-[80vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-100">
          <h3 className="text-sm font-bold text-gray-800">
            {isEdit ? "编辑" : "添加"}{scope === "docker" ? "应用配置" : "服务连接配置"}
          </h3>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-lg leading-none">x</button>
        </div>

        <div className="flex-1 overflow-y-auto px-6 py-4 space-y-4">
          <div className="grid grid-cols-[64px_1fr] gap-x-3 gap-y-2.5 items-center">
            <label className="text-[11px] text-gray-400 text-right">名称 *</label>
            <input value={name} onChange={(e) => setName(e.target.value)} placeholder="例: PostgreSQL 连接"
              className="text-xs px-2.5 py-2 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300" />
            <label className="text-[11px] text-gray-400 text-right">分类</label>
            <select value={category} onChange={(e) => setCategory(e.target.value)}
              className="text-xs px-2.5 py-2 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 w-32">
              {categories.map((c) => <option key={c.value} value={c.value}>{c.label}</option>)}
            </select>
          </div>

          <div>
            <div className="flex items-center justify-between mb-2">
              <span className="text-[11px] text-gray-500 font-medium">配置项</span>
              <button onClick={addEntry}
                className="text-[11px] px-2 py-0.5 rounded border border-dashed border-gray-300 text-gray-400 hover:border-gray-400 hover:text-gray-600 transition-colors">
                + 添加配置项
              </button>
            </div>

            {/* 表头 */}
            <div className="flex items-center gap-1.5 mb-1 px-0.5">
              <span className="text-[10px] text-gray-300 w-24 shrink-0">名称</span>
              <span className="text-[10px] text-gray-300 flex-1">值</span>
              <span className="text-[10px] text-gray-300 flex-1">密码（选填）</span>
              <span className="w-3 shrink-0" />
            </div>

            <div className="space-y-1.5">
              {entries.map((entry, idx) => (
                <div key={idx} className="flex items-center gap-1.5">
                  <input value={entry.key} onChange={(e) => updateEntry(idx, "key", e.target.value)}
                    placeholder="配置项" className="text-xs px-2 py-1.5 rounded border border-gray-200 bg-gray-50 w-24 focus:outline-none focus:border-blue-300 shrink-0" />
                  <input value={entry.value} onChange={(e) => updateEntry(idx, "value", e.target.value)}
                    placeholder="值" className="text-xs px-2 py-1.5 rounded border border-gray-200 bg-gray-50 flex-1 focus:outline-none focus:border-blue-300 font-mono" />
                  <input value={entry.secretValue ?? ""} onChange={(e) => updateEntry(idx, "secretValue", e.target.value)}
                    placeholder="密码/密钥" className="text-xs px-2 py-1.5 rounded border border-gray-200 bg-gray-50 flex-1 focus:outline-none focus:border-blue-300 font-mono" />
                  <button onClick={() => removeEntry(idx)}
                    className="text-gray-300 hover:text-red-400 text-xs transition-colors shrink-0">x</button>
                </div>
              ))}
            </div>
          </div>
        </div>

        <div className="flex items-center justify-end gap-2 px-6 py-3 border-t border-gray-100 bg-gray-50/50">
          <button onClick={onClose}
            className="px-3 py-1.5 rounded-md text-xs border border-gray-200 text-gray-500 hover:bg-gray-50 transition-colors">
            取消
          </button>
          <button onClick={handleSubmit} disabled={saving || !name.trim()}
            className="px-4 py-1.5 rounded-md text-xs font-medium bg-blue-600 text-white hover:bg-blue-700 transition-colors disabled:opacity-40">
            {saving ? "保存中…" : "保存"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── 单条配置卡片 ──────────────────────────────────────────────────────────────

function ServiceConfigCard({ config, onEdit, onDelete }: {
  config: ServiceConfig;
  onEdit: () => void;
  onDelete: () => void;
}) {
  const [confirmDelete, setConfirmDelete] = useState(false);
  const [revealSecrets, setRevealSecrets] = useState<Set<number>>(new Set());
  const entries: ServiceConfigEntry[] = (() => {
    try { return JSON.parse(config.config_data); } catch { return []; }
  })();

  const toggleReveal = (idx: number) => {
    setRevealSecrets((prev) => {
      const next = new Set(prev);
      next.has(idx) ? next.delete(idx) : next.add(idx);
      return next;
    });
  };

  const allText = entries
    .map((e) => {
      if (e.secretValue) return `${e.key}: ${e.value} / ${e.secretValue}`;
      return `${e.key}: ${e.value}`;
    })
    .join("\n");

  return (
    <div className="bg-white border border-gray-200 rounded-lg overflow-hidden">
      <div className="flex items-center gap-2 px-3 py-2 bg-gray-50/60 border-b border-gray-100">
        <span className={`text-[10px] px-1.5 py-0.5 rounded border font-medium ${getCategoryStyle(config.category)}`}>
          {getCategoryLabel(config.category)}
        </span>
        <span className="text-xs font-semibold text-gray-800 flex-1 min-w-0 truncate">{config.name}</span>
        <CopyBtn value={allText} />
        <button onClick={onEdit}
          className="text-[11px] text-gray-400 hover:text-blue-500 transition-colors">编辑</button>
        {!confirmDelete ? (
          <button onClick={() => setConfirmDelete(true)}
            className="text-[11px] text-gray-400 hover:text-red-500 transition-colors">删除</button>
        ) : (
          <div className="flex gap-1">
            <button onClick={onDelete}
              className="text-[11px] text-red-500 hover:text-red-700 transition-colors font-medium">确认</button>
            <button onClick={() => setConfirmDelete(false)}
              className="text-[11px] text-gray-400 transition-colors">取消</button>
          </div>
        )}
      </div>

      {entries.length > 0 && (
        <div className="px-3 py-2 space-y-0.5">
          {entries.map((entry, idx) => (
            <div key={idx} className="flex items-center gap-2 py-0.5 group">
              <span className="text-[11px] text-gray-400 w-20 shrink-0 text-right truncate" title={entry.key}>
                {entry.key}
              </span>
              <span className="text-xs font-mono text-gray-700 min-w-0 truncate" title={entry.value}>
                {entry.value}
              </span>
              {entry.secretValue && (
                <>
                  <span className="text-gray-300 text-[10px]">/</span>
                  <span className="text-xs font-mono text-gray-700 min-w-0 truncate" title={entry.secretValue}>
                    {revealSecrets.has(idx) ? entry.secretValue : "••••••••"}
                  </span>
                  <button onClick={() => toggleReveal(idx)}
                    className="text-[10px] text-gray-400 hover:text-gray-600 transition-colors shrink-0">
                    {revealSecrets.has(idx) ? "隐藏" : "显示"}
                  </button>
                  <span className="opacity-0 group-hover:opacity-100 transition-opacity">
                    <CopyBtn value={entry.secretValue} />
                  </span>
                </>
              )}
              {!entry.secretValue && (
                <span className="opacity-0 group-hover:opacity-100 transition-opacity">
                  <CopyBtn value={entry.value} />
                </span>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── 主组件 ────────────────────────────────────────────────────────────────────

const SCOPE_META: Record<ScopeType, { title: string; emptyHint: string }> = {
  system: {
    title: "服务连接配置",
    emptyHint: "暂无服务连接配置，点击「+ 添加」记录数据库、缓存等连接信息",
  },
  docker: {
    title: "Docker 应用配置",
    emptyHint: "暂无应用配置，点击「+ 添加」记录容器应用的登录地址、账号等信息",
  },
};

export function ServiceConfigPanel({ serverId, scope = "system" }: { serverId: string; scope?: ScopeType }) {
  const qc = useQueryClient();
  const [showModal, setShowModal] = useState(false);
  const [editingConfig, setEditingConfig] = useState<ServiceConfig | null>(null);
  const meta = SCOPE_META[scope];

  const { data: configs = [] } = useQuery({
    queryKey: ["service-configs", serverId, scope],
    queryFn: () => getServiceConfigs(serverId, scope),
  });

  const addMut = useMutation({
    mutationFn: (input: SaveServiceConfigInput) => addServiceConfig(serverId, input),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["service-configs", serverId, scope] }); setShowModal(false); },
  });

  const editMut = useMutation({
    mutationFn: ({ id, input }: { id: string; input: SaveServiceConfigInput }) => editServiceConfig(id, input),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["service-configs", serverId, scope] }); setEditingConfig(null); },
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteServiceConfig(id),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["service-configs", serverId, scope] }),
  });

  return (
    <div>
      <div className="flex items-center justify-between mb-2">
        <h4 className="text-[11px] font-semibold text-gray-400 uppercase tracking-wider">{meta.title}</h4>
        <button onClick={() => setShowModal(true)}
          className="text-[11px] px-2 py-0.5 rounded border border-dashed border-gray-300 text-gray-400 hover:border-blue-300 hover:text-blue-500 transition-colors">
          + 添加
        </button>
      </div>

      <div className="space-y-2">
        {configs.map((cfg) => (
          <ServiceConfigCard
            key={cfg.id}
            config={cfg}
            onEdit={() => setEditingConfig(cfg)}
            onDelete={() => deleteMut.mutate(cfg.id)}
          />
        ))}

        {configs.length === 0 && (
          <p className="text-[11px] text-gray-300 text-center py-3">{meta.emptyHint}</p>
        )}
      </div>

      {showModal && (
        <ServiceConfigModal
          scope={scope}
          onSave={(input) => addMut.mutate(input)}
          onClose={() => setShowModal(false)}
          saving={addMut.isPending}
        />
      )}

      {editingConfig && (
        <ServiceConfigModal
          scope={scope}
          initial={editingConfig}
          onSave={(input) => editMut.mutate({ id: editingConfig.id, input })}
          onClose={() => setEditingConfig(null)}
          saving={editMut.isPending}
        />
      )}
    </div>
  );
}
