import { useCallback, useEffect, useState } from 'react'
import { useSearch } from '@tanstack/react-router'
import { GitBranch, RefreshCw, Search, Terminal, Trash2 } from 'lucide-react'
import { api, type TaskLog } from '@/api'
import { useLogs } from '@/api/hooks'
import { LogDetailPanel } from '@/components/business/LogDetailPanel'
import { StatusDot } from '@/components/business/StatusDot'
import { Button, Card, Input, Modal, PageHeader, Select } from '@/components/ui'
import { TASK_EVENTS, TASK_STATUS_TEXT, TASK_TYPE } from '@/constants'
import { useEventBus } from '@/hooks/useEventBus'
import { useLogStream } from '@/hooks/useLogStream'
import { formatDateTime, formatDuration } from '@/lib/format'
import { toast } from '@/lib/toast'
import { cn } from '@/lib/utils'

export default function History() {
  const search = useSearch({ strict: false }) as { status?: string; task_name?: string; task_id?: string }
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(() => {
    const n = Number(localStorage.getItem('history_page_size') || '20')
    return [10, 20, 50, 100].includes(n) ? n : 20
  })
  const [status, setStatus] = useState(search.status || 'all')
  const [taskName, setTaskName] = useState(search.task_name || '')
  const [debouncedName, setDebouncedName] = useState(search.task_name || '')
  const [taskId, setTaskId] = useState(search.task_id || '')
  const [selected, setSelected] = useState<TaskLog | null>(null)
  const [fullscreen, setFullscreen] = useState(false)
  const [clearOpen, setClearOpen] = useState(false)
  const [deleteId, setDeleteId] = useState<string | null>(null)
  const [stopping, setStopping] = useState(false)

  const { data, isLoading, refetch, isFetching } = useLogs({
    page,
    page_size: pageSize,
    status: status === 'all' ? undefined : status,
    task_name: debouncedName || undefined,
    task_id: taskId || undefined,
  })
  const { content, loading, liveLog } = useLogStream(selected)

  const items = Array.isArray(data?.data) ? data.data : []
  const total = data?.total || 0
  const totalPages = Math.max(1, Math.ceil(total / pageSize))

  useEffect(() => {
    localStorage.setItem('history_page_size', String(pageSize))
  }, [pageSize])

  const onTaskEvent = useCallback(() => {
    refetch()
  }, [refetch])

  useEventBus(
    [TASK_EVENTS.SUCCESS, TASK_EVENTS.FAILED, TASK_EVENTS.TIMEOUT, TASK_EVENTS.RUNNING, TASK_EVENTS.QUEUED, TASK_EVENTS.CANCELLED],
    onTaskEvent,
  )

  useEffect(() => {
    if (search.status) setStatus(search.status)
    if (search.task_name) {
      setTaskName(search.task_name)
      setDebouncedName(search.task_name)
    }
    if (search.task_id !== undefined) setTaskId(search.task_id || '')
  }, [search.status, search.task_name, search.task_id])

  useEffect(() => {
    const t = setTimeout(() => {
      setDebouncedName(taskName)
      setPage(1)
    }, 300)
    return () => clearTimeout(t)
  }, [taskName])

  async function stopTask() {
    const id = liveLog?.id || selected?.id
    if (!id) return
    setStopping(true)
    try {
      await api.tasks.stop(id)
      toast.success('已发送停止指令')
    } catch (e: any) {
      toast.error(e?.message || '停止失败')
    } finally {
      setStopping(false)
      refetch()
    }
  }

  async function clearLogs() {
    try {
      await api.logs.clear()
      setClearOpen(false)
      setSelected(null)
      refetch()
      toast.success('日志已清空')
    } catch (e: any) {
      toast.error(e?.message || '清空失败')
    }
  }

  async function deleteLog() {
    if (!deleteId) return
    try {
      await api.logs.delete(deleteId)
      if (selected?.id === deleteId) setSelected(null)
      setDeleteId(null)
      refetch()
      toast.success('记录已删除')
    } catch (e: any) {
      toast.error(e?.message || '删除失败')
    }
  }

  const detailLog = liveLog || selected

  return (
    <div>
      <PageHeader
        title="执行历史"
        description="查看任务执行记录和日志"
        actions={
          <>
            <Button variant="secondary" onClick={() => refetch()} disabled={isFetching}>
              <RefreshCw size={14} className={isFetching ? 'animate-spin' : ''} />
              刷新
            </Button>
            <Button variant="danger" onClick={() => setClearOpen(true)}>
              <Trash2 size={14} />
              清空日志
            </Button>
          </>
        }
      />

      <div className="mb-4 flex flex-wrap gap-2">
        <div className="relative min-w-[200px] max-w-xs flex-1">
          <Search size={14} className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-[var(--text-muted)]" />
          <Input className="pl-9" placeholder="搜索任务..." value={taskName} onChange={(e) => setTaskName(e.target.value)} />
        </div>
        <Select
          className="max-w-[160px]"
          value={status}
          onChange={(e) => {
            setStatus(e.target.value)
            setPage(1)
          }}
        >
          <option value="all">所有状态</option>
          {Object.entries(TASK_STATUS_TEXT).map(([k, v]) => (
            <option key={k} value={k}>
              {v}
            </option>
          ))}
        </Select>
        {taskId ? (
          <Button
            size="sm"
            variant="secondary"
            onClick={() => {
              setTaskId('')
              setPage(1)
            }}
          >
            清除任务筛选: {taskId.slice(0, 8)}...
          </Button>
        ) : null}
      </div>

      <div className="grid gap-4 lg:grid-cols-[1.15fr_1fr] lg:min-h-[520px]">
        <Card className={cn('flex min-h-[320px] flex-col overflow-hidden', selected ? 'hidden lg:flex' : 'flex')}>
          <div className="hidden border-b border-[var(--border)] bg-[var(--bg-tertiary)]/50 px-4 py-2 text-xs text-[var(--text-muted)] sm:grid sm:grid-cols-[56px_40px_1fr_80px_140px_36px] sm:gap-2">
            <span>序号</span>
            <span className="text-center">类型</span>
            <span>任务</span>
            <span className="text-right">耗时</span>
            <span className="text-right">时间</span>
            <span />
          </div>
          <div className="flex-1 divide-y divide-[var(--border)] overflow-y-auto">
            {isLoading ? (
              <div className="p-6 text-[var(--text-muted)]">加载中...</div>
            ) : items.length === 0 ? (
              <div className="p-6 text-[var(--text-muted)]">暂无日志</div>
            ) : (
              items.map((log, index) => (
                <div
                  key={log.id}
                  className={cn(
                    'cursor-pointer px-3 py-2.5 transition hover:bg-[var(--bg-hover)] sm:grid sm:grid-cols-[56px_40px_1fr_80px_140px_36px] sm:items-center sm:gap-2',
                    selected?.id === log.id && 'bg-[var(--bg-tertiary)]',
                  )}
                  onClick={() => setSelected(log)}
                >
                  <div className="flex items-center gap-2 sm:contents">
                    <span className="inline-flex items-center gap-2 text-[11px] tabular-nums text-[var(--text-muted)]">
                      <StatusDot state={log.status} />#{total - (page - 1) * 20 - index}
                    </span>
                    <span className="hidden justify-center sm:flex" title={log.task_type === TASK_TYPE.REPO ? '仓库同步' : '普通任务'}>
                      {log.task_type === TASK_TYPE.REPO ? <GitBranch size={14} /> : <Terminal size={14} />}
                    </span>
                    <div className="min-w-0">
                      <div className="truncate text-sm font-medium">{log.task_name || log.task_id}</div>
                      <div className="mt-0.5 truncate font-mono text-[11px] text-[var(--text-muted)]">{log.command}</div>
                      <div className="mt-0.5 text-[11px] text-[var(--text-muted)] sm:hidden">
                        {TASK_STATUS_TEXT[log.status] || log.status} · {formatDuration(log.duration)}
                      </div>
                    </div>
                    <span className="hidden text-right text-xs text-[var(--text-muted)] sm:block">{formatDuration(log.duration)}</span>
                    <span className="hidden text-right text-[11px] text-[var(--text-muted)] sm:block">{formatDateTime(log.start_time || log.created_at)}</span>
                    <Button
                      size="icon"
                      variant="ghost"
                      className="ml-auto sm:ml-0"
                      onClick={(e) => {
                        e.stopPropagation()
                        setDeleteId(log.id)
                      }}
                    >
                      <Trash2 size={14} />
                    </Button>
                  </div>
                </div>
              ))
            )}
          </div>
          <div className="flex items-center justify-between border-t border-[var(--border)] px-4 py-3">
            <span className="text-sm text-[var(--text-muted)]">
              共 {total} 条 · 第 {page}/{totalPages} 页
            </span>
            <div className="flex gap-2">
              <Button variant="secondary" size="sm" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>
                上一页
              </Button>
              <Button variant="secondary" size="sm" disabled={page >= totalPages} onClick={() => setPage((p) => p + 1)}>
                下一页
              </Button>
            </div>
          </div>
        </Card>

        <Card className={cn('min-h-[320px] overflow-hidden', !selected && 'hidden lg:block')}>
          <LogDetailPanel
            log={detailLog}
            content={content}
            loading={loading}
            isStopping={stopping}
            onClose={() => setSelected(null)}
            onStop={stopTask}
            onDelete={(id) => setDeleteId(id)}
            onMaximize={() => setFullscreen(true)}
          />
        </Card>
      </div>

      <Modal open={fullscreen} title="日志全屏" onClose={() => setFullscreen(false)} size="full">
        <div className="h-[75vh] -m-4">
          <LogDetailPanel
            log={detailLog}
            content={content}
            loading={loading}
            isStopping={stopping}
            onClose={() => setFullscreen(false)}
            onStop={stopTask}
          />
        </div>
      </Modal>

      <Modal
        open={clearOpen}
        title="清空日志"
        onClose={() => setClearOpen(false)}
        footer={
          <>
            <Button variant="secondary" onClick={() => setClearOpen(false)}>
              取消
            </Button>
            <Button variant="danger" onClick={clearLogs}>
              确认清空
            </Button>
          </>
        }
      >
        <p className="text-sm text-[var(--text-secondary)]">确认清空全部执行历史？此操作不可恢复。</p>
      </Modal>

      <Modal
        open={!!deleteId}
        title="删除日志"
        onClose={() => setDeleteId(null)}
        footer={
          <>
            <Button variant="secondary" onClick={() => setDeleteId(null)}>
              取消
            </Button>
            <Button variant="danger" onClick={deleteLog}>
              删除
            </Button>
          </>
        }
      >
        <p className="text-sm text-[var(--text-secondary)]">确认删除该条执行记录？</p>
      </Modal>
    </div>
  )
}
