import { useState, useEffect } from "react";
import { open as openDialog } from "@tauri-apps/plugin-dialog";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import {
  detectV2raynDbPath, getActiveV2raynNode, scanV2raynNodes, buildShareLink,
  syncWslProxy, getWslProxyStatus, clearWslProxy,
  testWslProxyIp, testWinProxyIp,
  getSettings, updateSettings,
  CONFIG_TYPE_LABEL,
  type ActiveV2raynNode, type V2raynNode, type WslProxyStatus,
} from "../../lib/commands";
import { useUIStore } from "../../store/ui";

const inputCls = "flex-1 border border-gray-200 rounded-lg px-3 py-2 text-xs font-mono outline-none focus:ring-2 focus:ring-blue-200";

// ── Win 代理配置卡片 ──────────────────────────────────────────────────────────

function WinProxyCard({ onPathSaved }: { onPathSaved: (path: string) => void }) {
  const showToast = useUIStore((s) => s.showToast);
  const qc = useQueryClient();

  const { data: settings } = useQuery({
    queryKey: ["settings", undefined],
    queryFn: () => getSettings(undefined),
    staleTime: 30000,
  });

  const [dbPath, setDbPath] = useState("");
  const [detecting, setDetecting] = useState(false);
  const [loadingNode, setLoadingNode] = useState(false);
  const [activeNode, setActiveNode] = useState<ActiveV2raynNode | null>(null);

  const saved = settings?.v2rayn_db_path ?? "";

  useEffect(() => {
    if (saved) { setDbPath(saved); onPathSaved(saved); }
  }, [saved]);

  const handleDetect = async () => {
    setDetecting(true);
    try {
      const found = await detectV2raynDbPath();
      if (found) {
        setDbPath(found);
        showToast(`已找到：${found}`);
      } else {
        showToast("未自动找到，请手动浏览选择文件");
      }
    } finally { setDetecting(false); }
  };

  const handleBrowse = async () => {
    const selected = await openDialog({
      multiple: false,
      filters: [{ name: "v2rayN 数据库", extensions: ["db"] }],
    });
    if (selected) setDbPath(selected as string);
  };

  const handleSave = async () => {
    if (!dbPath.trim()) { showToast("❌ 路径不能为空"); return; }
    await updateSettings({ v2rayn_db_path: dbPath.trim() }, undefined);
    qc.invalidateQueries({ queryKey: ["settings", undefined] });
    onPathSaved(dbPath.trim());
    showToast("已保存 ✓");
  };

  const handleReadNode = async () => {
    const path = dbPath.trim() || saved;
    if (!path) { showToast("❌ 请先配置 v2rayN 路径"); return; }
    setLoadingNode(true);
    try {
      const node = await getActiveV2raynNode(path);
      setActiveNode(node);
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally { setLoadingNode(false); }
  };

  const isChanged = dbPath.trim() !== saved;

  return (
    <div className="bg-white rounded-xl border border-gray-100 shadow-sm p-5 space-y-4">
      <div className="flex items-center gap-2">
        <span className="text-base">🪟</span>
        <p className="text-sm font-semibold text-gray-700">Windows 代理（v2rayN）</p>
      </div>

      {/* 路径配置 */}
      <div className="space-y-2">
        <div className="flex gap-2">
          <input
            value={dbPath}
            onChange={(e) => setDbPath(e.target.value)}
            placeholder="v2rayN guiNDB.db 路径"
            className={inputCls}
          />
          <button
            onClick={handleDetect}
            disabled={detecting}
            className="px-3 py-2 rounded-lg text-xs border border-gray-200 text-gray-600 hover:bg-gray-50 disabled:opacity-50 shrink-0 transition-colors"
          >
            {detecting ? "扫描中…" : "扫描"}
          </button>
          <button
            onClick={handleBrowse}
            className="px-3 py-2 rounded-lg text-xs border border-gray-200 text-gray-600 hover:bg-gray-50 shrink-0 transition-colors"
          >
            📁
          </button>
        </div>
        <div className="flex items-center justify-between">
          <p className="text-xs text-gray-400">
            通常位于：<code className="font-mono bg-gray-50 px-1 rounded">%APPDATA%\v2rayN\guiConfigs\guiNDB.db</code>
          </p>
          <button
            onClick={handleSave}
            disabled={!isChanged || !dbPath.trim()}
            className="px-4 py-1.5 rounded-lg text-xs bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-40 transition-colors shrink-0 ml-2"
          >
            保存路径
          </button>
        </div>
        {saved && (
          <div className="flex items-center gap-1.5 text-xs text-green-600">
            <span className="w-2 h-2 rounded-full bg-green-400 shrink-0" />
            已配置：<span className="font-mono truncate">{saved}</span>
          </div>
        )}
      </div>

      {/* 当前节点 */}
      <div className="border-t border-gray-100 pt-3 flex items-center gap-3">
        <button
          onClick={handleReadNode}
          disabled={loadingNode || (!dbPath.trim() && !saved)}
          className="px-3 py-2 rounded-lg text-xs border border-gray-200 text-gray-600 hover:bg-gray-50 disabled:opacity-40 shrink-0 transition-colors"
        >
          {loadingNode ? "读取中…" : "读取当前节点"}
        </button>
        {activeNode ? (
          <div className="flex-1 flex items-center gap-2 px-3 py-2 bg-blue-50 rounded-lg border border-blue-100 min-w-0">
            <span className="text-xs font-semibold text-blue-700 shrink-0">
              {CONFIG_TYPE_LABEL[activeNode.config_type] ?? "?"}
            </span>
            <span className="text-xs font-medium text-blue-800 truncate">{activeNode.remarks}</span>
            <span className="text-xs text-blue-400 font-mono shrink-0">
              {activeNode.address}:{activeNode.port}
            </span>
          </div>
        ) : (
          <p className="text-xs text-gray-400">点击读取 v2rayN 当前激活节点</p>
        )}
      </div>
    </div>
  );
}

// ── WSL 代理同步卡片 ──────────────────────────────────────────────────────────

function WslSyncCard({ dbPath }: { dbPath: string }) {
  const showToast = useUIStore((s) => s.showToast);
  const [status, setStatus] = useState<WslProxyStatus | null>(null);
  const [loading, setLoading] = useState(false);
  const [syncing, setSyncing] = useState(false);
  const [clearing, setClearing] = useState(false);

  const refreshStatus = async () => {
    setLoading(true);
    try {
      const s = await getWslProxyStatus();
      setStatus(s);
    } catch {
      setStatus(null);
    } finally { setLoading(false); }
  };

  // 不再自动刷新 — WSL 状态检测较慢，由用户手动点击「刷新状态」触发

  const handleSync = async () => {
    setSyncing(true);
    try {
      const msg = await syncWslProxy(dbPath || undefined);
      showToast(`✓ ${msg}`);
      await refreshStatus();
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally { setSyncing(false); }
  };

  const handleClear = async () => {
    setClearing(true);
    try {
      await clearWslProxy();
      showToast("WSL 代理配置已清除");
      await refreshStatus();
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally { setClearing(false); }
  };

  return (
    <div className="bg-white rounded-xl border border-gray-100 shadow-sm p-5 space-y-4">
      <div className="flex items-center gap-2">
        <span className="text-base">🐧</span>
        <p className="text-sm font-semibold text-gray-700">WSL 代理同步</p>
        <button
          onClick={refreshStatus}
          disabled={loading}
          className="ml-auto text-xs text-gray-400 hover:text-gray-600 disabled:opacity-40 transition-colors"
        >
          {loading ? "检测中…" : "刷新状态"}
        </button>
      </div>

      {/* 状态指示 */}
      {status === null ? (
        <div className="flex items-center gap-2 px-4 py-3 rounded-xl bg-gray-50 border border-dashed border-gray-200">
          <span className="w-2.5 h-2.5 rounded-full bg-gray-300 shrink-0" />
          <span className="text-xs text-gray-400">WSL 状态未知（点击刷新状态）</span>
        </div>
      ) : status.configured ? (
        <div className="space-y-2">
          {/* 多个警告可并存，由上到下优先级降低 */}
          {status.stale && (
            <div className="flex items-center gap-2 px-4 py-3 rounded-xl bg-yellow-50 border border-yellow-300">
              <span className="w-2.5 h-2.5 rounded-full bg-yellow-400 shrink-0" />
              <div className="flex-1 min-w-0">
                <span className="text-xs font-semibold text-yellow-700">⚠ IP 已变更，需重新同步</span>
                <span className="text-xs text-yellow-600 ml-2 font-mono">
                  {status.configured_ip ?? "?"} → {status.current_ip ?? "?"}
                </span>
              </div>
            </div>
          )}
          {status.bashrc_ok === false && (
            <div className="flex items-center gap-2 px-4 py-3 rounded-xl bg-orange-50 border border-orange-300">
              <span className="w-2.5 h-2.5 rounded-full bg-orange-400 shrink-0" />
              <div className="flex-1 min-w-0">
                <span className="text-xs font-semibold text-orange-700">⚠ 非登录 Shell 代理链接已断开</span>
                <span className="text-xs text-orange-600 ml-2">/etc/bash.bashrc source 行缺失，请重新同步</span>
              </div>
            </div>
          )}
          {!status.stale && status.bashrc_ok !== false && (
            <div className="flex items-center gap-2 px-4 py-3 rounded-xl bg-green-50 border border-green-200">
              <span className="w-2.5 h-2.5 rounded-full bg-green-400 shrink-0 animate-pulse" />
              <div className="flex-1 min-w-0">
                <span className="text-xs font-semibold text-green-700">已配置</span>
                {status.port && (
                  <span className="text-xs text-green-600 ml-2 font-mono">
                    http_proxy=http://{status.current_ip ?? "win-host"}:{status.port}
                  </span>
                )}
              </div>
            </div>
          )}
        </div>
      ) : (
        <div className="flex items-center gap-2 px-4 py-3 rounded-xl bg-gray-50 border border-dashed border-gray-200">
          <span className="w-2.5 h-2.5 rounded-full bg-gray-300 shrink-0" />
          <span className="text-xs text-gray-500">未配置，点击「同步到 WSL」完成设置</span>
        </div>
      )}

      {/* 操作按钮 */}
      <div className="flex gap-2">
        <button
          onClick={handleSync}
          disabled={syncing || !dbPath}
          className="flex-1 py-2.5 rounded-xl text-sm font-semibold bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-40 transition-colors"
        >
          {syncing ? "同步中…" : "同步到 WSL"}
        </button>
        {status?.configured && (
          <button
            onClick={handleClear}
            disabled={clearing}
            className="px-4 py-2.5 rounded-xl text-sm border border-red-200 text-red-500 hover:bg-red-50 disabled:opacity-40 transition-colors"
          >
            {clearing ? "清除中…" : "清除"}
          </button>
        )}
      </div>

      {!dbPath && (
        <p className="text-xs text-amber-500">⚠ 请先完成上方「Win 代理配置」并保存路径</p>
      )}

      {/* 说明 */}
      <div className="px-4 py-3 rounded-xl bg-gray-50 border border-gray-100 space-y-1.5">
        <p className="text-xs font-medium text-gray-500">同步后的效果</p>
        <p className="text-xs text-gray-400">
          写入 <code className="font-mono bg-white px-1 rounded border border-gray-100">/etc/profile.d/v2rayn-proxy.sh</code>，新开终端自动生效
        </p>
        <p className="text-xs text-gray-400">
          当前终端立即生效：<code className="font-mono bg-white px-1 rounded border border-gray-100">source /etc/profile.d/v2rayn-proxy.sh</code>
        </p>
        <p className="text-xs text-gray-400">适用于 curl、git、npm、pip 等命令行工具</p>
      </div>
    </div>
  );
}

// ── 代理一致性测试卡片 ────────────────────────────────────────────────────────

type IpState = { status: "idle" } | { status: "loading" } | { status: "ok"; ip: string } | { status: "error"; msg: string };

function ProxyTestCard() {
  const [winState, setWinState] = useState<IpState>({ status: "idle" });
  const [wslState, setWslState] = useState<IpState>({ status: "idle" });
  const [testing, setTesting] = useState(false);

  const runTest = async () => {
    setTesting(true);
    setWinState({ status: "loading" });
    setWslState({ status: "loading" });

    const [winResult, wslResult] = await Promise.allSettled([
      testWinProxyIp(),
      testWslProxyIp(),
    ]);

    setWinState(
      winResult.status === "fulfilled"
        ? { status: "ok", ip: winResult.value }
        : { status: "error", msg: String(winResult.reason) },
    );
    setWslState(
      wslResult.status === "fulfilled"
        ? { status: "ok", ip: wslResult.value }
        : { status: "error", msg: String(wslResult.reason) },
    );
    setTesting(false);
  };

  const winIp = winState.status === "ok" ? winState.ip : null;
  const wslIp = wslState.status === "ok" ? wslState.ip : null;
  const bothDone = winState.status !== "idle" && winState.status !== "loading"
    && wslState.status !== "idle" && wslState.status !== "loading";
  const consistent = bothDone && winIp !== null && wslIp !== null && winIp === wslIp;

  return (
    <div className="bg-white rounded-xl border border-gray-100 shadow-sm p-5 space-y-4">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <span className="text-base">🔍</span>
          <p className="text-sm font-semibold text-gray-700">代理一致性测试</p>
        </div>
        <button
          onClick={runTest}
          disabled={testing}
          className="px-4 py-2 rounded-lg text-xs font-semibold bg-gray-800 text-white hover:bg-gray-700 disabled:opacity-40 transition-colors"
        >
          {testing ? "测试中…" : "开始测试"}
        </button>
      </div>

      {/* 结果行 */}
      <div className="space-y-2">
        {(
          [
            { label: "🪟 Windows", state: winState },
            { label: "🐧 WSL",     state: wslState },
          ] as const
        ).map(({ label, state }) => (
          <div key={label} className="flex items-center gap-3 px-4 py-3 rounded-xl bg-gray-50 border border-gray-100">
            <span className="text-xs font-medium text-gray-500 w-20 shrink-0">{label}</span>
            {state.status === "idle" && (
              <span className="text-xs text-gray-300">点击测试</span>
            )}
            {state.status === "loading" && (
              <span className="text-xs text-gray-400 animate-pulse">请求中…</span>
            )}
            {state.status === "ok" && (
              <code className="text-xs font-mono text-gray-700 bg-white px-2 py-0.5 rounded border border-gray-100">
                {state.ip}
              </code>
            )}
            {state.status === "error" && (
              <span className="text-xs text-red-500 truncate">{state.msg}</span>
            )}
          </div>
        ))}
      </div>

      {/* 对比结果 */}
      {bothDone && (
        <div className={`flex items-center gap-2 px-4 py-3 rounded-xl border ${
          consistent
            ? "bg-green-50 border-green-200"
            : winIp && wslIp
              ? "bg-red-50 border-red-200"
              : "bg-amber-50 border-amber-200"
        }`}>
          {consistent ? (
            <>
              <span className="text-green-500 font-bold">✓</span>
              <span className="text-xs font-semibold text-green-700">出口 IP 一致，代理效果相同</span>
            </>
          ) : winIp && wslIp ? (
            <>
              <span className="text-red-500 font-bold">✗</span>
              <span className="text-xs font-semibold text-red-700">出口 IP 不一致，请重新同步代理</span>
            </>
          ) : (
            <>
              <span className="text-amber-500">⚠</span>
              <span className="text-xs text-amber-700">部分测试失败，请检查错误信息</span>
            </>
          )}
        </div>
      )}

      <p className="text-xs text-gray-400">
        两侧均通过 <code className="font-mono">api.ipify.org</code> 获取出口 IP，测试约需 5-15 秒
      </p>
    </div>
  );
}

// ── 节点列表（可选，用于查看/复制）────────────────────────────────────────────

const TYPE_COLOR: Record<number, string> = {
  1: "bg-blue-100 text-blue-700",
  3: "bg-purple-100 text-purple-700",
  5: "bg-green-100 text-green-700",
  6: "bg-orange-100 text-orange-700",
  7: "bg-pink-100 text-pink-700",
};

function NodeListCard({ dbPath }: { dbPath: string }) {
  const showToast = useUIStore((s) => s.showToast);
  const [nodes, setNodes] = useState<V2raynNode[]>([]);
  const [loading, setLoading] = useState(false);
  const [expanded, setExpanded] = useState(false);

  const handleScan = async () => {
    if (!dbPath) { showToast("❌ 请先设置 v2rayN 路径"); return; }
    setLoading(true);
    try {
      const result = await scanV2raynNodes(dbPath);
      setNodes(result);
      setExpanded(true);
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally { setLoading(false); }
  };

  const copyLink = async (node: V2raynNode) => {
    const link = buildShareLink(node);
    if (!link) { showToast("❌ 暂不支持此协议"); return; }
    await navigator.clipboard.writeText(link).then(
      () => showToast(`已复制 ${node.remarks} ✓`),
      () => showToast("❌ 复制失败"),
    );
  };

  return (
    <div className="bg-white rounded-xl border border-gray-100 shadow-sm p-5 space-y-3">
      <div className="flex items-center justify-between">
        <p className="text-sm font-semibold text-gray-700">节点列表</p>
        <div className="flex items-center gap-2">
          {nodes.length > 0 && (
            <button
              onClick={() => setExpanded(!expanded)}
              className="text-xs text-gray-400 hover:text-gray-600"
            >
              {expanded ? "收起" : `展开 ${nodes.length} 个`}
            </button>
          )}
          <button
            onClick={handleScan}
            disabled={loading || !dbPath}
            className="px-3 py-1.5 rounded-lg text-xs bg-gray-100 text-gray-600 hover:bg-gray-200 disabled:opacity-40 transition-colors"
          >
            {loading ? "读取中…" : "读取全部节点"}
          </button>
        </div>
      </div>
      <p className="text-xs text-gray-400">可查看所有节点并复制 share link</p>

      {expanded && nodes.length > 0 && (
        <div className="space-y-1.5 max-h-64 overflow-y-auto">
          {nodes.map((node) => (
            <div
              key={node.index_id}
              className="flex items-center gap-3 px-3 py-2.5 bg-gray-50 rounded-lg border border-gray-100 group"
            >
              <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2 flex-wrap">
                  <span className="text-xs font-medium text-gray-700 truncate">{node.remarks}</span>
                  <span className={`text-xs px-1.5 py-0.5 rounded font-medium shrink-0 ${TYPE_COLOR[node.config_type] ?? "bg-gray-100 text-gray-600"}`}>
                    {CONFIG_TYPE_LABEL[node.config_type] ?? "Unknown"}
                  </span>
                </div>
                <p className="text-xs font-mono text-gray-400 mt-0.5">{node.address}:{node.port}</p>
              </div>
              <button
                onClick={() => copyLink(node)}
                className="opacity-0 group-hover:opacity-100 px-2 py-1 rounded text-xs border border-blue-200 text-blue-600 hover:bg-blue-50 transition-all"
              >
                复制链接
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── 交互教程 ──────────────────────────────────────────────────────────────────

function CodeBlock({ code }: { code: string }) {
  const showToast = useUIStore((s) => s.showToast);
  return (
    <div className="relative group">
      <pre className="font-mono bg-gray-900 text-green-300 rounded-lg px-4 py-3 text-xs leading-relaxed whitespace-pre overflow-x-auto">
        {code}
      </pre>
      <button
        onClick={() => navigator.clipboard.writeText(code).then(() => showToast("已复制 ✓"))}
        className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 px-2 py-1 rounded text-xs bg-gray-700 text-gray-300 hover:bg-gray-600 transition-all"
      >
        复制
      </button>
    </div>
  );
}

type Section = {
  id: string;
  icon: string;
  title: string;
  tag?: string;
  content: React.ReactNode;
};

const GUIDE_SECTIONS: Section[] = [
  {
    id: "concept",
    icon: "💡",
    title: "核心概念：出口 IP 才是判断标准",
    content: (
      <div className="space-y-3 text-xs text-gray-600 leading-relaxed">
        <p>WSL 和 Windows 各有自己的 IP，但这些都是"内部地址"，不重要。</p>
        <div className="bg-gray-50 rounded-lg p-3 font-mono text-xs space-y-1">
          <p><span className="text-gray-400">你的机器</span> → <span className="text-blue-600">v2rayN (Win)</span> → <span className="text-green-600 font-semibold">36.50.x.x（出口 IP）</span> → 目标网站</p>
          <p><span className="text-gray-400">WSL</span>{"     "}→ <span className="text-blue-600">v2rayN (Win)</span> → <span className="text-green-600 font-semibold">36.50.x.x（出口 IP）</span> → 目标网站</p>
        </div>
        <p>两边出口 IP 相同 = 代理效果一致。用本应用的「代理一致性测试」验证。</p>
      </div>
    ),
  },
  {
    id: "why-simple",
    icon: "🔗",
    title: "为什么不需要在 WSL 装 v2rayA",
    tag: "经验教训",
    content: (
      <div className="space-y-2 text-xs text-gray-600 leading-relaxed">
        <p>v2rayA 方案很复杂：需要安装、配置账号、对接 REST API，还有各种坑。</p>
        <p>其实 v2rayN 已经开了 <code className="bg-gray-100 px-1 rounded font-mono">AllowLAN = true</code>，WSL 可以直接通过 Windows 宿主机 IP 访问它：</p>
        <CodeBlock code={`# WSL 里获取 Windows 宿主机 IP
ip route | grep default | awk '{print $3}'
# 通常是 172.x.x.1

# 直接通过 Windows v2rayN 代理访问网络
export http_proxy="http://172.x.x.1:10808"
curl https://api.ipify.org  # 返回的就是代理出口 IP`} />
        <p className="text-green-700 font-medium">结论：WSL 只需要设置环境变量，不需要安装任何代理软件。</p>
      </div>
    ),
  },
  {
    id: "quickpath",
    icon: "⚡",
    title: "最佳捷径：三步完成配置",
    tag: "推荐流程",
    content: (
      <div className="space-y-4 text-xs text-gray-600">
        <div className="space-y-1">
          <p className="font-semibold text-gray-700">① 确认 v2rayN 开启了 AllowLAN</p>
          <p>v2rayN → 参数设置 → Core 类型设置 → 确认「允许来自局域网的连接」已勾选</p>
        </div>
        <div className="space-y-1">
          <p className="font-semibold text-gray-700">② 本应用一键同步</p>
          <p>「Win 代理配置」设好路径 → 点「同步到 WSL」→ 自动写入代理配置</p>
        </div>
        <div className="space-y-1">
          <p className="font-semibold text-gray-700">③ 重开终端或手动 source</p>
          <CodeBlock code={`source ~/.bashrc
# 验证
echo $http_proxy          # 应有值
curl https://api.ipify.org  # 应返回代理出口 IP`} />
        </div>
        <div className="bg-blue-50 border border-blue-100 rounded-lg px-3 py-2">
          <p className="text-blue-700">重装后恢复：装好 v2rayN → 装好本应用 → 点「同步到 WSL」，完成。</p>
        </div>
      </div>
    ),
  },
  {
    id: "pitfall-binary",
    icon: "⚠️",
    title: "坑：工具是 Windows 程序，WSL 代理对它无效",
    tag: "常见陷阱",
    content: (
      <div className="space-y-3 text-xs text-gray-600">
        <p>在 WSL 里敲命令，不代表它就是 Linux 程序。路径以 <code className="bg-gray-100 px-1 rounded font-mono">/mnt/c/</code> 开头的都是 Windows 程序，走 Windows 网络栈，WSL 的 <code className="bg-gray-100 px-1 rounded font-mono">http_proxy</code> 对它完全无效。</p>
        <p className="font-semibold text-gray-700">快速诊断：</p>
        <CodeBlock code={`which opencode          # 看路径
# /mnt/c/... → Windows 程序 ❌（WSL 代理无效）
# /usr/... 或 /home/... → Linux 程序 ✓

file $(which opencode)  # 更准确
# ELF 64-bit → Linux 原生 ✓
# PE32 / Windows  → Windows 程序 ❌`} />
        <p className="font-semibold text-gray-700">解决方案：安装 Linux 原生版本</p>
        <CodeBlock code={`# 以 opencode 为例——找到已装的 Linux 版位置
find ~/.npm-global -name 'opencode' -type f
# 建 symlink 覆盖 Windows 版（/usr/local/bin 优先级高于 Windows PATH）
sudo ln -sf /path/to/linux/opencode /usr/local/bin/opencode
# 验证
file $(which opencode)  # 应为 ELF`} />
      </div>
    ),
  },
  {
    id: "pitfall-shell",
    icon: "⚠️",
    title: "坑：代理变量只在部分 Shell 类型生效",
    tag: "常见陷阱",
    content: (
      <div className="space-y-3 text-xs text-gray-600">
        <div className="overflow-x-auto">
          <table className="w-full text-xs border-collapse">
            <thead>
              <tr className="bg-gray-50">
                <th className="text-left px-3 py-2 border border-gray-100 font-medium text-gray-700">Shell 类型</th>
                <th className="text-left px-3 py-2 border border-gray-100 font-medium text-gray-700">加载来源</th>
                <th className="text-left px-3 py-2 border border-gray-100 font-medium text-gray-700">代理是否自动生效</th>
              </tr>
            </thead>
            <tbody>
              {[
                ["登录 Shell（Ubuntu 终端图标）", "/etc/profile.d/", "✓ 自动"],
                ["非登录交互 Shell（VSCode 终端）", "~/.bashrc", "✓ 自动（同步时已写入）"],
                ["非交互 Shell（脚本、子进程）", "不加载任何配置", "需继承父进程环境"],
              ].map(([type, source, result]) => (
                <tr key={type}>
                  <td className="px-3 py-2 border border-gray-100">{type}</td>
                  <td className="px-3 py-2 border border-gray-100 font-mono text-gray-500">{source}</td>
                  <td className={`px-3 py-2 border border-gray-100 font-medium ${result.startsWith("✓") ? "text-green-600" : "text-amber-600"}`}>{result}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <p>本应用同步时会同时写入 <code className="bg-gray-100 px-1 rounded font-mono">/etc/profile.d/</code>、<code className="bg-gray-100 px-1 rounded font-mono">/etc/bash.bashrc</code>、<code className="bg-gray-100 px-1 rounded font-mono">~/.bashrc</code>，覆盖所有场景。</p>
        <p className="font-semibold text-gray-700">如果当前终端没生效（旧会话）：</p>
        <CodeBlock code={`source ~/.bashrc
echo $http_proxy  # 验证是否有值`} />
      </div>
    ),
  },
  {
    id: "diagnose",
    icon: "🔍",
    title: "快速诊断清单",
    content: (
      <div className="space-y-3 text-xs text-gray-600">
        <p>遇到 WSL 里无法联网时，按顺序排查：</p>
        <CodeBlock code={`# 1. 代理变量是否存在？
echo $http_proxy
# 空 → source ~/.bashrc 或重开终端

# 2. 代理能通么？
curl -s --max-time 5 --proxy "$http_proxy" https://api.ipify.org
# 超时/失败 → v2rayN 节点挂了，切换节点后重新同步

# 3. 工具是 Linux 还是 Windows 程序？
file $(which 工具名)
# Windows PE → 找 Linux 原生版或用 WSLENV 传参

# 4. 出口 IP 是否与 Windows 一致？
# 用本应用「代理一致性测试」按钮验证`} />
      </div>
    ),
  },
];

function ProxyGuideCard() {
  const [open, setOpen] = useState(false);
  const [activeId, setActiveId] = useState<string | null>(null);

  return (
    <div className="bg-white rounded-xl border border-gray-100 shadow-sm overflow-hidden">
      {/* 标题栏 */}
      <button
        onClick={() => setOpen(!open)}
        className="w-full flex items-center justify-between px-5 py-4 hover:bg-gray-50 transition-colors"
      >
        <div className="flex items-center gap-2">
          <span className="text-base">📖</span>
          <p className="text-sm font-semibold text-gray-700">WSL 代理配置指南</p>
          <span className="text-xs px-2 py-0.5 rounded-full bg-blue-50 text-blue-600 border border-blue-100">
            经验沉淀
          </span>
        </div>
        <span className={`text-gray-400 text-xs transition-transform ${open ? "rotate-180" : ""}`}>▼</span>
      </button>

      {open && (
        <div className="border-t border-gray-100">
          {/* 章节导航 */}
          <div className="flex gap-1 px-5 py-3 overflow-x-auto border-b border-gray-50 bg-gray-50">
            {GUIDE_SECTIONS.map((s) => (
              <button
                key={s.id}
                onClick={() => setActiveId(activeId === s.id ? null : s.id)}
                className={`shrink-0 px-3 py-1.5 rounded-lg text-xs font-medium transition-colors ${
                  activeId === s.id
                    ? "bg-blue-600 text-white"
                    : "bg-white border border-gray-200 text-gray-600 hover:border-blue-300 hover:text-blue-600"
                }`}
              >
                {s.icon} {s.title.split("：")[0].split("：")[0].replace(/^.*?[：:]\s*/, "").substring(0, 16) || s.title.substring(0, 16)}
              </button>
            ))}
          </div>

          {/* 内容区 */}
          <div className="divide-y divide-gray-50">
            {GUIDE_SECTIONS.map((s) => (
              <div key={s.id}>
                <button
                  onClick={() => setActiveId(activeId === s.id ? null : s.id)}
                  className="w-full flex items-center gap-3 px-5 py-3.5 hover:bg-gray-50 transition-colors text-left"
                >
                  <span className="text-sm">{s.icon}</span>
                  <span className="flex-1 text-xs font-semibold text-gray-700">{s.title}</span>
                  {s.tag && (
                    <span className={`text-xs px-2 py-0.5 rounded-full shrink-0 ${
                      s.tag === "经验教训" ? "bg-amber-50 text-amber-600 border border-amber-100" :
                      s.tag === "推荐流程" ? "bg-green-50 text-green-600 border border-green-100" :
                      s.tag === "常见陷阱" ? "bg-red-50 text-red-600 border border-red-100" :
                      "bg-gray-100 text-gray-500"
                    }`}>
                      {s.tag}
                    </span>
                  )}
                  <span className={`text-gray-400 text-xs transition-transform shrink-0 ${activeId === s.id ? "rotate-180" : ""}`}>▼</span>
                </button>
                {activeId === s.id && (
                  <div className="px-5 pb-5 pt-1">{s.content}</div>
                )}
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

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

export function ProxyPage() {
  const [savedDbPath, setSavedDbPath] = useState("");

  return (
    <div className="max-w-2xl mx-auto px-6 py-6 space-y-4 pb-12">
      <div>
        <h1 className="text-lg font-semibold text-gray-800">代理管理</h1>
        <p className="text-sm text-gray-400 mt-0.5">
          读取 Windows v2rayN 代理配置，一键同步到 WSL 环境变量
        </p>
      </div>

      <WinProxyCard onPathSaved={setSavedDbPath} />
      <WslSyncCard dbPath={savedDbPath} />
      <ProxyTestCard />
      <NodeListCard dbPath={savedDbPath} />
      <ProxyGuideCard />
    </div>
  );
}
