import { useEffect, useMemo, useState } from 'react'
import { CheckCircle2, Clock, Command, Copy, Play, RefreshCw, Server, Terminal, XCircle } from 'lucide-react'
import Modal from './Modal'
import { executeBatchCommand } from '../services/connections'
import type { BatchCommandResult, Connection, ConnectionReachabilityStatus, ConnectionStatusItem } from '../types'

const reachabilityCopy: Record<ConnectionReachabilityStatus, { dot: string; label: string; text: string }> = {
  unknown: { dot: 'bg-slate-500', label: '未检测', text: 'text-slate-500' },
  checking: { dot: 'bg-amber-400', label: '检测中', text: 'text-amber-300' },
  online: { dot: 'bg-emerald-500 shadow-[0_0_4px_rgba(16,185,129,0.5)]', label: '在线', text: 'text-emerald-500/80' },
  offline: { dot: 'bg-slate-500', label: '离线', text: 'text-slate-500' },
}

export default function BatchCommandModal({
  open,
  connections,
  connectionStatuses,
  connectionStatusDetails,
  onRefreshStatuses,
  statusError,
  statusLoading,
  onClose,
}: {
  open: boolean
  connections: Connection[]
  connectionStatuses: Record<number, ConnectionReachabilityStatus>
  connectionStatusDetails: Record<number, ConnectionStatusItem>
  onRefreshStatuses: () => Promise<void>
  statusError: string | null
  statusLoading: boolean
  onClose: () => void
}) {
  const [selectedIds, setSelectedIds] = useState<number[]>(() => connections.slice(0, 2).map((item) => item.id))
  const [command, setCommand] = useState('df -h\nfree -m')
  const [running, setRunning] = useState(false)
  const [results, setResults] = useState<BatchCommandResult[]>([])
  const [error, setError] = useState<string | null>(null)

  const summary = useMemo(
    () => ({
      total: selectedIds.length,
      success: results.filter((item) => item.success).length,
      failure: results.filter((item) => !item.success).length,
    }),
    [results, selectedIds.length],
  )

  const onlineIds = useMemo(
    () => connections.filter((item) => connectionStatuses[item.id] === 'online').map((item) => item.id),
    [connectionStatuses, connections],
  )

  const offlineCount = useMemo(
    () => connections.filter((item) => connectionStatuses[item.id] === 'offline').length,
    [connectionStatuses, connections],
  )

  useEffect(() => {
    setSelectedIds((prev) =>
      prev.filter(
        (id) =>
          connections.some((item) => item.id === id) &&
          connectionStatuses[id] === 'online',
      ),
    )
  }, [connectionStatuses, connections])

  if (!open) return null

  async function handleRun() {
    const runnableIds = selectedIds.filter((id) => connectionStatuses[id] === 'online')
    if (!runnableIds.length || !command.trim()) return
    setRunning(true)
    setError(null)
    try {
      const response = await executeBatchCommand(runnableIds, command)
      setResults(response.data.results)
    } catch (err) {
      const message =
        (err as { response?: { data?: { message?: string; error?: string } } }).response?.data?.message || '批量执行失败'
      setError(message)
    } finally {
      setRunning(false)
    }
  }

  return (
    <Modal title="批量执行命令" onClose={onClose} maxWidth="max-w-6xl">
      <div className="flex h-[70vh] overflow-hidden rounded-2xl border border-slate-800 bg-[#0d1117]">
        <div className="flex w-72 shrink-0 flex-col border-r border-slate-800 bg-slate-900/70">
          <div className="flex items-center justify-between border-b border-slate-800 px-4 py-3 text-sm text-slate-300">
            <span>目标主机 ({selectedIds.length})</span>
            <div className="flex gap-3 text-xs">
              <button className="text-blue-400 disabled:text-slate-600" disabled={statusLoading} onClick={() => setSelectedIds(onlineIds)}>
                全选
              </button>
              <button className="text-slate-400" onClick={() => setSelectedIds([])}>
                清空
              </button>
              <button
                className="flex items-center gap-1 text-slate-400 transition hover:text-slate-200 disabled:text-slate-600"
                disabled={statusLoading || connections.length === 0}
                onClick={() => {
                  void onRefreshStatuses().catch(() => undefined)
                }}
              >
                <RefreshCw size={12} className={statusLoading ? 'animate-spin' : ''} />
                刷新
              </button>
            </div>
          </div>
          <div className="border-b border-slate-800 px-4 py-2 text-xs text-slate-500">
            在线 {onlineIds.length} / 离线 {offlineCount} / 总数 {connections.length}
          </div>
          <div className="flex-1 space-y-1 overflow-auto p-2">
            {connections.map((connection) => {
              const checked = selectedIds.includes(connection.id)
              const reachability = connectionStatuses[connection.id] ?? 'unknown'
              const reachabilityMeta = reachabilityCopy[reachability]
              const statusDetail = connectionStatusDetails[connection.id]
              const disabled = reachability !== 'online'
              return (
                <label
                  key={connection.id}
                  title={statusDetail?.message || reachabilityMeta.label}
                  className={`flex items-center gap-2 rounded-xl px-3 py-2 transition ${
                    disabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer hover:bg-slate-800'
                  }`}
                >
                  <input
                    type="checkbox"
                    disabled={disabled}
                    checked={checked}
                    onChange={() =>
                      setSelectedIds((prev) =>
                        checked ? prev.filter((item) => item !== connection.id) : [...prev, connection.id],
                      )
                    }
                  />
                  <div className="relative shrink-0">
                    <Server size={14} className={checked && !disabled ? 'text-blue-400' : 'text-slate-500'} />
                    <span className={`absolute -bottom-0.5 -right-0.5 h-2 w-2 rounded-full border border-slate-900 ${reachabilityMeta.dot}`} />
                  </div>
                  <div className="min-w-0">
                    <div className="truncate text-sm text-slate-300">{connection.name}</div>
                    <div className={`text-[10px] ${reachabilityMeta.text}`}>{reachabilityMeta.label}</div>
                  </div>
                </label>
              )
            })}
          </div>
        </div>

        <div className="flex flex-1 flex-col">
          <div className="border-b border-slate-800 bg-slate-900 px-4 py-4">
            <div className="flex items-end gap-4">
              <div className="flex-1 space-y-2">
                <label className="flex items-center gap-2 text-sm text-slate-300">
                  <Terminal size={14} className="text-emerald-400" />
                  批量执行脚本
                </label>
                <textarea
                  rows={5}
                  className="w-full resize-none rounded-2xl border border-slate-700 bg-black px-4 py-3 font-mono text-sm text-emerald-300 outline-none focus:border-blue-500"
                  value={command}
                  onChange={(event) => setCommand(event.target.value)}
                />
              </div>
              <button
                className="flex h-[46px] items-center gap-2 rounded-xl bg-blue-600 px-6 text-white transition hover:bg-blue-500 disabled:opacity-60"
                disabled={running || statusLoading || selectedIds.filter((id) => connectionStatuses[id] === 'online').length === 0}
                onClick={() => void handleRun()}
              >
                {running ? <RefreshCw size={16} className="animate-spin" /> : <Play size={16} fill="currentColor" />}
                {running ? '执行中...' : '开始执行'}
              </button>
            </div>
          </div>

          <div className="flex gap-6 border-b border-slate-800 bg-slate-800/60 px-4 py-2 text-sm">
            <span className="text-slate-300">总数: {summary.total}</span>
            <span className="font-medium text-emerald-400">成功: {summary.success}</span>
            <span className="font-medium text-red-400">失败: {summary.failure}</span>
          </div>

          <div className="flex-1 space-y-4 overflow-auto p-4">
            {statusError ? <div className="rounded-xl border border-amber-500/20 bg-amber-500/10 px-4 py-3 text-sm text-amber-200">{statusError}</div> : null}
            {error ? <div className="rounded-xl border border-red-500/20 bg-red-500/10 px-4 py-3 text-sm text-red-300">{error}</div> : null}
            {!results.length && !error ? (
              <div className="flex h-full flex-col items-center justify-center text-slate-500">
                <Command size={48} className="mb-3 text-slate-700" />
                <p>{statusLoading ? '正在检测主机状态...' : '请在上方输入命令并点击执行'}</p>
              </div>
            ) : null}
            {results.map((result) => (
              <div key={result.connectionId} className="overflow-hidden rounded-2xl border border-slate-700 bg-slate-900">
                <div className="flex items-center justify-between border-b border-slate-800 bg-slate-800/80 px-4 py-3">
                  <div className="flex items-center gap-3">
                    {result.success ? <CheckCircle2 size={16} className="text-emerald-500" /> : <XCircle size={16} className="text-red-500" />}
                    <span className="text-sm font-medium text-slate-100">{result.connectionName}</span>
                  </div>
                  <div className="flex items-center gap-4 text-xs text-slate-500">
                    <span className="flex items-center gap-1">
                      <Clock size={12} />
                      {result.durationMs}ms
                    </span>
                    <button
                      className="flex items-center gap-1 transition hover:text-slate-300"
                      onClick={() => navigator.clipboard.writeText(result.output || result.error || '')}
                    >
                      <Copy size={12} />
                      复制输出
                    </button>
                  </div>
                </div>
                <pre className={`overflow-auto bg-black p-4 text-xs leading-relaxed ${result.success ? 'text-slate-300' : 'text-red-400'}`}>
                  {result.output || result.error || ''}
                </pre>
              </div>
            ))}
          </div>
        </div>
      </div>
    </Modal>
  )
}
