import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  getHostApps, addHostApp, editHostApp, deleteHostApp,
  type HostApp, type SaveHostAppInput,
} from "../../lib/commands";

const DEPLOY_TYPES = [
  { value: "systemd", label: "systemd 服务", color: "bg-green-100 text-green-700 border-green-200" },
  { value: "pm2", label: "PM2", color: "bg-blue-100 text-blue-700 border-blue-200" },
  { value: "supervisor", label: "Supervisor", color: "bg-purple-100 text-purple-700 border-purple-200" },
  { value: "screen", label: "Screen/Tmux", color: "bg-cyan-100 text-cyan-700 border-cyan-200" },
  { value: "manual", label: "手动启动", color: "bg-gray-100 text-gray-600 border-gray-200" },
];

function getTypeStyle(t: string) {
  return DEPLOY_TYPES.find((d) => d.value === t)?.color ?? DEPLOY_TYPES[DEPLOY_TYPES.length - 1].color;
}
function getTypeLabel(t: string) {
  return DEPLOY_TYPES.find((d) => d.value === t)?.label ?? t;
}

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 CmdRow({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex items-center gap-2 px-3 py-1.5 bg-gray-900 rounded-md group">
      <span className="text-[10px] text-gray-500 w-10 shrink-0 text-right">{label}</span>
      <span className="text-[11px] text-green-400 font-mono flex-1 truncate">$ {value}</span>
      <span className="opacity-0 group-hover:opacity-100 transition-opacity">
        <CopyBtn value={value} />
      </span>
    </div>
  );
}

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

