import { useEffect, useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Alert, Button, Card, Form, Input, Result, Select, Space, Spin, Typography, message } from 'antd'
import { initApi } from '@/lib/api'
import { useAuthStore } from '@/store/auth'
import type { InitCheckResult, InitDBPayload } from '@/types/system'

const dbTypeOptions: Array<{ label: string; value: InitDBPayload['dbType'] }> = [
  { label: 'MySQL', value: 'mysql' },
  { label: 'PostgreSQL', value: 'pgsql' },
  { label: 'SQLite', value: 'sqlite' },
  { label: 'MSSQL', value: 'mssql' },
]

type InitState = 'checking' | 'required' | 'ready'

const dbDefaults: Record<InitDBPayload['dbType'], Partial<InitDBPayload>> = {
  mysql: {
    host: '127.0.0.1',
    port: '3306',
  },
  pgsql: {
    host: '127.0.0.1',
    port: '5432',
    template: 'template1',
  },
  sqlite: {
    dbPath: 'db',
  },
  mssql: {
    host: '127.0.0.1',
    port: '1433',
  },
}

function applyDbDefaults(currentValues: InitDBPayload, nextDbType: InitDBPayload['dbType']): InitDBPayload {
  return {
    ...currentValues,
    ...dbDefaults[nextDbType],
    dbType: nextDbType,
  }
}

