import { useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import {
  scanDevTools,
  scanWslDevTools,
  getDevTools,
  getSpaces,
  saveDevTools,
  deleteDevTool,
  upsertDevTool,
  type ScannedTool,
  type DevToolRecord,
  type SaveDevToolInput,
  type DevEnv,
} from "../../lib/commands";
import { useUIStore } from "../../store/ui";

// ── 分类元信息 ─────────────────────────────────────────────────────────────────

const CATEGORY_META: Record<string, { label: string; icon: string }> = {
  editor:          { label: "编辑器 / IDE",   icon: "✏️" },
  runtime:         { label: "语言运行时",      icon: "⚙️" },
  pkg_manager:     { label: "包管理器",        icon: "📦" },
  version_manager: { label: "版本管理器",      icon: "🔀" },
  cli:             { label: "命令行工具",      icon: "🖥️" },
  database:        { label: "数据库客户端",    icon: "🗄️" },
  other:           { label: "其他",           icon: "🔧" },
};

const CATEGORY_ORDER = ["editor", "runtime", "pkg_manager", "version_manager", "cli", "database", "other"];

function categoryLabel(cat: string) {
  return CATEGORY_META[cat]?.label ?? cat;
}
function categoryIcon(cat: string) {
  return CATEGORY_META[cat]?.icon ?? "🔧";
}

// ── 工具卡片（已保存列表） ─────────────────────────────────────────────────────

function SavedToolCard({ tool, onDelete }: { tool: DevToolRecord; onDelete: () => void }) {
  return (
    <div className="flex items-center gap-3 px-4 py-2.5 bg-white border border-gray-100 rounded-lg hover:border-gray-200 transition-colors group">
      <div className="flex-1 min-w-0">
        <div className="flex items-center gap-2">
          <span className="text-sm font-medium text-gray-800">{tool.name}</span>
          <span className="text-xs px-1.5 py-0.5 rounded bg-gray-100 text-gray-500">
            {categoryLabel(tool.category)}
          </span>
        </div>
        {tool.version && (
          <p className="text-xs text-gray-400 mt-0.5">{tool.version}</p>
        )}
        {tool.path && (
          <p className="text-xs text-gray-400 font-mono truncate mt-0.5">{tool.path}</p>
        )}
        {tool.note && (
          <p className="text-xs text-blue-500 mt-0.5">{tool.note}</p>
        )}
      </div>
      <button
        onClick={onDelete}
        className="opacity-0 group-hover:opacity-100 text-xs text-red-400 hover:text-red-600 transition-all shrink-0"
      >
        移除
      </button>
    </div>
  );
}

// ── 扫描结果行 ─────────────────────────────────────────────────────────────────

function ScanRow({
  tool,
  checked,
  onToggle,
  savedCmds,
}: {
  tool: ScannedTool;
  checked: boolean;
  onToggle: () => void;
  savedCmds: Set<string>;
}) {
  const alreadySaved = savedCmds.has(tool.cmd);
  return (
    <tr className={`border-b border-gray-50 ${!tool.found ? "opacity-40" : ""}`}>
      <td className="px-3 py-2 text-center w-8">
        <input
          type="checkbox"
          checked={checked}
          disabled={!tool.found}
          onChange={onToggle}
          className="accent-blue-600 cursor-pointer disabled:cursor-not-allowed"
        />
      </td>
      <td className="px-3 py-2">
        <div className="flex items-center gap-2">
          <span className="text-sm font-medium text-gray-800">{tool.name}</span>
          {alreadySaved && (
            <span className="text-xs px-1.5 py-0.5 rounded bg-green-50 text-green-600 border border-green-200">已收录</span>
          )}
          {!tool.found && (
            <span className="text-xs text-gray-400">未检测到</span>
          )}
        </div>
        {tool.version && (
          <p className="text-xs text-gray-400 mt-0.5">{tool.version}</p>
        )}
      </td>
      <td className="px-3 py-2 text-xs text-gray-400 font-mono truncate max-w-xs">
        {tool.path ?? "—"}
      </td>
    </tr>
  );
}

// ── 手动添加弹窗 ───────────────────────────────────────────────────────────────

function AddManualModal({ env, spaceId, onClose, onSaved }: { env: DevEnv; spaceId?: string; onClose: () => void; onSaved: () => void }) {
  const showToast = useUIStore((s) => s.showToast);
  const [form, setForm] = useState<SaveDevToolInput>({
    id: "", name: "", category: "other", cmd: "", path: "", version: "", note: "", env,
  });
  const [saving, setSaving] = useState(false);

  const set = (k: keyof SaveDevToolInput, v: string) =>
    setForm((f) => ({ ...f, [k]: v }));

  const handleSave = async () => {
    if (!form.name.trim()) { showToast("❌ 名称不能为空"); return; }
    if (!form.id.trim()) {
      form.id = form.name.toLowerCase().replace(/[^a-z0-9_-]/g, "-") + "-" + Date.now();
    }
    setSaving(true);
    try {
      await upsertDevTool({ ...form, space_id: spaceId });
      onSaved();
      onClose();
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally {
      setSaving(false);
    }
  };

  const inputCls = "w-full border border-gray-200 rounded-lg px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-blue-200";

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
      <div className="bg-white rounded-xl shadow-xl w-[460px] overflow-hidden">
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-100">
          <h2 className="font-semibold text-gray-800">手动添加工具</h2>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-xl leading-none">×</button>
        </div>
        <div className="px-6 py-4 grid grid-cols-2 gap-3">
          <div>
            <label className="block text-xs font-medium text-gray-600 mb-1">名称 *</label>
            <input className={inputCls} value={form.name} onChange={(e) => set("name", e.target.value)} placeholder="Docker Desktop" />
          </div>
          <div>
            <label className="block text-xs font-medium text-gray-600 mb-1">分类</label>
            <select className={inputCls} value={form.category} onChange={(e) => set("category", e.target.value)}>
              {CATEGORY_ORDER.map((c) => (
                <option key={c} value={c}>{categoryIcon(c)} {categoryLabel(c)}</option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-xs font-medium text-gray-600 mb-1">命令</label>
            <input className={inputCls} value={form.cmd ?? ""} onChange={(e) => set("cmd", e.target.value)} placeholder="docker" />
          </div>
          <div>
            <label className="block text-xs font-medium text-gray-600 mb-1">版本</label>
            <input className={inputCls} value={form.version ?? ""} onChange={(e) => set("version", e.target.value)} placeholder="24.0.0" />
          </div>
          <div className="col-span-2">
            <label className="block text-xs font-medium text-gray-600 mb-1">路径</label>
            <input className={`${inputCls} font-mono`} value={form.path ?? ""} onChange={(e) => set("path", e.target.value)} placeholder="C:\Program Files\Docker\Docker\Docker Desktop.exe" />
          </div>
          <div className="col-span-2">
            <label className="block text-xs font-medium text-gray-600 mb-1">备注</label>
            <input className={inputCls} value={form.note ?? ""} onChange={(e) => set("note", e.target.value)} placeholder="可选备注" />
          </div>
        </div>
        <div className="flex justify-end gap-3 px-6 py-4 border-t border-gray-100">
          <button onClick={onClose} className="px-4 py-2 rounded-lg text-sm border border-gray-200 text-gray-600 hover:bg-gray-50">取消</button>
          <button onClick={handleSave} disabled={saving} className="px-4 py-2 rounded-lg text-sm bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50">
            {saving ? "保存中…" : "保存"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── 环境内容面板（可复用于 Windows / WSL）────────────────────────────────────

function EnvPanel({ env, spaceId }: { env: DevEnv; spaceId?: string }) {
  const showToast = useUIStore((s) => s.showToast);
  const qc = useQueryClient();

  const [tab, setTab] = useState<"saved" | "scan">("saved");
  const [scanning, setScanning] = useState(false);
  const [scanned, setScanned] = useState<ScannedTool[]>([]);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [saving, setSaving] = useState(false);
  const [filterCat, setFilterCat] = useState<string>("all");

  const { data: savedTools = [] } = useQuery({
    queryKey: ["devTools", env, spaceId],
    queryFn: () => getDevTools(env, spaceId),
  });

  // 用 cmd 做已收录判断，避免 id 前缀不匹配
  const savedCmds = new Set(savedTools.map((t) => t.cmd).filter(Boolean) as string[]);

  const handleScan = async () => {
    setScanning(true);
    setScanned([]);
    setSelected(new Set());
    try {
      const result = env === "wsl" ? await scanWslDevTools() : await scanDevTools();
      setScanned(result);
      const auto = new Set(result.filter((t) => t.found && !savedCmds.has(t.cmd)).map((t) => t.id));
      setSelected(auto);
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally {
      setScanning(false);
    }
  };

  const toggle = (id: string) =>
    setSelected((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });

  const handleSaveSelected = async () => {
    const tools: SaveDevToolInput[] = scanned
      .filter((t) => selected.has(t.id))
      .map((t) => ({
        id: t.id,
        name: t.name,
        category: t.category,
        cmd: t.cmd,
        path: t.path ?? undefined,
        version: t.version ?? undefined,
        env,
        space_id: spaceId,
      }));
    if (tools.length === 0) { showToast("❌ 请至少勾选一项"); return; }
    setSaving(true);
    try {
      await saveDevTools(tools);
      qc.invalidateQueries({ queryKey: ["devTools", env, spaceId] });
      showToast(`已收录 ${tools.length} 个工具 ✓`);
      setTab("saved");
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await deleteDevTool(id);
      qc.invalidateQueries({ queryKey: ["devTools", env, spaceId] });
    } catch (e) {
      showToast(`❌ ${e}`);
    }
  };

  const groupedSaved = CATEGORY_ORDER.reduce<Record<string, DevToolRecord[]>>((acc, cat) => {
    const items = savedTools.filter((t) => t.category === cat);
    if (items.length > 0) acc[cat] = items;
    return acc;
  }, {});

  const scannedFiltered = filterCat === "all" ? scanned : scanned.filter((t) => t.category === filterCat);
  const scannedGroups = CATEGORY_ORDER.reduce<Record<string, ScannedTool[]>>((acc, cat) => {
    const items = scannedFiltered.filter((t) => t.category === cat);
    if (items.length > 0) acc[cat] = items;
    return acc;
  }, {});

  const foundCount = scanned.filter((t) => t.found).length;

  return (
    <div>
      {/* 内层 Tab */}
      <div className="flex gap-1 mb-4 bg-gray-100 p-1 rounded-lg w-fit">
        {(["saved", "scan"] as const).map((t) => (
          <button
            key={t}
            onClick={() => setTab(t)}
            className={`px-4 py-1.5 rounded-md text-sm font-medium transition-colors ${
              tab === t ? "bg-white shadow-sm text-gray-800" : "text-gray-500 hover:text-gray-700"
            }`}
          >
            {t === "saved" ? `已收录 (${savedTools.length})` : "扫描检测"}
          </button>
        ))}
      </div>

      {/* 已收录 */}
      {tab === "saved" && (
        <div>
          {savedTools.length === 0 ? (
            <div className="text-center py-16 text-gray-400">
              <p className="text-4xl mb-3">🔍</p>
              <p className="text-sm">还没有收录任何工具</p>
              <p className="text-xs mt-1">点击「扫描检测」自动发现{env === "wsl" ? " WSL " : "系统"}中已安装的工具</p>
              <button
                onClick={() => setTab("scan")}
                className="mt-4 px-4 py-2 rounded-lg text-sm bg-blue-600 text-white hover:bg-blue-700"
              >
                去扫描
              </button>
            </div>
          ) : (
            <div className="space-y-6">
              {Object.entries(groupedSaved).map(([cat, tools]) => (
                <div key={cat}>
                  <p className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-2">
                    {categoryIcon(cat)} {categoryLabel(cat)}
                  </p>
                  <div className="space-y-1.5">
                    {tools.map((t) => (
                      <SavedToolCard key={t.id} tool={t} onDelete={() => handleDelete(t.id)} />
                    ))}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* 扫描 */}
      {tab === "scan" && (
        <div>
          <div className="flex items-center gap-3 mb-4">
            <button
              onClick={handleScan}
              disabled={scanning}
              className="px-4 py-2 rounded-lg text-sm bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50"
            >
              {scanning ? "扫描中…" : "开始扫描"}
            </button>
            {scanned.length > 0 && (
              <span className="text-sm text-gray-500">
                检测到 <span className="font-medium text-green-600">{foundCount}</span> 个工具，共 {scanned.length} 项
              </span>
            )}
            {scanned.length > 0 && (
              <div className="flex-1 flex justify-end">
                <button
                  onClick={handleSaveSelected}
                  disabled={saving || selected.size === 0}
                  className="px-4 py-2 rounded-lg text-sm bg-green-600 text-white hover:bg-green-700 disabled:opacity-50"
                >
                  {saving ? "收录中…" : `收录选中 (${selected.size})`}
                </button>
              </div>
            )}
          </div>

          {scanned.length > 0 && (
            <div className="flex gap-2 flex-wrap mb-4">
              <button
                onClick={() => setFilterCat("all")}
                className={`px-3 py-1 rounded-full text-xs border transition-colors ${
                  filterCat === "all" ? "bg-blue-600 text-white border-blue-600" : "border-gray-200 text-gray-500 hover:bg-gray-50"
                }`}
              >
                全部
              </button>
              {CATEGORY_ORDER.filter((c) => scanned.some((t) => t.category === c)).map((c) => (
                <button
                  key={c}
                  onClick={() => setFilterCat(c)}
                  className={`px-3 py-1 rounded-full text-xs border transition-colors ${
                    filterCat === c ? "bg-blue-600 text-white border-blue-600" : "border-gray-200 text-gray-500 hover:bg-gray-50"
                  }`}
                >
                  {categoryIcon(c)} {categoryLabel(c)}
                </button>
              ))}
            </div>
          )}

          {scanned.length > 0 && (
            <div className="space-y-5">
              {Object.entries(scannedGroups).map(([cat, tools]) => (
                <div key={cat}>
                  <p className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-1.5">
                    {categoryIcon(cat)} {categoryLabel(cat)}
                  </p>
                  <div className="border border-gray-100 rounded-lg overflow-hidden">
                    <table className="w-full text-xs">
                      <thead className="bg-gray-50 text-gray-500">
                        <tr>
                          <th className="w-8 px-3 py-2"></th>
                          <th className="px-3 py-2 text-left font-medium">工具名称</th>
                          <th className="px-3 py-2 text-left font-medium text-gray-400">路径</th>
                        </tr>
                      </thead>
                      <tbody>
                        {tools.map((t) => (
                          <ScanRow
                            key={t.id}
                            tool={t}
                            checked={selected.has(t.id)}
                            onToggle={() => toggle(t.id)}
                            savedCmds={savedCmds}
                          />
                        ))}
                      </tbody>
                    </table>
                  </div>
                </div>
              ))}
            </div>
          )}

          {scanned.length === 0 && !scanning && (
            <div className="text-center py-16 text-gray-400">
              <p className="text-4xl mb-3">🔎</p>
              <p className="text-sm">
                点击「开始扫描」检测{env === "wsl" ? " WSL " : "系统"}中已安装的开发工具
              </p>
              <p className="text-xs mt-1 text-gray-300">会检测编辑器、运行时、包管理器、CLI 工具等共 35+ 项</p>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ── 主页面 ────────────────────────────────────────────────────────────────────

export function DevToolsPage() {
  const qc = useQueryClient();
  const [env, setEnv] = useState<DevEnv>("windows");
  const [showManual, setShowManual] = useState(false);

  const { data: spaces = [] } = useQuery({ queryKey: ["spaces"], queryFn: getSpaces });
  const spaceId = spaces.find((s) => s.is_current)?.id;

  return (
    <div className="p-6 max-w-4xl mx-auto pb-12">
      {/* 页头 */}
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-lg font-semibold text-gray-800">开发环境</h1>
          <p className="text-sm text-gray-400 mt-0.5">管理你的开发工具清单，掌握环境现状</p>
        </div>
        <button
          onClick={() => setShowManual(true)}
          className="px-3 py-1.5 rounded-lg text-sm border border-gray-200 text-gray-600 hover:bg-gray-50"
        >
          + 手动添加
        </button>
      </div>

      {/* 外层环境 Tab */}
      <div className="flex gap-1 mb-6 bg-slate-100 p-1 rounded-lg w-fit">
        <button
          onClick={() => setEnv("windows")}
          className={`px-5 py-1.5 rounded-md text-sm font-medium transition-colors ${
            env === "windows" ? "bg-white shadow-sm text-slate-800" : "text-slate-500 hover:text-slate-700"
          }`}
        >
          Windows
        </button>
        <button
          onClick={() => setEnv("wsl")}
          className={`px-5 py-1.5 rounded-md text-sm font-medium transition-colors ${
            env === "wsl" ? "bg-white shadow-sm text-slate-800" : "text-slate-500 hover:text-slate-700"
          }`}
        >
          WSL
        </button>
      </div>

      {/* 环境内容 */}
      <EnvPanel key={`${env}-${spaceId}`} env={env} spaceId={spaceId} />

      {showManual && (
        <AddManualModal
          env={env}
          spaceId={spaceId}
          onClose={() => setShowManual(false)}
          onSaved={() => {
            qc.invalidateQueries({ queryKey: ["devTools", env, spaceId] });
          }}
        />
      )}
    </div>
  );
}
