import { useCallback, useEffect, useState } from 'react'
import {
  Alert,
  Button,
  Col,
  Form,
  Input,
  Modal,
  Row,
  Space,
  Tag,
  Typography,
  message,
} from 'antd'
import { MailOutlined, PhoneOutlined } from '@ant-design/icons'

import { ContentCard } from '@/components/layout'
import { getErrorMessage } from '@/lib/errors'
import {
  bindEmail,
  bindPhone,
  sendEmailBindCode,
  sendPhoneBindCode,
  unbindEmail,
  unbindPhone,
} from '@/services/account-bindings'
import { getCurrentProfile, type CurrentUserProfile } from '@/services/profile'

const { Text } = Typography

type BindingChannel = 'email' | 'phone'

interface BindFormValues {
  email?: string
  phone?: string
  code?: string
  current_password?: string
  totp_code?: string
}

interface UnbindFormValues {
  current_password?: string
  totp_code?: string
}

interface ContactBindingsSectionProps {
  userId: number
  emailBindingEnabled: boolean
  phoneBindingEnabled: boolean
  refreshSessionUser: () => Promise<void>
}

function getChannelLabel(channel: BindingChannel): string {
  return channel === 'email' ? '邮箱' : '手机号'
}

function maskEmail(value: string): string {
  const [localPart, domain] = value.split('@')
  if (!localPart || !domain) {
    return value
  }
  if (localPart.length <= 2) {
    return `${localPart[0] ?? ''}***@${domain}`
  }
  return `${localPart.slice(0, 2)}***@${domain}`
}

function maskPhone(value: string): string {
  if (value.length <= 7) {
    return value
  }
  return `${value.slice(0, 3)}****${value.slice(-4)}`
}

