import React, { useState, useEffect, useCallback, useRef } from 'react'
import { Monitor, GitBranch, Settings, Plus, Trash2, GripVertical, Folder, Code, Sparkles } from 'lucide-react'
import { ConfigDialog } from './components/ConfigDialog'
import { DeleteConfirmDialog } from '@/components/dialogs/DeleteConfirmDialog'
import type { DeviceInfo, RemoteConfig, RemoteDevice } from './types'
import { useTabContentContext, useScreenshot } from '@/stores'
import { getRemoteConfig, saveRemoteConfig, getDeviceData } from './api'
import type { FileItem } from '@/lib/api'

const defaultConfig: RemoteConfig = {
  devices: [],
}

const createRemoteDesktopFileItem = (url: string, title: string, deviceName?: string): FileItem => {
  const id = deviceName ? `remote-${deviceName}` : 'remote-desktop'
  return {
    name: title,
    path: `remote-desktop://${id}?url=${encodeURIComponent(url)}&device=${encodeURIComponent(deviceName || '')}`,
    type: 'file' as const,
    size: 0,
    modified: new Date().toISOString(),
  }
}

const createRemoteGitFileItem = (url: string, title: string, deviceName?: string): FileItem => {
  const id = deviceName ? `remote-git-${deviceName}` : 'remote-git'
  return {
    name: title,
    path: `remote-git://${id}?url=${encodeURIComponent(url)}&device=${encodeURIComponent(deviceName || '')}`,
    type: 'file' as const,
    size: 0,
    modified: new Date().toISOString(),
  }
}

const createEmptyDevice = (): RemoteDevice => ({
  id: Date.now().toString(),
  deviceName: '',
  serverHost: '',
  desktopPort: 3000,
  gitPort: 3001,
})