export function InitPage() {
  const navigate = useNavigate()
  const token = useAuthStore((state) => state.token)
  const [form] = Form.useForm<InitDBPayload>()
  const [state, setState] = useState<InitState>('checking')
  const [checkingError, setCheckingError] = useState<string | null>(null)
  const [submitting, setSubmitting] = useState(false)
  const dbType = Form.useWatch('dbType', form) ?? 'mysql'

  const checkInitialization = async () => {
    try {
      const response = await initApi.checkDB()
      const data: InitCheckResult = response.data

      if (data.needInit) {
        setState('required')
      } else {
        setState('ready')
      }
      setCheckingError(null)
    } catch (error) {
      const messageText = error instanceof Error ? error.message : '初始化状态检测失败'
      setCheckingError(messageText)
    }
  }

  useEffect(() => {
    void checkInitialization()
  }, [])

  const helperText = useMemo(() => {
    switch (dbType) {
      case 'mysql':
        return '将创建数据库并写回 MySQL 连接配置。'
      case 'pgsql':
        return '默认使用 PostgreSQL 公共库建库，可按需指定 template。'
      case 'sqlite':
        return '将创建本地 SQLite 数据库文件，并写回 sqlite 配置。'
      case 'mssql':
        return '将按当前连接信息接入 MSSQL，并写回 mssql 配置。'
      default:
        return ''
    }
  }, [dbType])

  const onDbTypeChange = (nextDbType: InitDBPayload['dbType']) => {
    const currentValues = form.getFieldsValue()
    form.setFieldsValue(applyDbDefaults(currentValues, nextDbType))
  }

  const submit = async () => {
    const values = await form.validateFields()
    setSubmitting(true)
    try {
      await initApi.initDB(values)
      message.success('初始化完成，请使用 admin 账户登录')
      navigate('/login', { replace: true })
    } finally {
      setSubmitting(false)
    }
  }

  if (state === 'checking') {
    return (
      <div className="login-shell">
        <section className="login-hero">
          <span className="capsule">Project Bootstrap</span>
          <div style={{ maxWidth: 620, marginTop: 72 }}>
            <Typography.Title style={{ color: 'rgba(255,255,255,0.96)', fontSize: 52, marginBottom: 18 }}>
              正在检测
              <br />
              项目初始化状态
            </Typography.Title>
            <Typography.Paragraph style={{ color: 'rgba(255,255,255,0.78)', fontSize: 18, lineHeight: 1.8 }}>
              初始化页只在数据库尚未建立、配置尚未回写时使用。检测完成后会自动切换到对应状态。
            </Typography.Paragraph>
          </div>
        </section>
        <section className="login-form-wrap">
          <Card className="glass-panel login-card" bordered={false}>
            <div className="fullscreen-status" style={{ minHeight: 360 }}>
              <Spin size="large" />
              <span>正在检测初始化状态...</span>
              {checkingError ? (
                <Alert
                  type="warning"
                  showIcon
                  message="检测失败"
                  description={checkingError}
                  action={
                    <Button size="small" onClick={() => void checkInitialization()}>
                      重试
                    </Button>
                  }
                />
              ) : null}
            </div>
          </Card>
        </section>
      </div>
    )
  }

  if (state === 'ready') {
    return (
      <div className="login-shell">
        <section className="login-hero">
          <span className="capsule">Project Bootstrap</span>
          <div style={{ maxWidth: 620, marginTop: 72 }}>
            <Typography.Title style={{ color: 'rgba(255,255,255,0.96)', fontSize: 52, marginBottom: 18 }}>
              项目已经完成
              <br />
              首次初始化
            </Typography.Title>
            <Typography.Paragraph style={{ color: 'rgba(255,255,255,0.78)', fontSize: 18, lineHeight: 1.8 }}>
              当前服务已经具备数据库连接和基础管理员账号，不需要再次执行初始化。
            </Typography.Paragraph>
          </div>
        </section>
        <section className="login-form-wrap">
          <Card className="glass-panel login-card" bordered={false}>
            <Result
              status="success"
              title="无需再次初始化"
              subTitle="如果需要调整系统配置，请登录后台后在系统配置页修改。"
              extra={[
                <Button key="login" type="primary" onClick={() => navigate(token ? '/' : '/login', { replace: true })}>
                  {token ? '进入后台' : '前往登录'}
                </Button>,
                <Button key="check" onClick={() => void checkInitialization()}>
                  重新检测
                </Button>,
              ]}
            />
          </Card>
        </section>
      </div>
    )
  }

  return (
    <div className="login-shell">
      <section className="login-hero">
        <span className="capsule">Project Bootstrap</span>
        <div style={{ maxWidth: 620, marginTop: 72 }}>
          <Typography.Title style={{ color: 'rgba(255,255,255,0.96)', fontSize: 52, marginBottom: 18 }}>
            首次启动先完成
            <br />
            项目初始化
          </Typography.Title>
          <Typography.Paragraph style={{ color: 'rgba(255,255,255,0.78)', fontSize: 18, lineHeight: 1.8 }}>
            这里负责创建主业务数据库、写回当前服务配置，并生成默认管理员账号。初始化完成后，再进入后台登录。
          </Typography.Paragraph>
        </div>
      </section>
      <section className="login-form-wrap">
        <Card className="glass-panel login-card" bordered={false}>
          <Typography.Title level={2} style={{ marginBottom: 8 }}>
            初始化项目
          </Typography.Title>
          <Typography.Paragraph className="text-muted" style={{ marginBottom: 20 }}>
            默认管理员账号固定为 `admin`，密码使用下面填写的管理员密码。
          </Typography.Paragraph>
          {checkingError ? (
            <Alert
              type="warning"
              showIcon
              message="状态检测存在异常"
              description={checkingError}
              style={{ marginBottom: 16 }}
            />
          ) : null}
          <Form
            form={form}
            layout="vertical"
            initialValues={{
              adminPassword: '',
              dbType: 'mysql',
              host: '127.0.0.1',
              port: '3306',
              dbName: 'go_web_template',
              userName: 'root',
              dbPath: 'db',
              template: 'template1',
            }}
            onFinish={submit}
          >
            <Form.Item name="dbType" label="数据库类型" rules={[{ required: true, message: '请选择数据库类型' }]}>
              <Select options={dbTypeOptions} onChange={onDbTypeChange} />
            </Form.Item>
            <Typography.Paragraph className="text-muted" style={{ marginTop: -8, marginBottom: 16 }}>
              {helperText}
            </Typography.Paragraph>
            <div className="init-form-grid">
              {dbType === 'sqlite' ? (
                <Form.Item
                  name="dbPath"
                  label="数据库目录"
                  rules={[{ required: true, message: '请输入 SQLite 数据库目录' }]}
                >
                  <Input placeholder="例如 db" />
                </Form.Item>
              ) : (
                <>
                  <Form.Item name="host" label="数据库地址" rules={[{ required: true, message: '请输入数据库地址' }]}>
                    <Input placeholder="例如 127.0.0.1" />
                  </Form.Item>
                  <Form.Item name="port" label="数据库端口" rules={[{ required: true, message: '请输入数据库端口' }]}>
                    <Input placeholder="例如 3306" />
                  </Form.Item>
                  <Form.Item
                    name="userName"
                    label="数据库用户名"
                    rules={[{ required: true, message: '请输入数据库用户名' }]}
                  >
                    <Input placeholder="例如 root" />
                  </Form.Item>
                  <Form.Item name="password" label="数据库密码">
                    <Input.Password placeholder="请输入数据库密码" />
                  </Form.Item>
                </>
              )}
              <Form.Item name="dbName" label="数据库名" rules={[{ required: true, message: '请输入数据库名' }]}>
                <Input placeholder={dbType === 'sqlite' ? '例如 go_web_template' : '例如 go_web_template'} />
              </Form.Item>
              {dbType === 'pgsql' ? (
                <Form.Item name="template" label="建库模板">
                  <Input placeholder="默认 template1" />
                </Form.Item>
              ) : (
                <div />
              )}
              <Form.Item
                name="adminPassword"
                label="管理员密码"
                rules={[
                  { required: true, message: '请输入管理员密码' },
                  { min: 6, message: '管理员密码至少 6 位' },
                ]}
              >
                <Input.Password placeholder="初始化后 admin 账户使用此密码登录" />
              </Form.Item>
            </div>
            <Alert
              type="info"
              showIcon
              style={{ marginBottom: 20 }}
              message="初始化完成后，后端会立即持有数据库连接，并将连接配置写回当前配置文件。"
            />
            <Space wrap>
              <Button type="primary" htmlType="submit" loading={submitting}>
                开始初始化
              </Button>
              <Button onClick={() => void checkInitialization()}>重新检测</Button>
              <Button onClick={() => navigate('/login', { replace: true })}>返回登录页</Button>
            </Space>
          </Form>
        </Card>
      </section>
    </div>
  )
}
