"use client";

import { Loader2, MonitorPlay, Plus, Radio, RefreshCw, Trash2 } from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";

import {
  buildYoutubeIniFromFields,
  parseYoutubeIniFields,
  parseYoutubeStreamKeySuffix,
  type YoutubeIniFields,
} from "@/lib/youtubeConfigUtils";
import { LiveProcessLiveLogCard } from "@/components/live-product/LiveProcessLiveLogCard";
import {
  defaultPm2NameForChannel,
  loadYoutubeProChannels,
  newChannelId,
  saveYoutubeProChannels,
  type YoutubeProChannel,
} from "@/lib/youtubeProChannels";

type ProcessEntry = { pm2: string; script: string; label: string };

type TFn = (zh: string, en: string) => string;

function isYoutubeProcess(e: ProcessEntry) {
  return /youtube/i.test(e.script) || /youtube/i.test(e.pm2);
}

const MODE_KEY = "live-hub-youtube-mode-v1";

type Props = {
  t: TFn;
  busy: boolean;
  entries: ProcessEntry[];
  currentProc: string;
  setCurrentProc: (v: string) => void;
  urlConfig: string;
  setUrlConfig: (v: string) => void;
  onRunProcess: (a: "start" | "stop" | "restart", processPm2?: string) => void;
  onSaveUrlConfig: (content?: string) => void | Promise<void>;
  fetchJson: <T,>(path: string, init?: RequestInit) => Promise<T>;
};