export function ContactBindingsSection({
  userId,
  emailBindingEnabled,
  phoneBindingEnabled,
  refreshSessionUser,
}: ContactBindingsSectionProps) {
  const [bindForm] = Form.useForm<BindFormValues>()
  const [unbindForm] = Form.useForm<UnbindFormValues>()
  const [profile, setProfile] = useState<CurrentUserProfile | null>(null)
  const [loading, setLoading] = useState(true)
  const [bindVisible, setBindVisible] = useState(false)
  const [unbindVisible, setUnbindVisible] = useState(false)
  const [bindSubmitting, setBindSubmitting] = useState(false)
  const [unbindSubmitting, setUnbindSubmitting] = useState(false)
  const [sendCodeLoading, setSendCodeLoading] = useState(false)
  const [activeChannel, setActiveChannel] = useState<BindingChannel | null>(null)

  const fetchProfile = useCallback(async () => {
    try {
      setLoading(true)
      const nextProfile = await getCurrentProfile(userId)
      setProfile(nextProfile)
    } catch (error) {
      message.error(getErrorMessage(error, '获取账号绑定状态失败'))
    } finally {
      setLoading(false)
    }
  }, [userId])

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

  const refreshAll = useCallback(async () => {
    await Promise.all([fetchProfile(), refreshSessionUser()])
  }, [fetchProfile, refreshSessionUser])

  const openBindModal = (channel: BindingChannel) => {
    setActiveChannel(channel)
    bindForm.resetFields()
    setBindVisible(true)
  }

  const openUnbindModal = (channel: BindingChannel) => {
    setActiveChannel(channel)
    unbindForm.resetFields()
    setUnbindVisible(true)
  }

  const closeBindModal = () => {
    setBindVisible(false)
    setActiveChannel(null)
    bindForm.resetFields()
  }

  const closeUnbindModal = () => {
    setUnbindVisible(false)
    setActiveChannel(null)
    unbindForm.resetFields()
  }

  const handleSendCode = async () => {
    if (!activeChannel) {
      return
    }

    try {
      setSendCodeLoading(true)
      if (activeChannel === 'email') {
        const values = await bindForm.validateFields(['email'])
        await sendEmailBindCode({ email: String(values.email).trim() })
      } else {
        const values = await bindForm.validateFields(['phone'])
        await sendPhoneBindCode({ phone: String(values.phone).trim() })
      }
      message.success(`${getChannelLabel(activeChannel)}验证码已发送`)
    } catch (error) {
      message.error(getErrorMessage(error, `发送${getChannelLabel(activeChannel)}验证码失败`))
    } finally {
      setSendCodeLoading(false)
    }
  }

  const handleBind = async (values: BindFormValues) => {
    if (!activeChannel) {
      return
    }

    try {
      setBindSubmitting(true)
      const verification = {
        current_password: values.current_password?.trim() || undefined,
        totp_code: values.totp_code?.trim() || undefined,
      }

      if (activeChannel === 'email') {
        await bindEmail({
          email: values.email?.trim() || '',
          code: values.code?.trim() || '',
          ...verification,
        })
      } else {
        await bindPhone({
          phone: values.phone?.trim() || '',
          code: values.code?.trim() || '',
          ...verification,
        })
      }

      message.success(`${getChannelLabel(activeChannel)}已更新`)
      closeBindModal()
      await refreshAll()
    } catch (error) {
      message.error(getErrorMessage(error, `${getChannelLabel(activeChannel)}绑定失败`))
    } finally {
      setBindSubmitting(false)
    }
  }

  const handleUnbind = async (values: UnbindFormValues) => {
    if (!activeChannel) {
      return
    }

    try {
      setUnbindSubmitting(true)
      const verification = {
        current_password: values.current_password?.trim() || undefined,
        totp_code: values.totp_code?.trim() || undefined,
      }

      if (activeChannel === 'email') {
        await unbindEmail(verification)
      } else {
        await unbindPhone(verification)
      }

      message.success(`${getChannelLabel(activeChannel)}已解绑`)
      closeUnbindModal()
      await refreshAll()
    } catch (error) {
      message.error(getErrorMessage(error, `${getChannelLabel(activeChannel)}解绑失败`))
    } finally {
      setUnbindSubmitting(false)
    }
  }

  const renderBindingCard = (channel: BindingChannel) => {
    const isEmail = channel === 'email'
    const label = getChannelLabel(channel)
    const value = isEmail ? profile?.user.email || '' : profile?.user.phone || ''
    const isBound = value !== ''
    const bindingEnabled = isEmail ? emailBindingEnabled : phoneBindingEnabled
    const displayValue = isEmail ? maskEmail(value) : maskPhone(value)

    return (
      <div
        style={{
          border: '1px solid #f0f0f0',
          borderRadius: 12,
          padding: 16,
          height: '100%',
          background: '#fff',
        }}
      >
        <Space direction="vertical" size={12} style={{ width: '100%' }}>
          <Space wrap>
            {isEmail ? <MailOutlined /> : <PhoneOutlined />}
            <Text strong>{label}</Text>
            <Tag color={isBound ? 'success' : 'default'}>{isBound ? '已绑定' : '未绑定'}</Tag>
            {!bindingEnabled && <Tag color="warning">验证码通道未启用</Tag>}
          </Space>

          <div>
            <Text type="secondary">当前{label}</Text>
            <div style={{ marginTop: 4 }}>
              <Text>{isBound ? displayValue : '未绑定'}</Text>
            </div>
          </div>

          <Text type="secondary">
            {bindingEnabled
              ? `绑定或更换${label}时，系统会校验新${label}验证码以及当前账号身份。`
              : `当前环境未启用${label}验证码通道，暂不可发起绑定或更换。`}
          </Text>

          <Space wrap>
            <Button type="primary" disabled={!bindingEnabled} onClick={() => openBindModal(channel)}>
              {isBound ? `更换${label}` : `绑定${label}`}
            </Button>
            {isBound && (
              <Button danger onClick={() => openUnbindModal(channel)}>
                {`解绑${label}`}
              </Button>
            )}
          </Space>
        </Space>
      </div>
    )
  }

  return (
    <>
      <ContentCard title="邮箱 / 手机号绑定" style={{ marginTop: 24 }}>
        <Space direction="vertical" size={16} style={{ width: '100%' }}>
          <Alert
            type="info"
            showIcon
            message="邮箱和手机号属于账号登录方式管理。绑定或更换需要验证码和当前账号验证，解绑会校验当前账号身份并保留至少一种登录方式。"
          />

          {loading ? (
            <Text type="secondary">正在加载账号绑定状态...</Text>
          ) : (
            <Row gutter={[16, 16]}>
              <Col xs={24} xl={12}>
                {renderBindingCard('email')}
              </Col>
              <Col xs={24} xl={12}>
                {renderBindingCard('phone')}
              </Col>
            </Row>
          )}
        </Space>
      </ContentCard>

      <Modal
        title={activeChannel ? `确认${getChannelLabel(activeChannel)}绑定` : '确认绑定'}
        open={bindVisible}
        onCancel={closeBindModal}
        onOk={() => bindForm.submit()}
        confirmLoading={bindSubmitting}
        okText="确认绑定"
      >
        <Space direction="vertical" style={{ width: '100%' }}>
          <Alert
            type="info"
            showIcon
            message={activeChannel ? `请先发送${getChannelLabel(activeChannel)}验证码，再输入当前账号密码或 TOTP 完成验证。` : ''}
          />
          <Form form={bindForm} layout="vertical" onFinish={handleBind}>
            {activeChannel === 'email' ? (
              <Form.Item
                name="email"
                label="新邮箱"
                rules={[
                  { required: true, message: '请输入新邮箱' },
                  { type: 'email', message: '请输入有效的邮箱地址' },
                ]}
              >
                <Input placeholder="请输入新邮箱" />
              </Form.Item>
            ) : (
              <Form.Item
                name="phone"
                label="新手机号"
                rules={[
                  { required: true, message: '请输入新手机号' },
                  {
                    pattern: /^\+?[1-9]\d{6,14}$/,
                    message: '请输入符合 E.164 的手机号',
                  },
                ]}
              >
                <Input placeholder="例如：+8613800138000" />
              </Form.Item>
            )}

            <Form.Item
              name="code"
              label="验证码"
              rules={[{ required: true, message: '请输入验证码' }]}
            >
              <Input
                placeholder="请输入验证码"
                addonAfter={
                  <Button type="link" size="small" loading={sendCodeLoading} onClick={handleSendCode}>
                    发送验证码
                  </Button>
                }
              />
            </Form.Item>

            <Form.Item name="current_password" label="当前密码">
              <Input.Password placeholder="建议填写当前密码" />
            </Form.Item>
            <Form.Item name="totp_code" label="TOTP / 恢复码">
              <Input placeholder="已开启 TOTP 时可填写验证码或恢复码" />
            </Form.Item>
          </Form>
        </Space>
      </Modal>

      <Modal
        title={activeChannel ? `确认解绑${getChannelLabel(activeChannel)}` : '确认解绑'}
        open={unbindVisible}
        onCancel={closeUnbindModal}
        onOk={() => unbindForm.submit()}
        confirmLoading={unbindSubmitting}
        okText="确认解绑"
        okButtonProps={{ danger: true }}
      >
        <Space direction="vertical" style={{ width: '100%' }}>
          <Alert
            type="warning"
            showIcon
            message={activeChannel ? `解绑${getChannelLabel(activeChannel)}前，需要验证当前账号身份；如果解绑后没有其他登录方式，系统会拒绝本次操作。` : ''}
          />
          <Form form={unbindForm} layout="vertical" onFinish={handleUnbind}>
            <Form.Item name="current_password" label="当前密码">
              <Input.Password placeholder="填写当前密码" />
            </Form.Item>
            <Form.Item name="totp_code" label="TOTP / 恢复码">
              <Input placeholder="或填写 TOTP 验证码 / 恢复码" />
            </Form.Item>
          </Form>
        </Space>
      </Modal>
    </>
  )
}