function HostAppModal({ initial, onSave, onClose, saving }: {
  initial?: HostApp;
  onSave: (input: SaveHostAppInput) => void;
  onClose: () => void;
  saving: boolean;
}) {
  const [name, setName] = useState(initial?.name ?? "");
  const [deployType, setDeployType] = useState(initial?.deploy_type ?? "systemd");
  const [serviceName, setServiceName] = useState(initial?.service_name ?? "");
  const [binaryPath, setBinaryPath] = useState(initial?.binary_path ?? "");
  const [configPath, setConfigPath] = useState(initial?.config_path ?? "");
  const [logPath, setLogPath] = useState(initial?.log_path ?? "");
  const [port, setPort] = useState(initial?.port ?? "");
  const [startCmd, setStartCmd] = useState(initial?.start_cmd ?? "");
  const [stopCmd, setStopCmd] = useState(initial?.stop_cmd ?? "");
  const [restartCmd, setRestartCmd] = useState(initial?.restart_cmd ?? "");
  const [statusCmd, setStatusCmd] = useState(initial?.status_cmd ?? "");
  const [notes, setNotes] = useState(initial?.notes ?? "");

  // systemd 时自动填充命令
  const autoFillSystemd = (svc: string) => {
    setServiceName(svc);
    if (deployType === "systemd" && svc.trim()) {
      const s = svc.trim();
      if (!startCmd) setStartCmd(`systemctl start ${s}`);
      if (!stopCmd) setStopCmd(`systemctl stop ${s}`);
      if (!restartCmd) setRestartCmd(`systemctl restart ${s}`);
      if (!statusCmd) setStatusCmd(`systemctl status ${s}`);
    }
  };

  const handleSubmit = () => {
    if (!name.trim()) return;
    onSave({
      name: name.trim(),
      deploy_type: deployType,
      service_name: serviceName.trim() || undefined,
      binary_path: binaryPath.trim() || undefined,
      config_path: configPath.trim() || undefined,
      log_path: logPath.trim() || undefined,
      port: port.trim() || undefined,
      start_cmd: startCmd.trim() || undefined,
      stop_cmd: stopCmd.trim() || undefined,
      restart_cmd: restartCmd.trim() || undefined,
      status_cmd: statusCmd.trim() || undefined,
      notes: notes.trim() || undefined,
    });
  };

  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-[560px] max-h-[85vh] 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 ? "编辑宿主机应用" : "添加宿主机应用"}</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-3">
          <div className="grid grid-cols-[72px_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="例: Nginx"
              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={deployType} onChange={(e) => setDeployType(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-40">
              {DEPLOY_TYPES.map((d) => <option key={d.value} value={d.value}>{d.label}</option>)}
            </select>
            <label className="text-[11px] text-gray-400 text-right">服务名</label>
            <input value={serviceName} onChange={(e) => autoFillSystemd(e.target.value)}
              placeholder={deployType === "systemd" ? "例: nginx" : "例: app-name"}
              className="text-xs px-2.5 py-2 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono" />
            <label className="text-[11px] text-gray-400 text-right">端口</label>
            <input value={port} onChange={(e) => setPort(e.target.value)} placeholder="例: 8080"
              className="text-xs px-2.5 py-2 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono w-28" />
            <label className="text-[11px] text-gray-400 text-right">程序路径</label>
            <input value={binaryPath} onChange={(e) => setBinaryPath(e.target.value)} placeholder="/usr/bin/..."
              className="text-xs px-2.5 py-2 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono" />
            <label className="text-[11px] text-gray-400 text-right">配置路径</label>
            <input value={configPath} onChange={(e) => setConfigPath(e.target.value)} placeholder="/etc/..."
              className="text-xs px-2.5 py-2 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono" />
            <label className="text-[11px] text-gray-400 text-right">日志路径</label>
            <input value={logPath} onChange={(e) => setLogPath(e.target.value)} placeholder="/var/log/..."
              className="text-xs px-2.5 py-2 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono" />
          </div>

          {/* 管理命令 */}
          <div>
            <span className="text-[11px] text-gray-500 font-medium">管理命令</span>
            <div className="grid grid-cols-[72px_1fr] gap-x-3 gap-y-2 items-center mt-1.5">
              <label className="text-[11px] text-gray-400 text-right">启动</label>
              <input value={startCmd} onChange={(e) => setStartCmd(e.target.value)} placeholder="systemctl start ..."
                className="text-xs px-2.5 py-1.5 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono" />
              <label className="text-[11px] text-gray-400 text-right">停止</label>
              <input value={stopCmd} onChange={(e) => setStopCmd(e.target.value)} placeholder="systemctl stop ..."
                className="text-xs px-2.5 py-1.5 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono" />
              <label className="text-[11px] text-gray-400 text-right">重启</label>
              <input value={restartCmd} onChange={(e) => setRestartCmd(e.target.value)} placeholder="systemctl restart ..."
                className="text-xs px-2.5 py-1.5 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono" />
              <label className="text-[11px] text-gray-400 text-right">状态</label>
              <input value={statusCmd} onChange={(e) => setStatusCmd(e.target.value)} placeholder="systemctl status ..."
                className="text-xs px-2.5 py-1.5 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300 font-mono" />
            </div>
          </div>

          <div className="grid grid-cols-[72px_1fr] gap-x-3 items-center">
            <label className="text-[11px] text-gray-400 text-right">备注</label>
            <input value={notes} onChange={(e) => setNotes(e.target.value)} placeholder="用途说明"
              className="text-xs px-2.5 py-2 rounded border border-gray-200 bg-gray-50 focus:outline-none focus:border-blue-300" />
          </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 HostAppCard({ app, onEdit, onDelete }: {
  app: HostApp;
  onEdit: () => void;
  onDelete: () => void;
}) {
  const [confirmDelete, setConfirmDelete] = useState(false);

  const infos = [
    app.service_name && { label: "服务名", value: app.service_name },
    app.port && { label: "端口", value: app.port },
    app.binary_path && { label: "程序", value: app.binary_path },
    app.config_path && { label: "配置", value: app.config_path },
    app.log_path && { label: "日志", value: app.log_path },
  ].filter(Boolean) as { label: string; value: string }[];

  const cmds = [
    app.start_cmd && { label: "启动", value: app.start_cmd },
    app.stop_cmd && { label: "停止", value: app.stop_cmd },
    app.restart_cmd && { label: "重启", value: app.restart_cmd },
    app.status_cmd && { label: "状态", value: app.status_cmd },
  ].filter(Boolean) as { label: string; value: string }[];

  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 ${getTypeStyle(app.deploy_type)}`}>
          {getTypeLabel(app.deploy_type)}
        </span>
        <span className="text-xs font-semibold text-gray-800 flex-1 min-w-0 truncate">{app.name}</span>
        {app.port && <span className="text-[11px] font-mono text-gray-400">:{app.port}</span>}
        {app.notes && <span className="text-[11px] text-gray-400">{app.notes}</span>}
        <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 font-medium transition-colors">确认</button>
            <button onClick={() => setConfirmDelete(false)}
              className="text-[11px] text-gray-400 transition-colors">取消</button>
          </div>
        )}
      </div>

      <div className="px-3 py-2 space-y-2">
        {/* 基础信息 */}
        {infos.length > 0 && (
          <div className="space-y-0.5">
            {infos.map((info, idx) => (
              <div key={idx} className="flex items-center gap-2 py-0.5 group">
                <span className="text-[11px] text-gray-400 w-10 shrink-0 text-right">{info.label}</span>
                <span className="text-xs font-mono text-gray-700 flex-1 min-w-0 truncate">{info.value}</span>
                <span className="opacity-0 group-hover:opacity-100 transition-opacity">
                  <CopyBtn value={info.value} />
                </span>
              </div>
            ))}
          </div>
        )}

        {/* 管理命令 */}
        {cmds.length > 0 && (
          <div className="space-y-1">
            {cmds.map((cmd, idx) => (
              <CmdRow key={idx} label={cmd.label} value={cmd.value} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// ── 主面板 ────────────────────────────────────────────────────────────────────

export function HostAppsPanel({ serverId }: { serverId: string }) {
  const qc = useQueryClient();
  const [showModal, setShowModal] = useState(false);
  const [editingApp, setEditingApp] = useState<HostApp | null>(null);

  const { data: apps = [] } = useQuery({
    queryKey: ["host-apps", serverId],
    queryFn: () => getHostApps(serverId),
  });

  const addMut = useMutation({
    mutationFn: (input: SaveHostAppInput) => addHostApp(serverId, input),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["host-apps", serverId] }); setShowModal(false); },
  });

  const editMut = useMutation({
    mutationFn: ({ id, input }: { id: string; input: SaveHostAppInput }) => editHostApp(id, input),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["host-apps", serverId] }); setEditingApp(null); },
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteHostApp(id),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["host-apps", serverId] }),
  });

  return (
    <div>
      <div className="flex items-center justify-between mb-2">
        <h4 className="text-[11px] font-semibold text-gray-400 uppercase tracking-wider">宿主机应用</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">
        {apps.map((app) => (
          <HostAppCard
            key={app.id}
            app={app}
            onEdit={() => setEditingApp(app)}
            onDelete={() => deleteMut.mutate(app.id)}
          />
        ))}

        {apps.length === 0 && (
          <p className="text-[11px] text-gray-300 text-center py-3">
            暂无宿主机应用，点击「+ 添加」记录 systemd 服务、PM2 进程等
          </p>
        )}
      </div>

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

      {editingApp && (
        <HostAppModal
          initial={editingApp}
          onSave={(input) => editMut.mutate({ id: editingApp.id, input })}
          onClose={() => setEditingApp(null)}
          saving={editMut.isPending}
        />
      )}
    </div>
  );
}
