import { useEffect, useRef, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Download, ExternalLink, RefreshCw, Trash2, Upload, UploadCloud } from 'lucide-react'
import { api, type WebUI } from '@/api'
import { useAbout, useSchedulerSettings, useSiteSettings } from '@/api/hooks'
import { useTheme } from '@/context/ThemeContext'
import { Button, Card, Input, PageHeader, Switch, Tabs, Textarea } from '@/components/ui'
import { toast } from '@/lib/toast'

export default function Settings() {
  const { theme, setTheme } = useTheme()
  const qc = useQueryClient()
  const { data: site } = useSiteSettings()
  const { data: scheduler } = useSchedulerSettings()
  const { data: about } = useAbout()
  const [tab, setTab] = useState('site')
  const [siteForm, setSiteForm] = useState({
    title: '',
    subtitle: '',
    page_size: '20',
    cookie_days: '7',
    openapi_enabled: false,
    openapi_token: '',
    system_notice_days: '7',
    system_notice_max_count: '1000',
    push_log_days: '7',
    push_log_max_count: '1000',
    login_log_days: '30',
    login_log_max_count: '1000',
    scheduler_log_days: '7',
    scheduler_log_max_count: '1000',
  })
  const [schedulerForm, setSchedulerForm] = useState({ worker_count: '4', queue_size: '100', rate_interval: '0' })
  const [passwordForm, setPasswordForm] = useState({ old_password: '', new_password: '', username: '' })
  const [changelog, setChangelog] = useState('')
  const [backupStatus, setBackupStatus] = useState<{ has_backup: boolean; backup_time: string } | null>(null)
  const [message, setMessage] = useState('')
  const webuiInputRef = useRef<HTMLInputElement>(null)

  const { data: loginLogs } = useQuery({
    queryKey: ['loginLogs'],
    queryFn: () => api.settings.getLoginLogs({ page: 1, page_size: 20 }),
    enabled: tab === 'security',
  })

  const { data: webuis, refetch: refetchWebui, isFetching: webuiFetching } = useQuery({
    queryKey: ['webuis'],
    queryFn: async () => {
      const list = await api.webui.list()
      return Array.isArray(list) ? list : []
    },
    enabled: tab === 'webui',
  })

  useEffect(() => {
    if (site) {
      setSiteForm({
        title: site.title || '',
        subtitle: site.subtitle || '',
        page_size: site.page_size || '20',
        cookie_days: site.cookie_days || '7',
        openapi_enabled: !!site.openapi_enabled,
        openapi_token: site.openapi_token || '',
        system_notice_days: site.system_notice_days || '7',
        system_notice_max_count: site.system_notice_max_count || '1000',
        push_log_days: site.push_log_days || '7',
        push_log_max_count: site.push_log_max_count || '1000',
        login_log_days: site.login_log_days || '30',
        login_log_max_count: site.login_log_max_count || '1000',
        scheduler_log_days: site.scheduler_log_days || '7',
        scheduler_log_max_count: site.scheduler_log_max_count || '1000',
      })
    }
  }, [site])

  useEffect(() => {
    if (scheduler) {
      setSchedulerForm({
        worker_count: scheduler.worker_count || '4',
        queue_size: scheduler.queue_size || '100',
        rate_interval: scheduler.rate_interval || '0',
      })
    }
  }, [scheduler])

  useEffect(() => {
    if (tab !== 'about' && tab !== 'backup') return
    if (tab === 'about') {
      api.settings
        .getChangelog()
        .then((t) => setChangelog(typeof t === 'string' ? t : ''))
        .catch(() => setChangelog(''))
    }
    api.settings
      .getBackupStatus()
      .then(setBackupStatus)
      .catch(() => setBackupStatus(null))
  }, [tab])

  const saveSite = useMutation({
    mutationFn: () =>
      api.settings.updateSite({
        ...(site || {}),
        ...siteForm,
        openapi_enabled: siteForm.openapi_enabled,
      } as any),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['siteSettings'] })
      qc.invalidateQueries({ queryKey: ['publicSite'] })
      setMessage('站点设置已保存')
      toast.success('站点设置已保存')
    },
    onError: (e: any) => {
      setMessage(e?.message || '保存失败')
      toast.error(e?.message || '保存失败')
    },
  })

  const saveScheduler = useMutation({
    mutationFn: () => api.settings.updateScheduler(schedulerForm),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['schedulerSettings'] })
      setMessage('调度设置已保存')
      toast.success('调度设置已保存')
    },
    onError: (e: any) => {
      setMessage(e?.message || '保存失败')
      toast.error(e?.message || '保存失败')
    },
  })

  const changePassword = useMutation({
    mutationFn: () =>
      api.settings.changePassword({
        old_password: passwordForm.old_password,
        new_password: passwordForm.new_password || undefined,
        username: passwordForm.username || undefined,
      }),
    onSuccess: () => {
      setPasswordForm({ old_password: '', new_password: '', username: '' })
      setMessage('账号信息已更新')
      toast.success('账号信息已更新')
    },
    onError: (e: any) => {
      setMessage(e?.message || '更新失败')
      toast.error(e?.message || '更新失败')
    },
  })

  const genToken = useMutation({
    mutationFn: () => api.settings.generateOpenapiToken(),
    onSuccess: (res) => {
      setSiteForm((f) => ({ ...f, openapi_token: res.token || '' }))
      setMessage('OpenAPI Token 已生成')
      toast.success('OpenAPI Token 已生成')
      qc.invalidateQueries({ queryKey: ['siteSettings'] })
    },
    onError: (e: any) => {
      setMessage(e?.message || '生成失败')
      toast.error(e?.message || '生成失败')
    },
  })

  const createBackup = useMutation({
    mutationFn: () => api.settings.createBackup(),
    onSuccess: async () => {
      setMessage('备份已创建')
      toast.success('备份已创建')
      setBackupStatus(await api.settings.getBackupStatus())
    },
    onError: (e: any) => {
      setMessage(e?.message || '备份失败')
      toast.error(e?.message || '备份失败')
    },
  })

  const uploadWebui = useMutation({
    mutationFn: (file: File) => api.webui.upload(file),
    onSuccess: (res) => {
      const msg = res?.message || 'WebUI 上传成功'
      setMessage(msg)
      toast.success(msg)
      refetchWebui()
      qc.invalidateQueries({ queryKey: ['siteSettings'] })
    },
    onError: (e: any) => {
      setMessage(e?.message || '上传失败')
      toast.error(e?.message || '上传失败')
    },
  })

  const activateWebui = useMutation({
    mutationFn: (name: string) => api.webui.setActive(name),
    onSuccess: (res) => {
      const msg = res?.message || '已切换前端主题'
      setMessage(msg)
      toast.success(msg)
      refetchWebui()
      qc.invalidateQueries({ queryKey: ['siteSettings'] })
    },
    onError: (e: any) => {
      setMessage(e?.message || '切换失败')
      toast.error(e?.message || '切换失败')
    },
  })

  const deleteWebui = useMutation({
    mutationFn: (name: string) => api.webui.delete(name),
    onSuccess: (res) => {
      const msg = res?.message || '已删除 WebUI'
      setMessage(msg)
      toast.success(msg)
      refetchWebui()
    },
    onError: (e: any) => {
      setMessage(e?.message || '删除失败')
      toast.error(e?.message || '删除失败')
    },
  })

  async function restoreBackup(file?: File | null) {
    if (!file) return
    try {
      await api.settings.restoreBackup(file)
      setMessage('恢复成功，建议刷新页面')
      toast.success('恢复成功，建议刷新页面')
    } catch (e: any) {
      setMessage(e?.message || '恢复失败')
      toast.error(e?.message || '恢复失败')
    }
  }

  const logs = Array.isArray(loginLogs?.data) ? loginLogs.data : []
  const webuiList: WebUI[] = Array.isArray(webuis) ? webuis : []
  const activeWebui = site?.active_webui || ''

  return (
    <div className="max-w-4xl space-y-4">
      <PageHeader title="系统设置" description="站点、调度、安全、前端定制与备份" />
      {message ? <div className="rounded-md bg-blue-500/10 px-3 py-2 text-sm text-blue-400">{message}</div> : null}

      <Tabs
        value={tab}
        onValueChange={setTab}
        items={[
          { value: 'site', label: '站点' },
          { value: 'webui', label: '前端定制' },
          { value: 'scheduler', label: '调度' },
          { value: 'security', label: '安全' },
          { value: 'backup', label: '备份' },
          { value: 'about', label: '关于' },
        ]}
      />

      {tab === 'site' ? (
        <div className="space-y-4">
          <Card className="space-y-3 p-4">
            <h2 className="font-medium">外观</h2>
            <div className="flex gap-2">
              <Button variant={theme === 'light' ? 'default' : 'secondary'} onClick={() => setTheme('light')}>
                浅色
              </Button>
              <Button variant={theme === 'dark' ? 'default' : 'secondary'} onClick={() => setTheme('dark')}>
                深色
              </Button>
            </div>
          </Card>
          <Card className="space-y-3 p-4">
            <h2 className="font-medium">站点设置</h2>
            <Input placeholder="站点标题" value={siteForm.title} onChange={(e) => setSiteForm((f) => ({ ...f, title: e.target.value }))} />
            <Input placeholder="站点副标题" value={siteForm.subtitle} onChange={(e) => setSiteForm((f) => ({ ...f, subtitle: e.target.value }))} />
            <div className="grid gap-3 md:grid-cols-2">
              <div>
                <label className="mb-1 block text-xs text-[var(--text-muted)]">分页大小</label>
                <Input placeholder="20" value={siteForm.page_size} onChange={(e) => setSiteForm((f) => ({ ...f, page_size: e.target.value }))} />
              </div>
              <div>
                <label className="mb-1 block text-xs text-[var(--text-muted)]">登录 Cookie 有效天数</label>
                <Input placeholder="7" value={siteForm.cookie_days} onChange={(e) => setSiteForm((f) => ({ ...f, cookie_days: e.target.value }))} />
              </div>
            </div>
            <label className="flex items-center justify-between text-sm">
              <span>启用 OpenAPI</span>
              <Switch checked={siteForm.openapi_enabled} onCheckedChange={(v) => setSiteForm((f) => ({ ...f, openapi_enabled: v }))} />
            </label>
            <div className="flex flex-wrap gap-2">
              <Input className="min-w-[220px] flex-1 font-mono text-xs" readOnly value={siteForm.openapi_token} placeholder="OpenAPI Token" />
              <Button variant="secondary" onClick={() => genToken.mutate()} disabled={genToken.isPending}>
                生成 Token
              </Button>
            </div>
            <div className="rounded-md border border-[var(--border)] bg-[var(--bg-secondary)] p-3 text-xs leading-5 text-[var(--text-secondary)]">
              <div className="mb-1 font-medium text-[var(--text-primary)]">MCP Server（Hermes / OpenClaw）</div>
              <p className="mb-2">
                OpenAPI 是 REST 接口；AI Agent 请使用 <code className="rounded bg-[var(--bg-tertiary)] px-1">taskpool mcp</code> 作为 MCP
                Server 完整接管任务/脚本/日志。
              </p>
              <pre className="overflow-x-auto whitespace-pre-wrap rounded-md border border-[var(--border)] bg-[var(--bg-primary)] p-2 font-mono text-[11px] text-[var(--text-primary)]">{`{
  "mcpServers": {
    "taskpool": {
      "command": "taskpool",
      "args": ["mcp"],
      "env": {
        "TASKPOOL_URL": "${window.location.origin}",
        "TASKPOOL_TOKEN": "${siteForm.openapi_token || '在设置页生成 OpenAPI Token'}"
      }
    }
  }
}`}</pre>
              <p className="mt-2 text-[var(--text-muted)]">详细说明见仓库 docs/guide/mcp.md 与 skills/taskpool/SKILL.md</p>
            </div>
            <h3 className="pt-2 text-sm font-medium text-[var(--text-secondary)]">日志保留</h3>
            <p className="text-xs text-[var(--text-muted)]">设置各类日志的保留天数和最大条数限制，超出后自动清理最旧记录</p>
            <div className="space-y-3">
              <div className="rounded-md border border-[var(--border)] bg-[var(--bg-tertiary)]/50 p-3">
                <div className="mb-2 text-sm font-medium text-[var(--text-primary)]">系统通知</div>
                <p className="mb-2 text-xs text-[var(--text-muted)]">系统级事件通知，如任务失败报警、服务状态变更等</p>
                <div className="grid gap-2 md:grid-cols-2">
                  <Input placeholder="保留天数" value={siteForm.system_notice_days} onChange={(e) => setSiteForm((f) => ({ ...f, system_notice_days: e.target.value }))} />
                  <Input placeholder="最大条数" value={siteForm.system_notice_max_count} onChange={(e) => setSiteForm((f) => ({ ...f, system_notice_max_count: e.target.value }))} />
                </div>
              </div>
              <div className="rounded-md border border-[var(--border)] bg-[var(--bg-tertiary)]/50 p-3">
                <div className="mb-2 text-sm font-medium text-[var(--text-primary)]">推送日志</div>
                <p className="mb-2 text-xs text-[var(--text-muted)]">消息推送记录，如钉钉、企业微信、Telegram 等渠道的发送历史</p>
                <div className="grid gap-2 md:grid-cols-2">
                  <Input placeholder="保留天数" value={siteForm.push_log_days} onChange={(e) => setSiteForm((f) => ({ ...f, push_log_days: e.target.value }))} />
                  <Input placeholder="最大条数" value={siteForm.push_log_max_count} onChange={(e) => setSiteForm((f) => ({ ...f, push_log_max_count: e.target.value }))} />
                </div>
              </div>
              <div className="rounded-md border border-[var(--border)] bg-[var(--bg-tertiary)]/50 p-3">
                <div className="mb-2 text-sm font-medium text-[var(--text-primary)]">登录日志</div>
                <p className="mb-2 text-xs text-[var(--text-muted)]">用户登录记录，包含 IP、时间、状态等安全审计信息</p>
                <div className="grid gap-2 md:grid-cols-2">
                  <Input placeholder="保留天数" value={siteForm.login_log_days} onChange={(e) => setSiteForm((f) => ({ ...f, login_log_days: e.target.value }))} />
                  <Input placeholder="最大条数" value={siteForm.login_log_max_count} onChange={(e) => setSiteForm((f) => ({ ...f, login_log_max_count: e.target.value }))} />
                </div>
              </div>
              <div className="rounded-md border border-[var(--border)] bg-[var(--bg-tertiary)]/50 p-3">
                <div className="mb-2 text-sm font-medium text-[var(--text-primary)]">调度日志</div>
                <p className="mb-2 text-xs text-[var(--text-muted)]">任务执行日志，包含命令输出、执行状态、耗时等信息</p>
                <div className="grid gap-2 md:grid-cols-2">
                  <Input placeholder="保留天数" value={siteForm.scheduler_log_days} onChange={(e) => setSiteForm((f) => ({ ...f, scheduler_log_days: e.target.value }))} />
                  <Input placeholder="最大条数" value={siteForm.scheduler_log_max_count} onChange={(e) => setSiteForm((f) => ({ ...f, scheduler_log_max_count: e.target.value }))} />
                </div>
              </div>
            </div>
            <Button onClick={() => saveSite.mutate()} disabled={saveSite.isPending}>
              保存站点设置
            </Button>
          </Card>
        </div>
      ) : null}

      {tab === 'webui' ? (
        <Card className="space-y-4 p-4">
          <div className="flex flex-wrap items-start justify-between gap-3">
            <div>
              <h2 className="font-medium">自定义前端包 (WebUI)</h2>
              <p className="mt-1 text-sm text-[var(--text-muted)]">上传并切换自定义前端资源包，实现深度定制</p>
              <a
                href="https://engigu.github.io/taskpool/guide/webui"
                target="_blank"
                rel="noreferrer"
                className="mt-2 inline-flex items-center gap-1 text-xs text-blue-500 hover:underline"
              >
                开发文档 <ExternalLink size={12} />
              </a>
            </div>
            <div className="flex gap-2">
              <Button variant="secondary" onClick={() => refetchWebui()} disabled={webuiFetching}>
                <RefreshCw size={14} className={webuiFetching ? 'animate-spin' : ''} />
                刷新
              </Button>
              <Button onClick={() => webuiInputRef.current?.click()} disabled={uploadWebui.isPending}>
                <UploadCloud size={14} />
                {uploadWebui.isPending ? '上传中...' : '上传资源包'}
              </Button>
              <input
                ref={webuiInputRef}
                type="file"
                accept=".zip"
                className="hidden"
                onChange={(e) => {
                  const file = e.target.files?.[0]
                  if (file) uploadWebui.mutate(file)
                  e.target.value = ''
                }}
              />
            </div>
          </div>

          {webuiList.length === 0 ? (
            <div className="rounded-md border border-dashed border-[var(--border)] p-8 text-center text-sm text-[var(--text-muted)]">
              暂无自定义前端包，可上传 zip 资源包
            </div>
          ) : (
            <div className="space-y-2">
              {webuiList.map((item) => {
                const active = activeWebui === item.name
                return (
                  <div key={item.name} className="flex flex-wrap items-center justify-between gap-3 rounded-md border border-[var(--border)] p-3">
                    <div className="min-w-0">
                      <div className="flex items-center gap-2">
                        <span className="font-medium">{item.name}</span>
                        {active ? (
                          <span className="rounded bg-emerald-500/15 px-1.5 py-0.5 text-[10px] text-emerald-500">当前</span>
                        ) : null}
                      </div>
                      <div className="mt-1 text-xs text-[var(--text-muted)]">
                        v{item.version || '-'} · {item.author || '未知作者'}
                        {item.min_panel_version ? ` · 最低面板 ${item.min_panel_version}` : ''}
                      </div>
                      {item.description ? <div className="mt-1 text-sm text-[var(--text-secondary)]">{item.description}</div> : null}
                    </div>
                    <div className="flex gap-2">
                      <Button size="sm" variant="secondary" disabled={active || activateWebui.isPending} onClick={() => activateWebui.mutate(item.name)}>
                        {active ? '使用中' : '启用'}
                      </Button>
                      <Button
                        size="sm"
                        variant="danger"
                        disabled={deleteWebui.isPending}
                        onClick={() => {
                          if (confirm(`确认删除前端包 ${item.name}？`)) deleteWebui.mutate(item.name)
                        }}
                      >
                        <Trash2 size={14} />
                      </Button>
                    </div>
                  </div>
                )
              })}
            </div>
          )}
        </Card>
      ) : null}

      {tab === 'scheduler' ? (
        <Card className="space-y-3 p-4">
          <h2 className="font-medium">调度设置</h2>
          <p className="text-xs text-[var(--text-muted)]">控制任务调度器的并发能力和队列行为</p>
          <div className="grid gap-3 md:grid-cols-3">
            <div>
              <label className="mb-1 block text-xs text-[var(--text-muted)]">Worker 数量</label>
              <Input placeholder="4" value={schedulerForm.worker_count} onChange={(e) => setSchedulerForm((f) => ({ ...f, worker_count: e.target.value }))} />
              <p className="mt-1 text-xs text-[var(--text-muted)]">并发执行任务的最大数量</p>
            </div>
            <div>
              <label className="mb-1 block text-xs text-[var(--text-muted)]">队列大小</label>
              <Input placeholder="100" value={schedulerForm.queue_size} onChange={(e) => setSchedulerForm((f) => ({ ...f, queue_size: e.target.value }))} />
              <p className="mt-1 text-xs text-[var(--text-muted)]">等待执行的任务队列容量</p>
            </div>
            <div>
              <label className="mb-1 block text-xs text-[var(--text-muted)]">限速间隔（毫秒）</label>
              <Input placeholder="0" value={schedulerForm.rate_interval} onChange={(e) => setSchedulerForm((f) => ({ ...f, rate_interval: e.target.value }))} />
              <p className="mt-1 text-xs text-[var(--text-muted)]">任务启动间隔，0 表示不限速</p>
            </div>
          </div>
          <Button onClick={() => saveScheduler.mutate()} disabled={saveScheduler.isPending}>
            保存调度设置
          </Button>
        </Card>
      ) : null}

      {tab === 'security' ? (
        <div className="space-y-4">
          <Card className="space-y-3 p-4">
            <h2 className="font-medium">账号安全</h2>
            <Input placeholder="新用户名（可选）" value={passwordForm.username} onChange={(e) => setPasswordForm((f) => ({ ...f, username: e.target.value }))} />
            <Input type="password" placeholder="旧密码" value={passwordForm.old_password} onChange={(e) => setPasswordForm((f) => ({ ...f, old_password: e.target.value }))} />
            <Input type="password" placeholder="新密码（可选）" value={passwordForm.new_password} onChange={(e) => setPasswordForm((f) => ({ ...f, new_password: e.target.value }))} />
            <Button onClick={() => changePassword.mutate()} disabled={!passwordForm.old_password || changePassword.isPending}>
              更新账号
            </Button>
          </Card>
          <Card className="overflow-hidden">
            <div className="border-b border-[var(--border)] px-4 py-3 text-sm font-medium">最近登录</div>
            {logs.length === 0 ? (
              <div className="p-4 text-sm text-[var(--text-muted)]">暂无登录日志</div>
            ) : (
              <div className="divide-y divide-[var(--border)]">
                {logs.map((log) => (
                  <div key={log.id} className="px-4 py-3 text-sm">
                    <div className="flex flex-wrap gap-2">
                      <span className="font-medium">{log.username}</span>
                      <span className="text-[var(--text-muted)]">{log.ip}</span>
                      <span className="text-xs text-[var(--text-muted)]">{log.status}</span>
                    </div>
                    <div className="mt-1 text-xs text-[var(--text-muted)]">
                      {log.message} · {log.created_at}
                    </div>
                  </div>
                ))}
              </div>
            )}
          </Card>
        </div>
      ) : null}

      {tab === 'backup' ? (
        <Card className="space-y-3 p-4">
          <h2 className="font-medium">备份与恢复</h2>
          <div className="text-sm text-[var(--text-muted)]">
            {backupStatus?.has_backup ? `最近备份: ${backupStatus.backup_time}` : '暂无备份'}
          </div>
          <div className="flex flex-wrap gap-2">
            <Button onClick={() => createBackup.mutate()} disabled={createBackup.isPending}>
              <RefreshCw size={14} />
              创建备份
            </Button>
            <a href={api.settings.downloadBackup()} className="inline-flex">
              <Button variant="secondary">
                <Download size={14} />
                下载备份
              </Button>
            </a>
            <label className="inline-flex cursor-pointer items-center gap-2 rounded-md border border-[var(--border)] bg-[var(--bg-secondary)] px-3 py-2 text-sm hover:bg-[var(--bg-hover)]">
              <Upload size={14} />
              恢复备份
              <input type="file" className="hidden" onChange={(e) => restoreBackup(e.target.files?.[0])} />
            </label>
          </div>
        </Card>
      ) : null}

      {tab === 'about' ? (
        <div className="space-y-4">
          <Card className="space-y-2 p-4 text-sm">
            <h2 className="font-medium">关于</h2>
            <div className="text-[var(--text-muted)]">版本: {about?.version || '-'}</div>
            <div className="text-[var(--text-muted)]">远程版本: {about?.remote_version || '-'}</div>
            <div className="text-[var(--text-muted)]">构建时间: {about?.build_time || '-'}</div>
            <div className="text-[var(--text-muted)]">运行时间: {about?.uptime || '-'}</div>
            <div className="text-[var(--text-muted)]">内存: {about?.mem_usage || '-'}</div>
            <div className="text-[var(--text-muted)]">
              任务/日志/变量: {about?.task_count ?? '-'} / {about?.log_count ?? '-'} / {about?.env_count ?? '-'}
            </div>
          </Card>
          <Card className="p-4">
            <h2 className="mb-2 font-medium">更新日志</h2>
            <Textarea className="min-h-[240px] font-mono text-xs" readOnly value={changelog || '暂无'} />
          </Card>
        </div>
      ) : null}
    </div>
  )
}