export const RemotePage: React.FC = () => {
  const [selectedDeviceId, setSelectedDeviceId] = useState<string | null>(null)
  const [dragIndex, setDragIndex] = useState<number | null>(null)
  const [dragOverIndex, setDragOverIndex] = useState<number | null>(null)
  const [showConfig, setShowConfig] = useState(false)
  const [config, setConfig] = useState<RemoteConfig>(defaultConfig)
  const [loading, setLoading] = useState(true)
  const [editingDevice, setEditingDevice] = useState<RemoteDevice | null>(null)
  const [deviceLastConnected, setDeviceLastConnected] = useState<Record<string, string>>({})
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)
  const [deletingDeviceId, setDeletingDeviceId] = useState<string | null>(null)

  // 自定义拖拽状态
  const dragRef = useRef<{
    isDragging: boolean
    startY: number
    startIndex: number
    currentIndex: number
    listRect: DOMRect | null
    itemRects: DOMRect[]
  }>({
    isDragging: false,
    startY: 0,
    startIndex: -1,
    currentIndex: -1,
    listRect: null,
    itemRects: [],
  })
  const listContainerRef = useRef<HTMLDivElement>(null)

  const { selectFile } = useTabContentContext()
  const { screenshot, lastConnected, loadScreenshots } = useScreenshot()

  const selectedConfig = config.devices.find(d => d.id === selectedDeviceId) || null

  useEffect(() => {
    const init = async () => {
      try {
        const savedConfig = await getRemoteConfig()
        const configWithDevices = savedConfig.devices ? savedConfig : { devices: [] }
        setConfig(configWithDevices)
        if (configWithDevices.devices.length > 0 && !selectedDeviceId) {
          setSelectedDeviceId(configWithDevices.devices[0].id)
        }
        // 加载所有设备的最后连接时间
        const newData: Record<string, string> = {}
        for (const device of configWithDevices.devices) {
          if (device.deviceName) {
            try {
              const data = await getDeviceData(device.deviceName)
              if (data?.lastConnected) {
                newData[device.deviceName] = data.lastConnected
              }
            } catch (err) {
              console.error('Failed to load device data:', err)
            }
          }
        }
        setDeviceLastConnected(newData)
      } catch (err) {
        console.error('Failed to load remote config:', err)
      } finally {
        setLoading(false)
      }
    }
    init()
  }, [])

  useEffect(() => {
    if (selectedConfig?.deviceName) {
      loadScreenshots(selectedConfig.deviceName)
    }
  }, [selectedDeviceId, selectedConfig?.deviceName, loadScreenshots])

  // 当全局 lastConnected 更新时，同步更新 deviceLastConnected
  useEffect(() => {
    if (selectedConfig?.deviceName) {
      setDeviceLastConnected(prev => ({
        ...prev,
        [selectedConfig.deviceName]: lastConnected
      }))
    }
  }, [lastConnected, selectedConfig?.deviceName])

  // 当设备列表变化时，加载新增设备的最后连接时间
  useEffect(() => {
    const loadNewDevices = async () => {
      for (const device of config.devices) {
        if (device.deviceName && !deviceLastConnected[device.deviceName]) {
          try {
            const data = await getDeviceData(device.deviceName)
            if (data?.lastConnected) {
              setDeviceLastConnected(prev => ({
                ...prev,
                [device.deviceName]: data.lastConnected
              }))
            }
          } catch (err) {
            console.error('Failed to load device data:', err)
          }
        }
      }
    }
    if (!loading) {
      loadNewDevices()
    }
  }, [config.devices, loading, deviceLastConnected])

  const devices: DeviceInfo[] = (config.devices || []).map(device => ({
    id: device.id,
    name: device.deviceName,
    status: device.serverHost ? 'online' as const : 'offline' as const,
    lastConnected: deviceLastConnected[device.deviceName] || '-',
  }))

  const selectedDevice = devices.find(device => device.id === selectedDeviceId) || null

  const existingDeviceNames = config.devices.map(d => d.deviceName)

  const handleOpenRemoteDesktop = () => {
    if (!selectedConfig?.serverHost) {
      setShowConfig(true)
      return
    }
    const url = `http://${selectedConfig.serverHost}:${selectedConfig.desktopPort}`
    const deviceName = selectedConfig.deviceName ? ` - ${selectedConfig.deviceName}` : ''
    const fileItem = createRemoteDesktopFileItem(url, `远程桌面${deviceName}`, selectedConfig.deviceName)
    selectFile(fileItem)
  }

  const handleOpenGitRepo = () => {
    if (!selectedConfig?.serverHost) {
      setShowConfig(true)
      return
    }
    const url = `http://${selectedConfig.serverHost}:${selectedConfig.gitPort}`
    const deviceName = selectedConfig.deviceName ? ` - ${selectedConfig.deviceName}` : ''
    const fileItem = createRemoteGitFileItem(url, `远程 Git 仓库${deviceName}`, selectedConfig.deviceName)
    selectFile(fileItem)
  }

  const handleOpenFileTransfer = () => {
    if (!selectedConfig?.serverHost) {
      setShowConfig(true)
      return
    }
    const url = `file-transfer-panel?host=${encodeURIComponent(selectedConfig.serverHost)}&port=${selectedConfig.desktopPort}`
    const fileItem: FileItem = {
      name: `文件传输 - ${selectedConfig.deviceName}`,
      path: url,
      type: 'file',
      size: 0,
      modified: new Date().toISOString(),
    }
    selectFile(fileItem)
  }

  const handleOpenCode = () => {
    if (!selectedConfig?.serverHost) {
      setShowConfig(true)
      return
    }
    const url = `http://${selectedConfig.serverHost}:${selectedConfig.desktopPort}/opencode`
    const deviceName = selectedConfig.deviceName ? ` - ${selectedConfig.deviceName}` : ''
    const fileItem = createRemoteDesktopFileItem(url, `OpenCode${deviceName}`, selectedConfig.deviceName)
    selectFile(fileItem)
  }

  const handleOpenClaw = () => {
    if (!selectedConfig?.serverHost) {
      setShowConfig(true)
      return
    }
    const url = `http://${selectedConfig.serverHost}:${selectedConfig.desktopPort}/openclaw`
    const deviceName = selectedConfig.deviceName ? ` - ${selectedConfig.deviceName}` : ''
    const fileItem = createRemoteDesktopFileItem(url, `OpenClaw${deviceName}`, selectedConfig.deviceName)
    selectFile(fileItem)
  }

  const handleOpenConfig = () => {
    if (selectedConfig) {
      setEditingDevice(selectedConfig)
    } else {
      setEditingDevice(createEmptyDevice())
    }
    setShowConfig(true)
  }

  const handleCloseConfig = () => {
    setShowConfig(false)
    setEditingDevice(null)
  }

  const handleSaveConfig = useCallback(async (device: RemoteDevice) => {
    const existingIndex = config.devices.findIndex(d => d.id === device.id)
    let newDevices: RemoteDevice[]
    if (existingIndex >= 0) {
      newDevices = [...config.devices]
      newDevices[existingIndex] = device
    } else {
      newDevices = [...config.devices, device]
    }
    const newConfig = { devices: newDevices }
    try {
      await saveRemoteConfig(newConfig)
      setConfig(newConfig)
      setSelectedDeviceId(device.id)
    } catch (err) {
      console.error('Failed to save config:', err)
    }
    setShowConfig(false)
    setEditingDevice(null)
  }, [config.devices])

  const handleAddDevice = () => {
    setEditingDevice(createEmptyDevice())
    setShowConfig(true)
  }

  const handleDeleteDevice = (deviceId: string) => {
    setDeletingDeviceId(deviceId)
    setDeleteDialogOpen(true)
  }

  const handleDeleteConfirm = async () => {
    if (!deletingDeviceId) return
    const newDevices = config.devices.filter(d => d.id !== deletingDeviceId)
    const newConfig = { devices: newDevices }
    try {
      await saveRemoteConfig(newConfig)
      setConfig(newConfig)
      if (selectedDeviceId === deletingDeviceId) {
        setSelectedDeviceId(newDevices.length > 0 ? newDevices[0].id : null)
      }
    } catch (err) {
      console.error('Failed to delete device:', err)
    }
    setDeleteDialogOpen(false)
    setDeletingDeviceId(null)
  }

  const handleDeleteCancel = () => {
    setDeleteDialogOpen(false)
    setDeletingDeviceId(null)
  }

  // 自定义拖拽处理 - 元素跟随鼠标移动 + 实时重排
  const handleMouseDown = (e: React.MouseEvent, index: number) => {
    // 只允许左键拖拽
    if (e.button !== 0) return

    // 阻止默认选择行为
    e.preventDefault()
    e.stopPropagation()

    const listContainer = listContainerRef.current
    if (!listContainer) return

    const listRect = listContainer.getBoundingClientRect()

    // 获取被拖动元素的引用
    const listContent = listContainer.querySelector('[data-drag-list]')
    const items = listContent?.querySelectorAll('[data-drag-item]') as NodeListOf<HTMLElement> | undefined
    const draggedElement = items?.[index]

    dragRef.current = {
      isDragging: true,
      startY: e.clientY,
      startIndex: index,
      currentIndex: index,
      listRect,
      itemRects: [],
    }

    setDragIndex(index)
    setDragOverIndex(index)

    // 直接操作DOM实现流畅拖动
    if (draggedElement) {
      draggedElement.style.position = 'relative'
      draggedElement.style.zIndex = '100'
      draggedElement.style.transition = 'none'
    }

    // 添加全局鼠标事件
    document.addEventListener('mousemove', handleMouseMove)
    document.addEventListener('mouseup', handleMouseUp)
  }

  const handleMouseMove = (e: MouseEvent) => {
    const drag = dragRef.current
    if (!drag.isDragging || !drag.listRect) return

    const { listRect, startIndex } = drag

    // 检测鼠标是否在列表区域内
    const isInListArea =
      e.clientX >= listRect.left &&
      e.clientX <= listRect.right &&
      e.clientY >= listRect.top &&
      e.clientY <= listRect.bottom

    // 如果鼠标移出列表区域，取消拖拽
    if (!isInListArea) {
      handleMouseUp(e)
      return
    }

    // 直接修改DOM实现流畅移动
    const listContent = listContainerRef.current?.querySelector('[data-drag-list]')
    const items = listContent?.querySelectorAll('[data-drag-item]') as NodeListOf<HTMLElement> | undefined
    const draggedElement = items?.[drag.startIndex]

    // 计算被拖动元素的偏移
    const deltaY = e.clientY - drag.startY

    if (draggedElement) {
      draggedElement.style.transform = `translateY(${deltaY}px)`
    }

    const mouseY = e.clientY

    // 简单计算：基于鼠标在列表中的相对位置，加24px偏移使落点在缝隙中间
    const relativeY = mouseY - listRect.top - 8
    let newIndex = Math.floor(relativeY / 48) - 1
    newIndex = Math.max(0, Math.min(newIndex, devices.length - 1))

    // 限制newIndex范围
    if (newIndex < 0) newIndex = 0
    if (newIndex >= devices.length) newIndex = devices.length - 1

    drag.currentIndex = newIndex
    setDragOverIndex(newIndex)

    // 直接操作其他元素DOM实现重排（去掉transition）
    if (items) {
      const itemHeight = 48
      items.forEach((item, i) => {
        if (i === drag.startIndex) return // 跳过被拖动的元素

        let transform = ''
        if (drag.startIndex < newIndex) {
          // 从上面拖到下面：原位置到目标位置之间的元素向上移动
          if (i > drag.startIndex && i <= newIndex) {
            transform = `translateY(-${itemHeight}px)`
          }
        } else if (drag.startIndex > newIndex) {
          // 从下面拖到上面：目标位置到原位置之间的元素向下移动
          if (i >= newIndex && i < drag.startIndex) {
            transform = `translateY(${itemHeight}px)`
          }
        }
        item.style.transform = transform
      })
    }
  }

  const handleMouseUp = async (e: MouseEvent) => {
    const drag = dragRef.current
    if (!drag.isDragging) return

    drag.isDragging = false

    document.removeEventListener('mousemove', handleMouseMove)
    document.removeEventListener('mouseup', handleMouseUp)

    // 清理所有元素的样式
    const listContent = listContainerRef.current?.querySelector('[data-drag-list]')
    const items = listContent?.querySelectorAll('[data-drag-item]') as NodeListOf<HTMLElement> | undefined
    items?.forEach(item => {
      item.style.transform = ''
      item.style.position = ''
      item.style.zIndex = ''
      item.style.transition = ''
    })
    const draggedElement = items?.[drag.startIndex]
    if (draggedElement) {
      draggedElement.style.transform = ''
      draggedElement.style.position = ''
      draggedElement.style.zIndex = ''
    }

    const { startIndex, currentIndex } = drag

    setDragIndex(null)
    setDragOverIndex(null)

    // 如果位置发生变化，保存新顺序
    if (startIndex !== currentIndex && currentIndex >= 0) {
      const newDevices = [...config.devices]
      const [movedItem] = newDevices.splice(startIndex, 1)
      newDevices.splice(currentIndex, 0, movedItem)

      const newConfig = { devices: newDevices }

      try {
        await saveRemoteConfig(newConfig)
        setConfig(newConfig)
      } catch (err) {
        console.error('Failed to save reordered config:', err)
      }
    }

    dragRef.current = {
      isDragging: false,
      startY: 0,
      startIndex: -1,
      currentIndex: -1,
      listRect: null,
      itemRects: [],
    }
  }

  if (loading) {
    return (
      <div className="h-full flex items-center justify-center">
        <div className="text-gray-500 dark:text-gray-400">加载中...</div>
      </div>
    )
  }

  return (
    <div className="h-full flex flex-col">
      <div className="pl-12 pt-6 pb-4 shrink-0">
        <h1 className="text-2xl font-bold text-gray-800 dark:text-gray-200 flex items-center gap-2 whitespace-nowrap">
          <Monitor className="w-8 h-8 shrink-0" />
          远程
        </h1>
      </div>

      <div className="flex-1 flex px-0 -ml-4">
        <div className="absolute left-60 top-[88px] bottom-16 w-px bg-gray-300/40 dark:bg-gray-500/50" />
        <div
          ref={listContainerRef}
          className="w-56 shrink-0 pr-4 overflow-hidden select-none"
        >
          <button
            onClick={handleAddDevice}
            className="w-full flex items-center gap-2 px-3 py-3 rounded-lg cursor-pointer transition-colors hover:bg-gray-100/50 dark:hover:bg-gray-700/40 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200"
          >
            <Plus size={16} className="shrink-0" />
            <span className="text-base truncate">添加设备</span>
          </button>
          <div data-drag-list className="space-y-2 w-full relative mt-2">
            {devices.map((device, index) => {
              const isSelected = selectedDeviceId === device.id
              const isDragging = dragIndex === index

              return (
                <div
                  key={device.id}
                  data-drag-item
                  className={`group flex items-center gap-2 px-3 py-3 rounded-lg transition-all w-full max-w-full ${
                    isSelected
                      ? 'bg-gray-100/50 dark:bg-gray-700/40'
                      : 'hover:bg-gray-100/30 dark:hover:bg-gray-700/20'
                  } ${isDragging ? 'opacity-90' : ''}`}
                  onClick={() => dragIndex === null && setSelectedDeviceId(device.id)}
                >
                  <span
                    onMouseDown={(e) => handleMouseDown(e, index)}
                    className="cursor-grab active:cursor-grabbing p-0.5 hover:bg-gray-200/50 dark:hover:bg-gray-600/50 rounded"
                  >
                    <GripVertical size={14} className="text-gray-400 shrink-0" />
                  </span>
                  <span
                    className={`w-2 h-2 rounded-full shrink-0 ${device.status === 'online' ? 'bg-green-500' : 'bg-gray-400'
                      }`}
                  />
                  <span className="text-base text-gray-700 dark:text-gray-300 truncate flex-1">
                    {device.name || '未命名设备'}
                  </span>
                  <button
                    onClick={(e) => {
                      e.stopPropagation()
                      handleDeleteDevice(device.id)
                    }}
                    className="opacity-0 group-hover:opacity-100 p-1 hover:bg-red-100 dark:hover:bg-red-900/30 rounded transition-all"
                  >
                    <Trash2 size={14} className="text-red-500" />
                  </button>
                </div>
              )
            })}
          </div>

          {devices.length === 0 && (
            <div className="text-center py-8 text-gray-500 dark:text-gray-400 text-sm">
              暂无设备，点击上方添加
            </div>
          )}
        </div>

        <div className="flex-1 pl-8 -mt-10 min-w-[400px] overflow-auto pb-6">
          {selectedDevice && selectedConfig ? (
            <div className="flex flex-col">
              <div className="flex items-center justify-between py-0 px-4 shrink-0 border-b border-gray-300/40 dark:border-gray-500/50">
                <div className="flex items-center gap-4">
                  <h2 className="text-lg font-semibold text-gray-800 dark:text-gray-200 whitespace-nowrap">
                    {selectedDevice.name || '未命名设备'}
                  </h2>
                  <div className="flex items-center gap-3 text-sm text-gray-500 dark:text-gray-400 whitespace-nowrap">
                    <span className="flex items-center gap-1">
                      <span
                        className={`w-1.5 h-1.5 rounded-full ${selectedDevice.status === 'online' ? 'bg-green-500' : 'bg-gray-400'
                          }`}
                      />
                      {selectedDevice.status === 'online' ? '在线' : '离线'}
                    </span>
                    <span>最后连接：{selectedDevice.lastConnected}</span>
                  </div>
                </div>
                <button
                  onClick={handleOpenConfig}
                  className="p-2 rounded-lg transition-colors hover:bg-gray-100/50 dark:hover:bg-gray-700/40 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
                  title="配置"
                >
                  <Settings size={18} />
                </button>
              </div>

              <div className="mt-6 mb-4">
                <div className="grid grid-cols-[2fr_1fr_1fr] gap-8">
                  <button
                    onClick={handleOpenRemoteDesktop}
                    className="relative flex flex-col rounded-2xl overflow-hidden border-2 border-gray-300 dark:border-gray-600 hover:border-gray-500 dark:hover:border-gray-400 bg-white dark:bg-gray-800 shadow-sm hover:shadow-md transition-all cursor-pointer"
                  >
                    <div className="relative">
                      <img
                        src={screenshot || '/background.png'}
                        alt="远程桌面"
                        className="w-full aspect-video object-cover"
                      />
                      <div className="absolute bottom-0 left-0 right-0 py-2 bg-gradient-to-t from-black/50 to-transparent text-lg font-medium text-white text-center">
                        远程桌面
                      </div>
                    </div>
                  </button>

                  <div className="grid grid-rows-2 gap-6">
                    <button
                      onClick={handleOpenGitRepo}
                      className="flex flex-col items-center justify-center gap-2 text-lg bg-white dark:bg-gray-800 border-2 border-gray-300 dark:border-gray-600 hover:border-gray-500 dark:hover:border-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-2xl shadow-sm hover:shadow-md transition-all font-medium text-gray-700 dark:text-gray-200"
                    >
                      <GitBranch size={28} className="text-gray-600 dark:text-gray-300" />
                      <span>Git 仓库</span>
                    </button>

                    <button
                      onClick={handleOpenFileTransfer}
                      className="flex flex-col items-center justify-center gap-2 text-lg bg-white dark:bg-gray-800 border-2 border-gray-300 dark:border-gray-600 hover:border-gray-500 dark:hover:border-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-2xl shadow-sm hover:shadow-md transition-all font-medium text-gray-700 dark:text-gray-200"
                    >
                      <Folder size={28} className="text-gray-600 dark:text-gray-300" />
                      <span>文件传输</span>
                    </button>
                  </div>

                  <div className="grid grid-rows-2 gap-6">
                    <button
                      onClick={handleOpenCode}
                      className="flex flex-col items-center justify-center gap-2 text-lg bg-white dark:bg-gray-800 border-2 border-gray-300 dark:border-gray-600 hover:border-gray-500 dark:hover:border-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-2xl shadow-sm hover:shadow-md transition-all font-medium text-gray-700 dark:text-gray-200"
                    >
                      <Code size={28} className="text-gray-600 dark:text-gray-300" />
                      <span>OpenCode</span>
                    </button>

                    <button
                      onClick={handleOpenClaw}
                      className="flex flex-col items-center justify-center gap-2 text-lg bg-white dark:bg-gray-800 border-2 border-gray-300 dark:border-gray-600 hover:border-gray-500 dark:hover:border-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 rounded-2xl shadow-sm hover:shadow-md transition-all font-medium text-gray-700 dark:text-gray-200"
                    >
                      <Sparkles size={28} className="text-gray-600 dark:text-gray-300" />
                      <span>OpenClaw</span>
                    </button>
                  </div>
                </div>
              </div>
              </div>
            ) : (
              <div className="h-full flex items-center justify-center text-gray-500 dark:text-gray-400">
                请选择设备
              </div>
            )}
          </div>

        {editingDevice && (
          <ConfigDialog
            isOpen={showConfig}
            onClose={handleCloseConfig}
            config={editingDevice}
            onSave={handleSaveConfig}
            existingDeviceNames={existingDeviceNames.filter(name => name !== editingDevice.deviceName)}
            isEdit={!!config.devices.find(d => d.id === editingDevice.id)}
          />
        )}

        {deletingDeviceId && (
          <DeleteConfirmDialog
            isOpen={deleteDialogOpen}
            title="删除设备"
            message={`确定要删除设备 "${config.devices.find(d => d.id === deletingDeviceId)?.deviceName || '未命名设备'}" 吗？`}
            expectedText="DELETE DEVICE"
            onConfirm={handleDeleteConfirm}
            onCancel={handleDeleteCancel}
          />
        )}
      </div>
    </div>
  )
}
