import { DownloadOutlined, LockOutlined, SettingOutlined, UploadOutlined, UserOutlined } from '@ant-design/icons'
import {
  Alert,
  Button,
  Card,
  Form,
  Input,
  Modal,
  Popconfirm,
  Radio,
  Space,
  Switch,
  Table,
  Tabs,
  Typography,
  Upload,
  message,
} from 'antd'
import { useEffect, useState } from 'react'
import { Link, Navigate } from 'react-router-dom'
import { adminApi } from '../api/client'
import { useAuth } from '../context/AuthContext'
import type { AdminUser, AIProvider, BackupInfo, SystemSettings } from '../types'

function formatBytes(size: number): string {
  if (size < 1024) return `${size} B`
  if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`
  return `${(size / 1024 / 1024).toFixed(1)} MB`
}

export default function SettingsPage() {
  const { user } = useAuth()
  const [settings, setSettings] = useState<SystemSettings | null>(null)
  const [users, setUsers] = useState<AdminUser[]>([])
  const [loading, setLoading] = useState(true)
  const [profileForm] = Form.useForm()
  const [createForm] = Form.useForm()
  const [createOpen, setCreateOpen] = useState(false)
  const [resetUser, setResetUser] = useState<AdminUser | null>(null)
  const [resetForm] = Form.useForm()
  const [aiForm] = Form.useForm()
  const [backups, setBackups] = useState<BackupInfo[]>([])
  const [backupLoading, setBackupLoading] = useState(false)
  const [runningBackup, setRunningBackup] = useState(false)
  const [restoring, setRestoring] = useState(false)
  const aiProvider = Form.useWatch('ai_provider', aiForm) as AIProvider | undefined

  if (!user?.is_superuser) return <Navigate to="/" replace />

  const load = async () => {
    setLoading(true)
    try {
      const [settingsRes, usersRes, backupsRes] = await Promise.all([
        adminApi.getSettings(),
        adminApi.listUsers(),
        adminApi.listBackups().catch(() => ({ data: [] as BackupInfo[] })),
      ])
      setSettings(settingsRes.data)
      setUsers(usersRes.data)
      setBackups(backupsRes.data)
      profileForm.setFieldsValue({ username: user.username })
      aiForm.setFieldsValue({
        ai_provider: settingsRes.data.ai_provider,
        ollama_base_url: settingsRes.data.ollama_base_url || '',
        ollama_model: settingsRes.data.ollama_model || '',
        openai_base_url: settingsRes.data.openai_base_url || '',
        openai_model: settingsRes.data.openai_model || '',
        openai_api_key: '',
        ocr_service_url: settingsRes.data.ocr_service_url || '',
      })
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    load()
  }, [])

  const toggleRegistration = async (checked: boolean) => {
    const { data } = await adminApi.updateSettings({ registration_enabled: checked })
    setSettings(data)
    message.success(checked ? '已开放注册' : '已关闭注册')
  }

  const toggleAiReview = async (checked: boolean) => {
    const { data } = await adminApi.updateSettings({ ai_review_enabled: checked })
    setSettings(data)
    message.success(checked ? '已开启 AI 复盘解读' : '已关闭 AI 复盘解读')
  }

  const saveProfile = async (values: {
    username: string
    current_password?: string
    password?: string
    confirm?: string
  }) => {
    if (values.password && values.password !== values.confirm) {
      message.error('两次密码不一致')
      return
    }
    await adminApi.updateProfile({
      username: values.username !== user?.username ? values.username : undefined,
      current_password: values.password ? values.current_password : undefined,
      password: values.password || undefined,
    })
    message.success('账号信息已更新，若修改了用户名或密码请重新登录')
  }

  const createUser = async (values: { username: string; password: string }) => {
    await adminApi.createUser(values)
    message.success('用户已创建')
    setCreateOpen(false)
    createForm.resetFields()
    load()
  }

  const resetPassword = async (values: { password: string }) => {
    if (!resetUser) return
    await adminApi.resetUserPassword(resetUser.id, values.password)
    message.success('密码已重置')
    setResetUser(null)
    resetForm.resetFields()
  }

  const removeUser = async (id: string) => {
    await adminApi.deleteUser(id)
    message.success('用户已删除')
    load()
  }

  const saveAiSettings = async (values: {
    ai_provider: AIProvider
    ollama_base_url?: string
    ollama_model?: string
    openai_base_url?: string
    openai_model?: string
    openai_api_key?: string
    ocr_service_url?: string
  }) => {
    const payload: Parameters<typeof adminApi.updateSettings>[0] = {
      ai_provider: values.ai_provider,
      ollama_base_url: values.ollama_base_url || null,
      ollama_model: values.ollama_model || null,
      openai_base_url: values.openai_base_url || null,
      openai_model: values.openai_model || null,
      ocr_service_url: values.ocr_service_url?.trim() || null,
    }
    if (values.openai_api_key?.trim()) {
      payload.openai_api_key = values.openai_api_key.trim()
    }
    const { data } = await adminApi.updateSettings(payload)
    setSettings(data)
    aiForm.setFieldValue('openai_api_key', '')
    message.success('AI 模型配置已保存')
  }

  const loadBackups = async () => {
    setBackupLoading(true)
    try {
      const { data } = await adminApi.listBackups()
      setBackups(data)
    } finally {
      setBackupLoading(false)
    }
  }

  const handleRunBackup = async () => {
    setRunningBackup(true)
    try {
      await adminApi.runBackup()
      message.success('备份已完成')
      await loadBackups()
    } catch {
      message.error('备份失败，请检查服务器 pg_dump 与目录权限')
    } finally {
      setRunningBackup(false)
    }
  }

  const handleDownloadBackup = async (filename: string) => {
    try {
      const { data } = await adminApi.downloadBackup(filename)
      const url = URL.createObjectURL(data)
      const a = document.createElement('a')
      a.href = url
      a.download = filename
      a.click()
      URL.revokeObjectURL(url)
    } catch {
      message.error('下载失败')
    }
  }

  const handleRestore = async (file: File) => {
    setRestoring(true)
    try {
      const { data } = await adminApi.restoreBackup(file)
      message.success(data.message || '数据已恢复')
      await loadBackups()
    } catch {
      message.error('恢复失败，请确认备份包完整且未损坏')
    } finally {
      setRestoring(false)
    }
    return false
  }

  return (
    <div className="page-container">
      <Space direction="vertical" size="large" style={{ width: '100%' }}>
        <div>
          <Typography.Title level={3} style={{ margin: 0 }}>
            系统设置
          </Typography.Title>
          <Typography.Text type="secondary">
            超级管理员 · <Link to="/">返回首页</Link>
          </Typography.Text>
        </div>

        <Tabs
          items={[
            {
              key: 'general',
              label: '基本设置',
              children: (
                <Space direction="vertical" size="large" style={{ width: '100%' }}>
                  <Card title="注册开关" loading={loading}>
                    <Space>
                      <Switch
                        checked={settings?.registration_enabled ?? true}
                        onChange={toggleRegistration}
                      />
                      <Typography.Text>
                        {settings?.registration_enabled
                          ? '开放注册：用户可在登录页自行注册'
                          : '关闭注册：仅超级管理员可添加用户'}
                      </Typography.Text>
                    </Space>
                  </Card>

                  <Card title="管理员账号">
                    <Form form={profileForm} layout="vertical" onFinish={saveProfile}>
                      <Form.Item
                        name="username"
                        label="用户名"
                        rules={[{ required: true, min: 3 }]}
                      >
                        <Input prefix={<UserOutlined />} />
                      </Form.Item>
                      <Form.Item name="current_password" label="当前密码（修改密码时必填）">
                        <Input.Password prefix={<LockOutlined />} />
                      </Form.Item>
                      <Form.Item name="password" label="新密码（留空则不修改）">
                        <Input.Password prefix={<LockOutlined />} />
                      </Form.Item>
                      <Form.Item name="confirm" label="确认新密码">
                        <Input.Password prefix={<LockOutlined />} />
                      </Form.Item>
                      <Button type="primary" htmlType="submit" icon={<SettingOutlined />}>
                        保存
                      </Button>
                    </Form>
                  </Card>
                </Space>
              ),
            },
            {
              key: 'ai',
              label: 'AI 模型',
              children: (
                <Card title="解题 AI 配置" loading={loading}>
                  <Form form={aiForm} layout="vertical" onFinish={saveAiSettings}>
                    <Form.Item name="ai_provider" label="AI 提供商" rules={[{ required: true }]}>
                      <Radio.Group>
                        <Radio.Button value="ollama">本地 Ollama</Radio.Button>
                        <Radio.Button value="openai">OpenAI 兼容 API</Radio.Button>
                      </Radio.Group>
                    </Form.Item>
                    {(aiProvider || settings?.ai_provider) === 'ollama' && (
                      <>
                        <Form.Item name="ollama_base_url" label="Ollama 地址">
                          <Input placeholder="http://127.0.0.1:11434" />
                        </Form.Item>
                        <Form.Item name="ollama_model" label="Ollama 模型">
                          <Input placeholder="qwen2.5:7b" />
                        </Form.Item>
                      </>
                    )}
                    {(aiProvider || settings?.ai_provider) === 'openai' && (
                      <>
                        <Form.Item name="openai_base_url" label="API Base URL">
                          <Input placeholder="https://api.openai.com/v1" />
                        </Form.Item>
                        <Form.Item name="openai_model" label="模型名称">
                          <Input placeholder="gpt-4o-mini" />
                        </Form.Item>
                        <Form.Item
                          name="openai_api_key"
                          label="API Key"
                          extra={
                            settings?.openai_api_key_set
                              ? '已配置 Key，留空则不修改'
                              : '请输入 API Key'
                          }
                        >
                          <Input.Password placeholder="sk-..." />
                        </Form.Item>
                      </>
                    )}
                    <Form.Item
                      name="ocr_service_url"
                      label="OCR 服务地址（局域网 GPU 机器）"
                      extra="留空则在应用服务器本机 CPU 识别。同机部署时填 http://127.0.0.1:23567（install.sh 已自动配置）"
                    >
                      <Input placeholder="http://192.168.8.100:23567" />
                    </Form.Item>
                    <Typography.Paragraph type="secondary">
                      错题/奥数解法将按学生学段（初中/高中）生成，并严格禁止超纲解题。
                    </Typography.Paragraph>
                    <Form.Item label="AI 复盘解读">
                      <Space>
                        <Switch
                          checked={settings?.ai_review_enabled ?? true}
                          onChange={toggleAiReview}
                        />
                        <Typography.Text>
                          {settings?.ai_review_enabled !== false
                            ? '已开启：成绩复盘页可生成 AI 解读'
                            : '已关闭：成绩复盘页不调用 AI'}
                        </Typography.Text>
                      </Space>
                    </Form.Item>
                    <Button type="primary" htmlType="submit">
                      保存 AI 配置
                    </Button>
                  </Form>
                </Card>
              ),
            },
            {
              key: 'backup',
              label: '数据备份',
              children: (
                <Space direction="vertical" size="large" style={{ width: '100%' }}>
                  <Alert
                    type="info"
                    showIcon
                    message="自动备份"
                    description="系统默认每 24 小时自动备份到 /root/grade-archive-backups，并保留最近 30 天。更换服务器时可下载备份包，在新服务器上传恢复。"
                  />
                  <Card
                    title="备份管理"
                    extra={
                      <Button type="primary" loading={runningBackup} onClick={handleRunBackup}>
                        立即备份
                      </Button>
                    }
                  >
                    <Table
                      rowKey="filename"
                      loading={backupLoading}
                      dataSource={backups}
                      pagination={{ pageSize: 8 }}
                      locale={{ emptyText: '暂无备份，请点击「立即备份」' }}
                      columns={[
                        { title: '文件名', dataIndex: 'filename' },
                        {
                          title: '大小',
                          dataIndex: 'size_bytes',
                          render: (v: number) => formatBytes(v),
                        },
                        {
                          title: '时间',
                          dataIndex: 'created_at',
                          render: (v: string) => new Date(v).toLocaleString(),
                        },
                        {
                          title: '操作',
                          render: (_, record) => (
                            <Button
                              icon={<DownloadOutlined />}
                              onClick={() => handleDownloadBackup(record.filename)}
                            >
                              下载
                            </Button>
                          ),
                        },
                      ]}
                    />
                  </Card>
                  <Card title="数据恢复（迁移服务器）">
                    <Typography.Paragraph type="secondary">
                      上传此前下载的 <Typography.Text code>grade-archive_*.tar.gz</Typography.Text>{' '}
                      备份包。恢复会覆盖当前数据库与 uploads 目录，操作前请先备份。
                    </Typography.Paragraph>
                    <Upload beforeUpload={handleRestore} showUploadList={false} accept=".tar.gz,application/gzip">
                      <Button icon={<UploadOutlined />} loading={restoring} danger>
                        上传并恢复
                      </Button>
                    </Upload>
                  </Card>
                </Space>
              ),
            },
            {
              key: 'users',
              label: '用户管理',
              children: (
                <Card
                  title="用户列表"
                  extra={
                    <Button type="primary" onClick={() => setCreateOpen(true)}>
                      添加用户
                    </Button>
                  }
                >
                  <Table
                    rowKey="id"
                    loading={loading}
                    dataSource={users}
                    pagination={false}
                    columns={[
                      { title: '用户名', dataIndex: 'username' },
                      {
                        title: '角色',
                        dataIndex: 'is_superuser',
                        render: (v: boolean) => (v ? '超级管理员' : '普通用户'),
                      },
                      {
                        title: '创建时间',
                        dataIndex: 'created_at',
                        render: (v: string) => new Date(v).toLocaleString(),
                      },
                      {
                        title: '操作',
                        render: (_, record) =>
                          record.is_superuser ? (
                            <Typography.Text type="secondary">—</Typography.Text>
                          ) : (
                            <Space>
                              <Button size="small" onClick={() => setResetUser(record)}>
                                重置密码
                              </Button>
                              <Popconfirm title="确定删除该用户？" onConfirm={() => removeUser(record.id)}>
                                <Button size="small" danger>
                                  删除
                                </Button>
                              </Popconfirm>
                            </Space>
                          ),
                      },
                    ]}
                  />
                </Card>
              ),
            },
          ]}
        />
      </Space>

      <Modal
        title="添加用户"
        open={createOpen}
        onCancel={() => setCreateOpen(false)}
        onOk={() => createForm.submit()}
        destroyOnHidden
      >
        <Form form={createForm} layout="vertical" onFinish={createUser}>
          <Form.Item name="username" label="用户名" rules={[{ required: true, min: 3 }]}>
            <Input />
          </Form.Item>
          <Form.Item name="password" label="密码" rules={[{ required: true, min: 6 }]}>
            <Input.Password />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={`重置密码 — ${resetUser?.username}`}
        open={!!resetUser}
        onCancel={() => setResetUser(null)}
        onOk={() => resetForm.submit()}
        destroyOnHidden
      >
        <Form form={resetForm} layout="vertical" onFinish={resetPassword}>
          <Form.Item name="password" label="新密码" rules={[{ required: true, min: 6 }]}>
            <Input.Password />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  )
}
