import { Image, Input, Text, View } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro'
import { useEffect, useState } from 'react'
import { AgreementModal, BottomDrawer, Page } from '@/components/ui'
import { backend, BRAND_LOGO_URL, BRAND_NAME, mapUser } from '@/api/backend'
import { getToken, getUser, saveToken, saveUser } from '@/stores/storage'
import { tapMedium } from '@/utils/feedback'
import { safeMiniappPath, toast } from '@/utils/nav'
import { DEBUG_CODE, DEBUG_PHONE, isAuthDebugEnabled, TEMP_AUTH_DEV_BYPASS } from '@/utils/dev-auth'

export default function LoginPage() {
  const [redirect, setRedirect] = useState('/pages/home/index')
  const [pcSessionId, setPcSessionId] = useState('')
  const [agreed, setAgreed] = useState(false)
  const [agreementTitle, setAgreementTitle] = useState('')
  const [loggingIn, setLoggingIn] = useState(false)
  const [loaded, setLoaded] = useState(false)
  const [debugMode, setDebugMode] = useState(TEMP_AUTH_DEV_BYPASS)
  const [phoneDrawerOpen, setPhoneDrawerOpen] = useState(false)
  const [phoneLoginStep, setPhoneLoginStep] = useState<'phone' | 'code'>('phone')
  const [phoneLoginPhone, setPhoneLoginPhone] = useState('')
  const [phoneLoginCode, setPhoneLoginCode] = useState('')
  const [phoneLoginSending, setPhoneLoginSending] = useState(false)
  const [phoneLoginSubmitting, setPhoneLoginSubmitting] = useState(false)

  useLoad((query) => {
    setRedirect(query.redirect ? safeMiniappPath(decodeURIComponent(String(query.redirect))) : '/pages/home/index')
    const scene = query.scene ? decodeURIComponent(String(query.scene)) : ''
    const sessionFromScene = scene.startsWith('pc_') ? scene.replace(/^pc_/, '') : ''
    setPcSessionId(String(query.pcSessionId || query.pc_session_id || sessionFromScene || ''))
    setDebugMode(isAuthDebugEnabled(query.debug))
    setLoaded(true)
  })

  useEffect(() => {
    if (!loaded || !pcSessionId) return
    void backend.markPcScanLoginScanned(pcSessionId).catch(() => undefined)
  }, [loaded, pcSessionId])

  useEffect(() => {
    if (!loaded) return
    if (debugMode) return
    const user = getUser()
    if (!user) return
    if (pcSessionId) {
      const token = getToken()
      if (!token || !user.phone) return
      void backend.preparePcScanLogin(token, pcSessionId).catch(() => undefined)
      if (user.onboardingCompleted) {
        Taro.navigateTo({ url: `/pages/auth/pc-confirm/index?sessionId=${encodeURIComponent(pcSessionId)}` })
        return
      }
      Taro.navigateTo({ url: `/pages/auth/onboarding/index?redirect=${encodeURIComponent(redirect)}&pcSessionId=${encodeURIComponent(pcSessionId)}` })
      return
    }
    if (user.onboardingCompleted) {
      Taro.reLaunch({ url: '/pages/home/index' })
      return
    }
    Taro.navigateTo({ url: `/pages/auth/onboarding/index?redirect=${encodeURIComponent(redirect)}` })
  }, [debugMode, loaded, pcSessionId, redirect])

  function ensureAgreement() {
    tapMedium()
    if (!agreed) {
      toast('请先阅读并同意用户协议')
      return false
    }
    return true
  }

  async function loginWithWechat() {
    if (debugMode) {
      enterDebugPhone()
      return
    }
    if (!ensureAgreement()) return
    setLoggingIn(true)
    try {
      const wxLogin = await Taro.login()
      if (!wxLogin.code) throw new Error('微信登录失败，请重试')
      const result = await backend.miniappWechatLogin(wxLogin.code, pcSessionId)
      if (result.token && result.user) {
        saveToken(result.token)
        saveUser(mapUser(result.user))
      }

      const pcQuery = pcSessionId ? `&pcSessionId=${encodeURIComponent(pcSessionId)}` : ''
      if (result.nextAction === 'bind_phone') {
        Taro.navigateTo({ url: `/pages/auth/bind-phone/index?redirect=${encodeURIComponent(redirect)}&miniappSessionToken=${encodeURIComponent(result.miniappSessionToken)}${pcQuery}` })
        return
      }
      if (result.nextAction === 'complete_profile') {
        Taro.navigateTo({ url: `/pages/auth/onboarding/index?redirect=${encodeURIComponent(redirect)}${pcQuery}` })
        return
      }
      if (pcSessionId) {
        Taro.navigateTo({ url: `/pages/auth/pc-confirm/index?sessionId=${encodeURIComponent(pcSessionId)}` })
        return
      }
      Taro.reLaunch({ url: redirect.startsWith('/pages/account') ? '/pages/account/index' : safeMiniappPath(redirect) })
    } catch (error) {
      toast(error instanceof Error ? error.message : '微信登录失败')
    } finally {
      setLoggingIn(false)
    }
  }

  function openPhoneLogin() {
    tapMedium()
    if (!debugMode && !agreed) {
      toast('请先阅读并同意用户协议')
      return
    }
    setPhoneLoginStep('phone')
    setPhoneLoginPhone('')
    setPhoneLoginCode('')
    setPhoneDrawerOpen(true)
  }

  function enterDebugPhone() {
    const pcQuery = pcSessionId ? `&pcSessionId=${encodeURIComponent(pcSessionId)}` : ''
    Taro.navigateTo({ url: `/pages/auth/bind-phone/index?debug=1&redirect=${encodeURIComponent(redirect)}${pcQuery}` })
  }

  function enterDebugOnboarding() {
    saveToken('debug-miniapp-token')
    saveUser({
      id: 'debug-user',
      name: '',
      phone: DEBUG_PHONE,
      authProvider: 'phone',
      onboardingCompleted: false,
      membershipLevel: 0
    })
    const pcQuery = pcSessionId ? `&pcSessionId=${encodeURIComponent(pcSessionId)}` : ''
    Taro.navigateTo({ url: `/pages/auth/onboarding/index?debug=1&redirect=${encodeURIComponent(redirect)}${pcQuery}` })
  }

  function previewPcConfirm() {
    tapMedium()
    Taro.navigateTo({ url: `/pages/auth/pc-confirm/index?preview=1&sessionId=preview-pc-login&region=${encodeURIComponent('中国大陆')}&device=${encodeURIComponent('Windows 电脑')}&browser=${encodeURIComponent('Chrome 浏览器')}` })
  }

  function openAgreement(title: string, event: { stopPropagation: () => void }) {
    event.stopPropagation()
    tapMedium()
    setAgreementTitle(title)
  }

  function routeAfterPhoneLogin(user: ReturnType<typeof mapUser>, token = '') {
    const pcQuery = pcSessionId ? `&pcSessionId=${encodeURIComponent(pcSessionId)}` : ''
    if (pcSessionId && token) void backend.preparePcScanLogin(token, pcSessionId).catch(() => undefined)
    if (!user.onboardingCompleted) {
      Taro.navigateTo({ url: `/pages/auth/onboarding/index?redirect=${encodeURIComponent(redirect)}${pcQuery}` })
      return
    }
    if (pcSessionId) {
      Taro.navigateTo({ url: `/pages/auth/pc-confirm/index?sessionId=${encodeURIComponent(pcSessionId)}` })
      return
    }
    Taro.reLaunch({ url: redirect.startsWith('/pages/account') ? '/pages/account/index' : safeMiniappPath(redirect) })
  }

  async function sendPhoneLoginCode() {
    tapMedium()
    if (!debugMode && !agreed) {
      toast('请先阅读并同意用户协议')
      return
    }
    if (!/^1\d{10}$/.test(phoneLoginPhone)) {
      toast('请输入正确手机号')
      return
    }
    setPhoneLoginSending(true)
    try {
      if (debugMode) {
        setPhoneLoginCode(DEBUG_CODE)
        setPhoneLoginStep('code')
        toast(`调试验证码：${DEBUG_CODE}`)
        return
      }
      await backend.sendPhoneCode(phoneLoginPhone)
      setPhoneLoginStep('code')
      toast('验证码已发送')
    } catch (error) {
      toast(error instanceof Error ? error.message : '验证码发送失败')
    } finally {
      setPhoneLoginSending(false)
    }
  }

  async function completePhoneLogin() {
    tapMedium()
    if (!/^1\d{10}$/.test(phoneLoginPhone)) {
      setPhoneLoginStep('phone')
      toast('请输入正确手机号')
      return
    }
    if (!phoneLoginCode) {
      toast('请输入验证码')
      return
    }
    if (!debugMode && !agreed) {
      toast('请先阅读并同意用户协议')
      return
    }
    setPhoneLoginSubmitting(true)
    try {
      if (debugMode) {
        saveToken('debug-miniapp-token')
        saveUser({
          id: 'debug-user',
          name: '',
          phone: phoneLoginPhone,
          authProvider: 'phone',
          onboardingCompleted: false,
          membershipLevel: 0
        })
        const pcQuery = pcSessionId ? `&pcSessionId=${encodeURIComponent(pcSessionId)}` : ''
        Taro.navigateTo({ url: `/pages/auth/onboarding/index?debug=1&redirect=${encodeURIComponent(redirect)}${pcQuery}` })
        return
      }
      const result = await backend.loginByPhone(phoneLoginPhone, phoneLoginCode)
      const user = mapUser(result.user)
      saveToken(result.token)
      saveUser(user)
      routeAfterPhoneLogin(user, result.token)
    } catch (error) {
      toast(error instanceof Error ? error.message : '登录失败')
    } finally {
      setPhoneLoginSubmitting(false)
    }
  }

  const phoneLoginPhoneReady = /^1\d{10}$/.test(phoneLoginPhone)
  const phoneLoginCodeReady = phoneLoginCode.trim().length > 0
  const phoneLoginActionDisabled = phoneLoginStep === 'phone' ? !phoneLoginPhoneReady || phoneLoginSending : !phoneLoginCodeReady || phoneLoginSubmitting

  return (
    <Page>
      <View className="auth-minimal auth-login-shell">
        <View className="auth-logo-card">
          <Image className="auth-logo" src={BRAND_LOGO_URL} mode="aspectFit" />
        </View>
        <View className="auth-brand-copy">
          <Text className="auth-brand-title">{BRAND_NAME}</Text>
        </View>
        <View className="auth-actions">
          <View className={(debugMode || agreed) && !loggingIn ? 'auth-big-btn primary' : 'auth-big-btn primary disabled'} onClick={() => void loginWithWechat()}>
            <Text>{loggingIn ? '微信登录中...' : '微信授权登录'}</Text>
          </View>
          <View className={(debugMode || agreed) ? 'auth-big-btn secondary' : 'auth-big-btn secondary disabled'} onClick={openPhoneLogin}>
            <Text>手机号登录</Text>
          </View>
          {debugMode && (
            <View className="auth-debug-actions">
              <Text className="auth-debug-pill" onClick={enterDebugPhone}>测试进入</Text>
              <Text className="auth-debug-pill ghost" onClick={previewPcConfirm}>授权页</Text>
              <Text className="auth-debug-link" onClick={enterDebugOnboarding}>完善资料测试</Text>
            </View>
          )}
        </View>
        <View className="login-agreement auth-agreement" onClick={() => setAgreed(!agreed)}>
          <View className={agreed ? 'agree-box checked' : 'agree-box'}>{agreed && <Text>✓</Text>}</View>
          <View className="agree-text">
            <Text>我已阅读并同意</Text>
            <Text className="agree-link" onClick={(event) => openAgreement('用户服务条款', event)}>《用户服务条款》</Text>
            <Text className="agree-link" onClick={(event) => openAgreement('隐私政策', event)}>《隐私政策》</Text>
          </View>
        </View>
        {agreementTitle && (
          <AgreementModal
            title={agreementTitle}
            onClose={() => setAgreementTitle('')}
          />
        )}
        {phoneDrawerOpen && (
          <BottomDrawer title="手机号登录" onClose={() => setPhoneDrawerOpen(false)} className="phone-login-drawer">
            <View className="phone-login-drawer-body">
              <Text className="phone-login-drawer-copy">
                {phoneLoginStep === 'phone' ? '输入手机号后获取验证码' : `验证码已发送至 ${phoneLoginPhone}`}
              </Text>
              <View className="phone-login-step-viewport">
                <View className={phoneLoginStep === 'code' ? 'phone-login-step-track code' : 'phone-login-step-track'}>
                  <View className="phone-login-step-panel">
                    <View className="drawer-auth-field">
                      <Text className="drawer-auth-label">手机号</Text>
                      <Input
                        className="drawer-auth-input"
                        focus={phoneLoginStep === 'phone'}
                        type="number"
                        maxlength={11}
                        value={phoneLoginPhone}
                        placeholder="请输入手机号"
                        onInput={(event) => setPhoneLoginPhone(String(event.detail.value))}
                      />
                    </View>
                  </View>
                  <View className="phone-login-step-panel">
                    <View className="drawer-auth-field">
                      <Text className="drawer-auth-label">验证码</Text>
                      <Input
                        className="drawer-auth-input"
                        focus={phoneLoginStep === 'code'}
                        type="number"
                        maxlength={6}
                        value={phoneLoginCode}
                        placeholder="请输入验证码"
                        onInput={(event) => setPhoneLoginCode(String(event.detail.value))}
                      />
                      <Text className="drawer-auth-change" onClick={() => setPhoneLoginStep('phone')}>更换手机号</Text>
                    </View>
                  </View>
                </View>
              </View>
              <View className={phoneLoginActionDisabled ? 'drawer-auth-primary translucent' : 'drawer-auth-primary'} onClick={() => phoneLoginStep === 'phone' ? void sendPhoneLoginCode() : void completePhoneLogin()}>
                <Text>{phoneLoginStep === 'phone' ? phoneLoginSending ? '发送中...' : '发送验证码' : phoneLoginSubmitting ? '登录中...' : '完成'}</Text>
              </View>
            </View>
          </BottomDrawer>
        )}
      </View>
    </Page>
  )
}