export function LiveYoutubeUnmannedView({
  t,
  busy,
  entries,
  currentProc,
  setCurrentProc,
  urlConfig,
  setUrlConfig,
  onRunProcess,
  onSaveUrlConfig,
  fetchJson,
}: Props) {
  const ytEntries = useMemo(() => entries.filter(isYoutubeProcess), [entries]);
  const processOptions = ytEntries.length ? ytEntries : entries;

  const [mode, setMode] = useState<"single" | "pro">("single");
  const [channels, setChannels] = useState<YoutubeProChannel[]>([]);
  const [activeCh, setActiveCh] = useState<string>("");
  const [youtubeIniText, setYoutubeIniText] = useState("");
  const [ytFields, setYtFields] = useState<YoutubeIniFields>({
    key: "",
    rtmps: true,
    bitrate: "",
    fastAudio: false,
  });
  const [ytIniStatus, setYtIniStatus] = useState<string | null>(null);
  const [ytIniLoading, setYtIniLoading] = useState(false);
  const [proUrlDraft, setProUrlDraft] = useState("");
  const [urlAutoRefresh, setUrlAutoRefresh] = useState(true);
  const [urlReloading, setUrlReloading] = useState(false);
  const [urlFetchNote, setUrlFetchNote] = useState<string | null>(null);
  const urlListDirtyRef = useRef(false);

  useEffect(() => {
    urlListDirtyRef.current = false;
  }, [currentProc]);

  const pullUrlConfigFromServer = useCallback(async () => {
    if (!currentProc) return;
    try {
      const data = await fetchJson<{ content?: string }>(
        `/get_url_config?process=${encodeURIComponent(currentProc)}`,
      );
      const c = data.content ?? "";
      if (mode === "single") setUrlConfig(c);
      else setProUrlDraft(c);
    } catch {
      /* ignore */
    }
  }, [currentProc, fetchJson, mode, setUrlConfig]);

  useEffect(() => {
    if (!currentProc || !urlAutoRefresh) return;
    const id = window.setInterval(() => {
      if (urlListDirtyRef.current) return;
      void pullUrlConfigFromServer();
    }, 8000);
    return () => clearInterval(id);
  }, [currentProc, urlAutoRefresh, pullUrlConfigFromServer]);

  const reloadUrlManual = async () => {
    if (!currentProc) return;
    setUrlReloading(true);
    setUrlFetchNote(null);
    urlListDirtyRef.current = false;
    try {
      const data = await fetchJson<{ content?: string }>(
        `/get_url_config?process=${encodeURIComponent(currentProc)}`,
      );
      const c = data.content ?? "";
      if (mode === "single") setUrlConfig(c);
      else setProUrlDraft(c);
      setUrlFetchNote(t("已从服务器读取 URL_config", "Reloaded URL_config from server"));
    } catch (e) {
      setUrlFetchNote((e as Error).message);
    } finally {
      setUrlReloading(false);
    }
  };

  useEffect(() => {
    try {
      const m = window.localStorage.getItem(MODE_KEY);
      if (m === "pro" || m === "single") setMode(m);
    } catch {
      /* ignore */
    }
  }, []);

  const setModePersist = (m: "single" | "pro") => {
    setMode(m);
    if (m === "pro") {
      const ch = channels.find((c) => c.id === activeCh) ?? channels[0];
      if (ch) {
        const u = (ch.urlLines ?? "").trim();
        setProUrlDraft(u || urlConfig);
      }
    }
    try {
      window.localStorage.setItem(MODE_KEY, m);
    } catch {
      /* ignore */
    }
  };

  useEffect(() => {
    const list = loadYoutubeProChannels();
    const initial =
      list.length > 0
        ? list
        : (() => {
            const id = newChannelId();
            return [
              {
                id,
                name: "线路 1",
                streamKey: "",
                urlLines: "",
                pm2Name: defaultPm2NameForChannel(id),
                notes: "",
              },
            ];
          })();
    setChannels(initial);
    if (!list.length) saveYoutubeProChannels(initial);
  }, []);

  useEffect(() => {
    if (channels.length && !activeCh) setActiveCh(channels[0].id);
  }, [channels, activeCh]);

  const persistChannels = useCallback((next: YoutubeProChannel[]) => {
    setChannels(next);
    saveYoutubeProChannels(next);
  }, []);

  const active = channels.find((c) => c.id === activeCh) || channels[0];

  const proLanesWithKey = useMemo(
    () => channels.filter((ch) => (ch.streamKey ?? "").trim().length > 0),
    [channels],
  );

  const selectProChannel = useCallback(
    (c: YoutubeProChannel) => {
      if (active && mode === "pro") {
        persistChannels(channels.map((x) => (x.id === active.id ? { ...x, urlLines: proUrlDraft } : x)));
      }
      const u = (c.urlLines ?? "").trim();
      setProUrlDraft(u || urlConfig);
      setActiveCh(c.id);
    },
    [active, mode, channels, proUrlDraft, urlConfig, persistChannels],
  );

  useEffect(() => {
    if (mode !== "pro" || !activeCh) return;
    const ch = channels.find((x) => x.id === activeCh);
    if (!ch) return;
    const want = (ch.pm2Name ?? "").trim() || defaultPm2NameForChannel(ch.id);
    if (processOptions.some((e) => e.pm2 === want)) setCurrentProc(want);
  }, [mode, activeCh, channels, processOptions, setCurrentProc]);

  const loadYoutubeIni = useCallback(async () => {
    if (!currentProc) return;
    setYtIniLoading(true);
    setYtIniStatus(null);
    try {
      const data = await fetchJson<{ content?: string }>(
        `/get_config?process=${encodeURIComponent(currentProc)}`,
      );
      const text = data.content ?? "";
      setYoutubeIniText(text);
      setYtFields(parseYoutubeIniFields(text));
    } catch (e) {
      setYtIniStatus((e as Error).message);
    } finally {
      setYtIniLoading(false);
    }
  }, [currentProc, fetchJson]);

  useEffect(() => {
    if (!currentProc) return;
    void loadYoutubeIni();
  }, [currentProc, loadYoutubeIni]);

  const updateActive = (patch: Partial<YoutubeProChannel>) => {
    if (!active) return;
    persistChannels(channels.map((c) => (c.id === active.id ? { ...c, ...patch } : c)));
  };

  const saveYoutubeIniToServer = async (content: string) => {
    if (!currentProc) {
      setYtIniStatus(t("请选择进程", "Pick a process"));
      return;
    }
    setYtIniLoading(true);
    setYtIniStatus(null);
    try {
      const params = new URLSearchParams({ process: currentProc });
      await fetchJson(`/save_config?${params}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ content }),
      });
      setYoutubeIniText(content);
      setYtIniStatus(t("youtube.ini 已保存", "youtube.ini saved"));
    } catch (e) {
      setYtIniStatus((e as Error).message);
    } finally {
      setYtIniLoading(false);
    }
  };

  const applyFieldsAndSave = async () => {
    const body = buildYoutubeIniFromFields(ytFields);
    await saveYoutubeIniToServer(body);
  };

  const syncFieldsFromText = () => {
    setYtFields(parseYoutubeIniFields(youtubeIniText));
    setYtIniStatus(t("已从下方原文同步到表单", "Synced from raw"));
  };

  const keySuffixUi = useMemo(() => {
    if (mode === "single") return parseYoutubeStreamKeySuffix(`key = ${ytFields.key}`);
    const k = active?.streamKey ?? "";
    return parseYoutubeStreamKeySuffix(`key = ${k}`);
  }, [mode, ytFields.key, active?.streamKey]);

  const saveProUrlAndServer = async () => {
    if (!active) return;
    updateActive({ urlLines: proUrlDraft });
    setUrlConfig(proUrlDraft);
    try {
      await Promise.resolve(onSaveUrlConfig(proUrlDraft));
      urlListDirtyRef.current = false;
    } catch {
      /* parent 已 toast */
    }
  };

  const saveSingleUrlAndClearDirty = async () => {
    try {
      await Promise.resolve(onSaveUrlConfig());
      urlListDirtyRef.current = false;
    } catch {
      /* parent 已 toast */
    }
  };

  const pushProStreamKeyToServer = async () => {
    if (!active) return;
    const base = parseYoutubeIniFields(youtubeIniText || buildYoutubeIniFromFields(ytFields));
    const f: YoutubeIniFields = {
      key: (active.streamKey ?? "").trim(),
      rtmps: base.rtmps,
      bitrate: base.bitrate,
      fastAudio: base.fastAudio,
    };
    const body = buildYoutubeIniFromFields(f);
    await saveYoutubeIniToServer(body);
    updateActive({ streamKey: f.key });
  };

  const lock = busy || ytIniLoading || urlReloading;

  const urlToolbar = (
    <div className="mt-2 flex flex-wrap items-center gap-4 text-xs text-zinc-400">
      <label className="flex cursor-pointer items-center gap-2">
        <input
          type="checkbox"
          className="rounded border-white/20 bg-black/40"
          checked={urlAutoRefresh}
          onChange={(e) => setUrlAutoRefresh(e.target.checked)}
        />
        {t("每 8 秒自动从服务器刷新", "Auto-refresh from server every 8s")}
      </label>
      <button
        type="button"
        disabled={lock}
        onClick={() => void reloadUrlManual()}
        className="rounded-lg border border-white/10 px-3 py-1.5 text-zinc-200 hover:bg-white/5"
      >
        {t("手动重新读取", "Reload from server")}
      </button>
    </div>
  );

  return (
    <div className="mx-auto max-w-4xl space-y-6">
      <div className="rounded-2xl border border-violet-500/25 bg-gradient-to-br from-violet-500/[0.12] via-zinc-950/80 to-cyan-500/5 p-6 shadow-xl shadow-violet-900/10">
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div className="flex items-center gap-3">
            <div className="flex h-11 w-11 items-center justify-center rounded-xl bg-gradient-to-br from-red-500/30 to-violet-600/30 ring-1 ring-white/10">
              <MonitorPlay className="h-5 w-5 text-red-200" />
            </div>
            <div>
              <h2 className="text-lg font-semibold tracking-tight text-white">
                {t("YouTube 无人直播", "YouTube unmanned live")}
              </h2>
              <p className="mt-0.5 text-xs text-zinc-500">
                {t(
                  "单路一条流；多路时每条线路一把密钥、一个进程名，填好密钥和直播地址后保存，再点「开始」。无需 Google 登录。",
                  "Single lane or multi-lane: one key and one process per lane — fill key & URLs, save, then Start. No Google login.",
                )}
              </p>
            </div>
          </div>
          <div className="flex rounded-xl border border-white/10 bg-black/30 p-1">
            <button
              type="button"
              onClick={() => setModePersist("single")}
              className={`rounded-lg px-4 py-2 text-xs font-medium transition ${
                mode === "single" ? "bg-violet-500/25 text-white" : "text-zinc-500 hover:text-zinc-300"
              }`}
            >
              {t("单频道", "Single")}
            </button>
            <button
              type="button"
              onClick={() => setModePersist("pro")}
              className={`rounded-lg px-4 py-2 text-xs font-medium transition ${
                mode === "pro" ? "bg-violet-500/25 text-white" : "text-zinc-500 hover:text-zinc-300"
              }`}
            >
              {t("多频道 Pro", "Multi Pro")}
            </button>
          </div>
        </div>
      </div>

      <div className="rounded-2xl border border-amber-500/20 bg-zinc-950/60 p-6 ring-1 ring-white/[0.04]">
        <div className="flex items-center gap-2 text-amber-200/90">
          <Radio className="h-4 w-4" />
          <h3 className="text-sm font-semibold text-white">{t("直播开关", "Live control")}</h3>
        </div>

        {mode === "single" ? (
          <>
            <label className="mt-4 block text-xs font-semibold uppercase tracking-wider text-zinc-500">
              {t("转播任务", "Relay task")}
            </label>
            <select
              className="mt-2 w-full rounded-xl border border-white/10 bg-black/40 px-4 py-3 text-sm text-white"
              value={currentProc}
              onChange={(e) => setCurrentProc(e.target.value)}
            >
              {processOptions.map((e) => (
                <option key={e.pm2} value={e.pm2}>
                  {e.label} ({e.pm2})
                </option>
              ))}
            </select>
            <div className="mt-4 grid grid-cols-2 gap-2 sm:grid-cols-3">
              {(
                [
                  ["start", t("开始直播", "Start"), "bg-emerald-500/20 text-emerald-200 ring-emerald-500/30"],
                  ["stop", t("停止直播", "Stop"), "bg-rose-500/15 text-rose-200 ring-rose-500/25"],
                  ["restart", t("重新开始", "Restart"), "bg-amber-500/15 text-amber-200 ring-amber-500/25"],
                ] as const
              ).map(([a, label, cls]) => (
                <button
                  key={a}
                  type="button"
                  disabled={lock}
                  onClick={() => onRunProcess(a)}
                  className={`rounded-xl px-4 py-3 text-sm font-medium ring-1 ${cls}`}
                >
                  {label}
                </button>
              ))}
            </div>
            <p className="mt-3 text-center font-mono text-[11px] text-zinc-600">
              key {t("尾码", "suffix")}: {keySuffixUi || "—"}
            </p>
          </>
        ) : (
          <>
            <p className="mt-3 text-xs text-zinc-500">
              {t("点选一行即可编辑该线路；此处只列出已保存过密钥的线路。", "Pick a row to edit. Only lanes with a saved key are listed.")}
            </p>
            {proLanesWithKey.length === 0 ? (
              <p className="mt-4 rounded-xl border border-white/10 bg-black/30 px-4 py-3 text-sm text-zinc-400">
                {channels.length > 0
                  ? t("请先在下方填写串流密钥并点「保存」。", "Enter a stream key below and tap Save.")
                  : t("请先新增线路。", "Add a lane first.")}
              </p>
            ) : (
              <div className="mt-4 space-y-2">
                {proLanesWithKey.map((c) => {
                  const pm = (c.pm2Name ?? "").trim() || defaultPm2NameForChannel(c.id);
                  const suffix = parseYoutubeStreamKeySuffix(`key = ${c.streamKey ?? ""}`);
                  const sel = activeCh === c.id;
                  return (
                    <div
                      key={c.id}
                      role="button"
                      tabIndex={0}
                      onClick={() => selectProChannel(c)}
                      onKeyDown={(e) => {
                        if (e.key === "Enter" || e.key === " ") {
                          e.preventDefault();
                          selectProChannel(c);
                        }
                      }}
                      className={`rounded-xl border p-3 text-left transition ${
                        sel ? "border-violet-500/45 bg-violet-500/[0.08]" : "border-white/10 bg-black/30 hover:border-white/20"
                      }`}
                    >
                      <div className="flex flex-wrap items-center justify-between gap-3">
                        <div className="min-w-0 flex flex-1 flex-wrap items-center gap-2">
                          <code className="shrink-0 font-mono text-xs text-cyan-300/90">{suffix || "—"}</code>
                          <span className="truncate text-sm text-zinc-200">{c.name}</span>
                        </div>
                        <div className="flex shrink-0 flex-wrap gap-2" onClick={(e) => e.stopPropagation()}>
                          <button
                            type="button"
                            disabled={lock}
                            onClick={() => onRunProcess("start", pm)}
                            className="rounded-lg bg-emerald-500/20 px-3 py-1.5 text-xs font-medium text-emerald-100 ring-1 ring-emerald-500/30 disabled:opacity-30"
                          >
                            {t("开始", "Start")}
                          </button>
                          <button
                            type="button"
                            disabled={lock}
                            onClick={() => onRunProcess("stop", pm)}
                            className="rounded-lg bg-rose-500/15 px-3 py-1.5 text-xs font-medium text-rose-100 ring-1 ring-rose-500/25 disabled:opacity-30"
                          >
                            {t("停止", "Stop")}
                          </button>
                          <button
                            type="button"
                            disabled={lock}
                            onClick={() => onRunProcess("restart", pm)}
                            className="rounded-lg bg-amber-500/15 px-3 py-1.5 text-xs font-medium text-amber-100 ring-1 ring-amber-500/25 disabled:opacity-30"
                          >
                            {t("重新开始", "Restart")}
                          </button>
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
            <p className="mt-3 text-center font-mono text-[11px] text-zinc-600">
              {t("当前线路", "Current lane")}: {active?.name ?? "—"} · key {keySuffixUi || "—"}
            </p>
          </>
        )}
      </div>

      {mode === "single" ? (
        <div className="rounded-2xl border border-white/[0.08] bg-zinc-950/50 p-6">
          <h3 className="text-sm font-semibold text-white">{t("YouTube 相关设置", "YouTube settings")}</h3>
          <p className="mt-1 text-xs text-zinc-500">
            {t("串流参数写进 youtube.ini，无需 Google 登录。", "Stream settings go to youtube.ini — no Google login.")}
          </p>

          <div className="mt-4 space-y-3">
            <label className="block text-xs text-zinc-400">{t("串流密钥", "Stream key")}</label>
            <input
              className="w-full rounded-xl border border-white/10 bg-black/40 px-4 py-3 text-sm font-mono text-zinc-200"
              spellCheck={false}
              autoComplete="off"
              value={ytFields.key}
              onChange={(e) => setYtFields((f) => ({ ...f, key: e.target.value }))}
              placeholder="xxxx-xxxx-xxxx-xxxx-xxxx"
            />
            <div className="grid gap-3 sm:grid-cols-3">
              <label className="flex flex-col gap-1 text-xs text-zinc-400">
                RTMPS
                <select
                  className="rounded-lg border border-white/10 bg-black/40 px-3 py-2 text-sm text-white"
                  value={ytFields.rtmps ? "1" : "0"}
                  onChange={(e) => setYtFields((f) => ({ ...f, rtmps: e.target.value === "1" }))}
                >
                  <option value="1">{t("是（默认）", "Yes")}</option>
                  <option value="0">{t("否 → RTMP", "No")}</option>
                </select>
              </label>
              <label className="flex flex-col gap-1 text-xs text-zinc-400">
                {t("比特率 kbps", "Bitrate kbps")}
                <input
                  className="rounded-lg border border-white/10 bg-black/40 px-3 py-2 font-mono text-sm"
                  value={ytFields.bitrate}
                  onChange={(e) => setYtFields((f) => ({ ...f, bitrate: e.target.value }))}
                  placeholder="4000"
                />
              </label>
              <label className="flex cursor-pointer items-center gap-2 pt-6 text-xs text-zinc-300">
                <input
                  type="checkbox"
                  className="rounded border-white/20 bg-black/40"
                  checked={ytFields.fastAudio}
                  onChange={(e) => setYtFields((f) => ({ ...f, fastAudio: e.target.checked }))}
                />
                fast_audio（{t("轻量音频", "lighter audio")}）
              </label>
            </div>
          </div>

          <div className="mt-4 flex flex-wrap gap-2">
            <button
              type="button"
              disabled={lock}
              onClick={() => void loadYoutubeIni()}
              className="inline-flex items-center gap-2 rounded-xl border border-white/10 bg-white/[0.05] px-4 py-2 text-sm text-zinc-200"
            >
              <RefreshCw className={`h-3.5 w-3.5 ${ytIniLoading ? "animate-spin" : ""}`} />
              {t("重新读取", "Reload")}
            </button>
            <button
              type="button"
              disabled={lock}
              onClick={() => void applyFieldsAndSave()}
              className="inline-flex items-center gap-2 rounded-xl bg-violet-500/25 px-4 py-2 text-sm font-medium text-violet-100 ring-1 ring-violet-500/35"
            >
              {ytIniLoading ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
              {t("保存 youtube.ini", "Save youtube.ini")}
            </button>
            <button
              type="button"
              disabled={lock}
              onClick={syncFieldsFromText}
              className="rounded-xl border border-white/10 px-4 py-2 text-sm text-zinc-400"
            >
              {t("从原文同步表单", "Parse raw")}
            </button>
          </div>

          <details className="mt-4 rounded-xl border border-white/5 bg-black/20 p-3">
            <summary className="cursor-pointer text-xs text-zinc-500">{t("高级：youtube.ini 原文", "Raw youtube.ini")}</summary>
            <textarea
              className="mt-2 h-36 w-full resize-y rounded-lg border border-white/10 bg-black/50 p-3 font-mono text-[11px] text-zinc-400"
              value={youtubeIniText}
              onChange={(e) => setYoutubeIniText(e.target.value)}
              spellCheck={false}
            />
            <button
              type="button"
              disabled={lock}
              className="mt-2 rounded-lg bg-cyan-500/15 px-3 py-1.5 text-xs text-cyan-200"
              onClick={() => void saveYoutubeIniToServer(youtubeIniText)}
            >
              {t("保存原文", "Save raw")}
            </button>
          </details>

          {ytIniStatus ? <p className="mt-2 font-mono text-xs text-zinc-500">{ytIniStatus}</p> : null}
        </div>
      ) : (
        <div className="space-y-6">
          <div className="rounded-2xl border border-white/[0.08] bg-zinc-950/50 p-6">
            <div className="flex flex-wrap items-center justify-between gap-2">
              <h3 className="text-sm font-semibold text-white">{t("当前线路", "Current lane")}</h3>
              <button
                type="button"
                disabled={lock}
                className="inline-flex items-center gap-1 rounded-lg bg-violet-500/20 px-3 py-1.5 text-xs text-violet-100 ring-1 ring-violet-500/30"
                onClick={() => {
                  const id = newChannelId();
                  const nc: YoutubeProChannel = {
                    id,
                    name: `${t("线路", "Ch")} ${channels.length + 1}`,
                    streamKey: "",
                    urlLines: "",
                    pm2Name: defaultPm2NameForChannel(id),
                    notes: "",
                  };
                  persistChannels([...channels, nc]);
                  setActiveCh(id);
                  setProUrlDraft("");
                }}
              >
                <Plus className="h-3.5 w-3.5" />
                {t("新增线路", "Add lane")}
              </button>
            </div>
            <label className="mt-3 block text-xs font-medium text-zinc-500">{t("切换线路", "Switch lane")}</label>
            <select
              className="mt-1 w-full rounded-xl border border-white/10 bg-black/40 px-3 py-2.5 text-sm text-white"
              value={activeCh}
              onChange={(e) => {
                const c = channels.find((x) => x.id === e.target.value);
                if (c) selectProChannel(c);
              }}
            >
              {channels.map((c) => (
                <option key={c.id} value={c.id}>
                  {c.name}
                </option>
              ))}
            </select>

            {active ? (
              <div className="mt-4 space-y-3 border-t border-white/5 pt-4">
                <input
                  className="w-full rounded-xl border border-white/10 bg-black/40 px-3 py-2 text-sm"
                  value={active.name}
                  onChange={(e) => updateActive({ name: e.target.value })}
                  placeholder={t("线路名称", "Lane name")}
                />
                <label className="block text-xs text-zinc-500">{t("串流密钥", "Stream key")}</label>
                <input
                  className="w-full rounded-xl border border-white/10 bg-black/40 px-3 py-2 font-mono text-sm"
                  spellCheck={false}
                  value={active.streamKey ?? ""}
                  onChange={(e) => updateActive({ streamKey: e.target.value })}
                  placeholder="xxxx-xxxx… / rtmp(s)://…"
                />
                <div className="flex flex-wrap gap-2">
                  <button
                    type="button"
                    disabled={lock}
                    onClick={() => void pushProStreamKeyToServer()}
                    className="rounded-xl bg-violet-500/25 px-4 py-2 text-sm font-medium text-violet-100 ring-1 ring-violet-500/35"
                  >
                    {t("保存", "Save")}
                  </button>
                </div>
                <details className="rounded-xl border border-white/5 bg-black/20 p-3">
                  <summary className="cursor-pointer text-xs text-zinc-500">{t("高级：进程名", "Advanced: process name")}</summary>
                  <input
                    className="mt-2 w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2 font-mono text-xs"
                    value={active.pm2Name ?? defaultPm2NameForChannel(active.id)}
                    onChange={(e) => updateActive({ pm2Name: e.target.value })}
                    spellCheck={false}
                    placeholder="youtube2__…"
                  />
                </details>
                <textarea
                  className="h-16 w-full resize-y rounded-xl border border-white/10 bg-black/40 p-3 text-xs text-zinc-300"
                  value={active.notes ?? ""}
                  onChange={(e) => updateActive({ notes: e.target.value })}
                  placeholder={t("备注（可选）", "Notes (optional)")}
                />
                <button
                  type="button"
                  disabled={lock || channels.length < 2}
                  className="inline-flex items-center gap-1 text-xs text-rose-300 hover:text-rose-200 disabled:opacity-30"
                  onClick={() => {
                    const next = channels.filter((c) => c.id !== active.id);
                    persistChannels(next);
                    setActiveCh(next[0]?.id || "");
                  }}
                >
                  <Trash2 className="h-3.5 w-3.5" />
                  {t("删除此线路", "Delete lane")}
                </button>
              </div>
            ) : null}
          </div>

          <div className="rounded-2xl border border-white/[0.08] bg-zinc-950/50 p-6">
            <h3 className="text-sm font-semibold text-white">{t("当前线路 · 直播地址列表", "URL list (this lane)")}</h3>
            {urlToolbar}
            {urlFetchNote ? <p className="mt-2 text-xs text-zinc-500">{urlFetchNote}</p> : null}
            <textarea
              className="mt-4 min-h-[160px] w-full resize-y rounded-xl border border-white/10 bg-black/50 p-4 font-mono text-xs text-zinc-300"
              value={proUrlDraft}
              onChange={(e) => {
                urlListDirtyRef.current = true;
                setProUrlDraft(e.target.value);
              }}
              spellCheck={false}
              placeholder="https://live.douyin.com/..."
            />
            <div className="mt-3 flex flex-wrap gap-2">
              <button
                type="button"
                disabled={lock}
                onClick={() => {
                  urlListDirtyRef.current = true;
                  setProUrlDraft(urlConfig);
                  setYtIniStatus(t("已从服务器草稿填充", "Loaded from server draft"));
                }}
                className="rounded-xl border border-white/10 px-4 py-2 text-sm text-zinc-300"
              >
                {t("填入全局地址", "Use global URLs")}
              </button>
              <button
                type="button"
                disabled={lock}
                onClick={() => void saveProUrlAndServer()}
                className="rounded-xl bg-cyan-500/20 px-4 py-2 text-sm text-cyan-100 ring-1 ring-cyan-500/30"
              >
                {t("保存地址", "Save URLs")}
              </button>
            </div>
          </div>
        </div>
      )}

      <div className="rounded-2xl border border-white/[0.08] bg-zinc-950/50 p-6">
        <h3 className="text-sm font-semibold text-white">{t("直播地址列表 · URL_config.ini", "URL_config.ini")}</h3>
        <p className="mt-1 text-xs text-zinc-500">
          {mode === "pro"
            ? t("Pro 模式在上方「当前线路」里编辑本线路地址。", "Pro: edit this lane’s URLs in the lane panel above.")
            : t("一行一个地址；可自动刷新或手动重新读取。", "One URL per line; auto-refresh or reload.")}
        </p>
        {mode === "single" ? (
          <>
            {urlToolbar}
            {urlFetchNote ? <p className="mt-2 text-xs text-zinc-500">{urlFetchNote}</p> : null}
            <textarea
              className="mt-4 min-h-[200px] w-full resize-y rounded-xl border border-white/10 bg-black/50 p-4 font-mono text-xs text-zinc-300"
              value={urlConfig}
              onChange={(e) => {
                urlListDirtyRef.current = true;
                setUrlConfig(e.target.value);
              }}
              spellCheck={false}
            />
            <button
              type="button"
              disabled={lock}
              onClick={() => void saveSingleUrlAndClearDirty()}
              className="mt-3 rounded-xl bg-cyan-500/20 px-4 py-2 text-sm text-cyan-100 ring-1 ring-cyan-500/30"
            >
              {t("保存 URL 配置", "Save URL config")}
            </button>
          </>
        ) : (
          <p className="mt-4 text-xs text-zinc-600">{t("Pro 模式：请使用「当前线路」中的地址列表。", "Use lane URL list in Pro mode.")}</p>
        )}
      </div>

      <LiveProcessLiveLogCard
        t={t}
        currentProc={currentProc}
        fetchJson={fetchJson}
        urlListText={mode === "single" ? urlConfig : proUrlDraft}
        keySuffixUi={keySuffixUi}
        showKeyRow
      />
    </div>
  );
}
