import { useCallback, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import {
  ArrowLeftOutlined,
  LockOutlined,
  MailOutlined,
  MobileOutlined,
  SafetyOutlined,
  UserOutlined,
} from '@ant-design/icons'
import { Alert, Button, Form, Input, Result, Space, Typography, message } from 'antd'

import { AuthLayout } from '@/layouts'
import { getErrorMessage, isFormValidationError } from '@/lib/errors'
import { getAuthCapabilities, register, sendSmsCode } from '@/services/auth'
import type { AuthCapabilities, RegisterResponse } from '@/types'

const { Paragraph, Text, Title } = Typography

const COUNTDOWN_SECONDS = 60
const DEFAULT_CAPABILITIES: AuthCapabilities = {
  password: true,
  email_activation: false,
  email_code: false,
  sms_code: false,
  password_reset: false,
  admin_bootstrap_required: false,
  oauth_providers: [],
}

type RegisterFormValues = {
  username: string
  nickname?: string
  email?: string
  phone?: string
  phoneCode?: string
  password: string
  confirmPassword: string
}

function buildRegisterSummary(result: RegisterResponse) {
  if (result.user.status === 0) {
    if (result.user.email) {
      return `账号已创建，激活邮件会发送到 ${result.user.email}。请完成激活后再登录。`
    }
    return '账号已创建，请按页面提示完成激活后再登录。'
  }

  return '账号已创建，现在可以返回登录页使用新账号登录。'
}

export function RegisterPage() {
  const [form] = Form.useForm<RegisterFormValues>()
  const [loading, setLoading] = useState(false)
  const [smsCountdown, setSmsCountdown] = useState(0)
  const [capabilities, setCapabilities] = useState<AuthCapabilities>(DEFAULT_CAPABILITIES)
  const [capabilitiesLoaded, setCapabilitiesLoaded] = useState(false)
  const [submitted, setSubmitted] = useState<RegisterResponse | null>(null)

  useEffect(() => {
    if (smsCountdown <= 0) {
      return
    }

    const timer = window.setTimeout(() => setSmsCountdown((current) => current - 1), 1000)
    return () => window.clearTimeout(timer)
  }, [smsCountdown])

  useEffect(() => {
    let cancelled = false

    const loadCapabilities = async () => {
      try {
        const result = await getAuthCapabilities()
        if (!cancelled) {
          setCapabilities(result)
        }
      } catch {
        if (!cancelled) {
          setCapabilities(DEFAULT_CAPABILITIES)
        }
      } finally {
        if (!cancelled) {
          setCapabilitiesLoaded(true)
        }
      }
    }

    void loadCapabilities()

    return () => {
      cancelled = true
    }
  }, [])

  const handleSendSmsCode = useCallback(async () => {
    try {
      const values = await form.validateFields(['phone'])
      const phone = values.phone?.trim()
      if (!phone) {
        return
      }

      setSmsCountdown(COUNTDOWN_SECONDS)
      await sendSmsCode({ phone, purpose: 'register' })
      message.success('验证码已发送到手机')
    } catch (error) {
      setSmsCountdown(0)
      if (isFormValidationError(error)) {
        return
      }
      message.error(getErrorMessage(error, '发送验证码失败'))
    }
  }, [form])

  const handleSubmit = useCallback(async (values: RegisterFormValues) => {
    setLoading(true)
    try {
      const phone = capabilities.sms_code ? values.phone?.trim() || undefined : undefined
      const result = await register({
        username: values.username.trim(),
        password: values.password,
        nickname: values.nickname?.trim() || undefined,
        email: values.email?.trim() || undefined,
        phone,
        phone_code: phone ? values.phoneCode?.trim() || undefined : undefined,
      })
      form.resetFields()
      setSmsCountdown(0)
      setSubmitted(result)
      message.success(result.user.status === 0 ? '注册成功，请完成邮箱激活' : '注册成功')
    } catch (error) {
      message.error(getErrorMessage(error, '注册失败，请检查输入信息后重试'))
    } finally {
      setLoading(false)
    }
  }, [capabilities.sms_code, form])

  if (submitted) {
    const activationEmail = submitted.user.email?.trim()

    return (
      <AuthLayout>
        <Result
          status="success"
          title="注册成功"
          subTitle={(
            <Paragraph>
              <Text strong>{submitted.user.username}</Text>
              {' '}
              {buildRegisterSummary(submitted)}
            </Paragraph>
          )}
          extra={[
            <Link key="login" to="/login">
              <Button type="primary">返回登录</Button>
            </Link>,
            submitted.user.status === 0 && activationEmail && capabilities.email_activation ? (
              <Link key="activation" to={`/activate-account?email=${encodeURIComponent(activationEmail)}`}>
                <Button>重新发送激活邮件</Button>
              </Link>
            ) : null,
          ]}
        />
      </AuthLayout>
    )
  }

  return (
    <AuthLayout>
      <Title level={3} style={{ marginBottom: 8 }}>
        创建账号
      </Title>
      <Paragraph type="secondary" style={{ marginBottom: 24 }}>
        {capabilitiesLoaded
          ? capabilities.sms_code
            ? '支持用户名注册；填写手机号时需要先完成短信验证码校验。'
            : '支持用户名和邮箱注册；当前环境未启用短信能力，因此手机号注册暂不可用。'
          : '填写基础信息后即可创建账号。'}
      </Paragraph>

      {capabilities.admin_bootstrap_required && (
        <Alert
          type="warning"
          showIcon
          message="当前仍需管理员初始化"
          description="自助注册不会创建首个管理员账号。如需进入后台管理，请先完成管理员初始化。"
          action={(
            <Link to="/bootstrap-admin">
              <Button size="small" type="primary">初始化管理员</Button>
            </Link>
          )}
          style={{ marginBottom: 24 }}
        />
      )}

      <Form<RegisterFormValues> form={form} layout="vertical" onFinish={handleSubmit} autoComplete="off">
        <Form.Item
          name="username"
          rules={[{ required: true, message: '请输入用户名' }]}
        >
          <Input
            prefix={<UserOutlined />}
            placeholder="用户名"
            size="large"
            autoComplete="username"
          />
        </Form.Item>
        <Form.Item name="nickname">
          <Input
            prefix={<UserOutlined />}
            placeholder="昵称（选填）"
            size="large"
            autoComplete="nickname"
          />
        </Form.Item>
        <Form.Item
          name="email"
          rules={[
            { type: 'email', message: '请输入有效的邮箱地址' },
          ]}
        >
          <Input
            prefix={<MailOutlined />}
            placeholder="邮箱地址（选填）"
            size="large"
            autoComplete="email"
          />
        </Form.Item>

        {capabilities.sms_code && (
          <>
            <Form.Item
              name="phone"
              rules={[
                { pattern: /^$|^1\d{10}$/, message: '请输入有效的手机号' },
              ]}
            >
              <Input
                prefix={<MobileOutlined />}
                placeholder="手机号（选填）"
                size="large"
                autoComplete="tel"
              />
            </Form.Item>
            <Form.Item
              name="phoneCode"
              dependencies={['phone']}
              rules={[
                ({ getFieldValue }) => ({
                  validator(_, value) {
                    const phone = String(getFieldValue('phone') ?? '').trim()
                    if (!phone) {
                      return Promise.resolve()
                    }
                    if (/^\d{6}$/.test(String(value ?? '').trim())) {
                      return Promise.resolve()
                    }
                    return Promise.reject(new Error('请输入 6 位短信验证码'))
                  },
                }),
              ]}
            >
              <Space.Compact style={{ width: '100%' }}>
                <Input
                  prefix={<SafetyOutlined />}
                  placeholder="短信验证码"
                  size="large"
                  maxLength={6}
                  style={{ flex: 1 }}
                />
                <Button
                  size="large"
                  disabled={smsCountdown > 0}
                  onClick={() => void handleSendSmsCode()}
                  style={{ width: 120 }}
                >
                  {smsCountdown > 0 ? `${smsCountdown}s` : '获取验证码'}
                </Button>
              </Space.Compact>
            </Form.Item>
          </>
        )}

        <Form.Item
          name="password"
          rules={[{ required: true, message: '请输入密码' }]}
        >
          <Input.Password
            prefix={<LockOutlined />}
            placeholder="密码"
            size="large"
            autoComplete="new-password"
          />
        </Form.Item>
        <Form.Item
          name="confirmPassword"
          dependencies={['password']}
          rules={[
            { required: true, message: '请再次输入密码' },
            ({ getFieldValue }) => ({
              validator(_, value) {
                if (!value || getFieldValue('password') === value) {
                  return Promise.resolve()
                }
                return Promise.reject(new Error('两次输入的密码不一致'))
              },
            }),
          ]}
        >
          <Input.Password
            prefix={<LockOutlined />}
            placeholder="确认密码"
            size="large"
            autoComplete="new-password"
          />
        </Form.Item>
        <Form.Item>
          <Button type="primary" htmlType="submit" size="large" block loading={loading}>
            创建账号
          </Button>
        </Form.Item>
      </Form>

      <div style={{ textAlign: 'center', marginTop: 16 }}>
        <Space split={<Text type="secondary">|</Text>}>
          <Link to="/login">
            <Text type="secondary">
              <ArrowLeftOutlined style={{ marginRight: 4 }} />
              返回登录
            </Text>
          </Link>
          {capabilities.password_reset && (
            <Link to="/forgot-password">
              <Text type="secondary">忘记密码？</Text>
            </Link>
          )}
        </Space>
      </div>
    </AuthLayout>
  )
}
