'use client'

import { useSearchParams, useRouter } from 'next/navigation'
import Link from 'next/link'
import { useEffect, useState } from 'react'
import { MessageSquareText, QrCode, Smartphone } from 'lucide-react'
import { useApp } from '@/components/providers/AppProvider'
import { ImagePlaceholder } from '@/components/shared/ImagePlaceholder'
import { backend, clearStaffToken, saveStaffToken, type BackendSiteHomeSlide, type StaffAccount } from '@/lib/backend'
import { navigateReliably, safeInternalHref } from '@/lib/navigation'

const onboardingHomeHref = `/onboarding?redirect=${encodeURIComponent('/')}`
type PcScanStatus = 'pending' | 'scanned' | 'need_phone' | 'need_profile' | 'confirming' | 'confirmed' | 'expired' | 'cancelled'

function retryAfterSeconds(error: unknown) {
  const retryAfter = Number((error as { retryAfter?: unknown })?.retryAfter || 0)
  return Number.isFinite(retryAfter) && retryAfter > 0 ? Math.ceil(retryAfter) : 0
}

function pcScanStatusText(status: PcScanStatus) {
  if (status === 'scanned') return '手机已扫码'
  if (status === 'need_phone') return '请在小程序绑定手机号'
  if (status === 'need_profile') return '请在小程序完善资料'
  if (status === 'confirming') return '请在小程序确认登录'
  if (status === 'confirmed') return '登录成功，正在进入'
  if (status === 'expired') return '二维码已过期'
  if (status === 'cancelled') return '扫码登录已取消'
  return '请用微信扫码打开小程序'
}

function staffDefaultPath(account: StaffAccount) {
  const roleEntry: Record<string, string> = {
    super_admin: '/admin',
    operations_admin: '/admin',
    finance_admin: '/admin/revenue',
    content_admin: '/admin/site/home',
    checkin_staff: '/admin/events/checkin',
    agent_staff: '/staff?mode=tasks',
    consultant: '/staff?mode=consulting',
    data_service_staff: '/staff?mode=data-service',
  }
  return safeInternalHref(account.defaultEntry || roleEntry[account.role] || '/staff', roleEntry[account.role] || '/staff')
}

function pcClientRegion() {
  const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || ''
  const language = navigator.language || ''
  if (timeZone === 'Asia/Shanghai' || language.toLowerCase().includes('zh-cn')) return '中国大陆'
  return timeZone || language || '未知地区'
}

function pcClientDevice(userAgent: string) {
  if (/Windows NT/i.test(userAgent)) return 'Windows 电脑'
  if (/Macintosh|Mac OS X/i.test(userAgent)) return 'macOS 电脑'
  if (/iPad/i.test(userAgent)) return 'iPad'
  if (/iPhone/i.test(userAgent)) return 'iPhone'
  if (/Android/i.test(userAgent)) return 'Android 设备'
  if (/Linux/i.test(userAgent)) return 'Linux 电脑'
  return '电脑端设备'
}

function pcClientBrowser(userAgent: string) {
  if (/Edg\//i.test(userAgent)) return 'Microsoft Edge'
  if (/Chrome\//i.test(userAgent) && !/Chromium|OPR\//i.test(userAgent)) return 'Chrome 浏览器'
  if (/Safari\//i.test(userAgent) && !/Chrome\//i.test(userAgent)) return 'Safari 浏览器'
  if (/Firefox\//i.test(userAgent)) return 'Firefox 浏览器'
  if (/OPR\//i.test(userAgent)) return 'Opera 浏览器'
  return '浏览器'
}

function pcClientInfo() {
  const userAgent = navigator.userAgent || ''
  return {
    region: pcClientRegion(),
    device: pcClientDevice(userAgent),
    browser: pcClientBrowser(userAgent),
  }
}

function LoginVisualCarousel({ slides }: { slides: BackendSiteHomeSlide[] }) {
  const visibleSlides = slides.filter((slide) => slide.imageUrl).slice(0, 3)
  const [activeIndex, setActiveIndex] = useState(0)

  useEffect(() => {
    if (visibleSlides.length <= 1) return
    const timer = window.setInterval(() => {
      setActiveIndex((current) => (current + 1) % visibleSlides.length)
    }, 4200)
    return () => window.clearInterval(timer)
  }, [visibleSlides.length])

  useEffect(() => {
    if (activeIndex >= visibleSlides.length) setActiveIndex(0)
  }, [activeIndex, visibleSlides.length])

  if (visibleSlides.length === 0) {
    return <ImagePlaceholder label="暂无登录图片" className="h-full min-h-full border-0" />
  }

  return (
    <div className="relative h-full min-h-full overflow-hidden">
      <div
        className="absolute inset-0 flex transition-transform duration-700 ease-out"
        style={{ transform: `translateX(-${activeIndex * 100}%)` }}
      >
        {visibleSlides.map((slide) => (
          <div key={slide.id} className="relative min-w-full">
            <div
              className="absolute inset-0 bg-cover bg-center"
              style={{ backgroundImage: `url(${slide.imageUrl})` }}
              role="img"
              aria-label={slide.title || '登录页轮播图'}
            />
          </div>
        ))}
      </div>
      <div className="pointer-events-none absolute inset-0 bg-[linear-gradient(90deg,rgba(10,58,120,0.16),rgba(10,58,120,0.02))]" />
      {visibleSlides.length > 1 && (
        <div className="absolute bottom-8 left-8 flex gap-2">
          {visibleSlides.map((slide, index) => (
            <button
              key={slide.id}
              type="button"
              onClick={() => setActiveIndex(index)}
              className={`h-1.5 rounded-full transition-all ${index === activeIndex ? 'w-8 bg-white' : 'w-3 bg-white/55 hover:bg-white/80'}`}
              aria-label={`查看登录页轮播图 ${index + 1}`}
            />
          ))}
        </div>
      )}
    </div>
  )
}

export function LoginForm() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const { login, loginWithToken } = useApp()
  const redirect = safeInternalHref(searchParams.get('redirect') || '/', '/')
  const wechatError = searchParams.get('wechatError') || ''
  const staffTarget = redirect.startsWith('/admin') || redirect.startsWith('/staff')
  const [mode, setMode] = useState<'phone' | 'wechat'>(staffTarget ? 'phone' : 'wechat')
  const [phone, setPhone] = useState('')
  const [code, setCode] = useState('')
  const [loginSlides, setLoginSlides] = useState<BackendSiteHomeSlide[]>([])
  const [error, setError] = useState('')
  const [sending, setSending] = useState(false)
  const [sendCooldown, setSendCooldown] = useState(0)
  const [submitting, setSubmitting] = useState(false)
  const [pcScanSessionId, setPcScanSessionId] = useState('')
  const [pcScanQr, setPcScanQr] = useState('')
  const [pcScanStatus, setPcScanStatus] = useState<PcScanStatus>('pending')
  const [pcScanRefreshKey, setPcScanRefreshKey] = useState(0)

  useEffect(() => {
    void backend.siteHome()
      .then((site) => setLoginSlides((site.loginSlides || []).filter((slide) => slide.imageUrl).slice(0, 3)))
      .catch(() => setLoginSlides([]))
  }, [])

  useEffect(() => {
    if (!wechatError) return
    setMode('wechat')
    setError(wechatError)
  }, [wechatError])

  useEffect(() => {
    if (staffTarget) setMode('phone')
  }, [staffTarget])

  useEffect(() => {
    if (mode !== 'wechat' || staffTarget) return
    let cancelled = false
    setError('')
    setPcScanStatus('pending')

    void backend.createPcScanLogin(redirect, pcClientInfo())
      .then((session) => {
        if (cancelled) return
        setPcScanSessionId(session.sessionId)
        setPcScanQr(session.qrUrl || session.qrDataUrl)
      })
      .catch((err) => {
        if (!cancelled) setError(err instanceof Error ? err.message : '小程序码生成失败')
      })

    return () => {
      cancelled = true
    }
  }, [mode, pcScanRefreshKey, redirect, staffTarget])

  useEffect(() => {
    if (!pcScanSessionId || mode !== 'wechat' || staffTarget) return
    let cancelled = false
    let exchanging = false

    const timer = window.setInterval(() => {
      if (exchanging) return
      void backend.pcScanLoginStatus(pcScanSessionId)
        .then(async (status) => {
          if (cancelled) return
          setPcScanStatus(status.status)
          if (status.status === 'confirmed' && status.exchangeCode) {
            exchanging = true
            setSubmitting(true)
            const result = await backend.exchangePcScanLogin(pcScanSessionId, status.exchangeCode)
            const profile = await loginWithToken(result.token, 'wechat')
            if (cancelled) return
            navigateReliably(profile.onboardingCompleted ? safeInternalHref(result.redirect || redirect, redirect) : onboardingHomeHref, (href) => router.replace(href))
          }
        })
        .catch((err) => {
          if (!cancelled) setError(err instanceof Error ? err.message : '扫码登录状态获取失败')
        })
        .finally(() => {
          if (!cancelled && exchanging) setSubmitting(false)
        })
    }, 1800)

    return () => {
      cancelled = true
      window.clearInterval(timer)
    }
  }, [loginWithToken, mode, pcScanSessionId, redirect, router, staffTarget])

  useEffect(() => {
    if (sendCooldown <= 0) return
    const timer = window.setInterval(() => {
      setSendCooldown((current) => Math.max(0, current - 1))
    }, 1000)
    return () => window.clearInterval(timer)
  }, [sendCooldown])

  async function sendCode() {
    if (sendCooldown > 0) return
    setSending(true)
    setError('')
    try {
      await backend.sendPhoneCode(phone)
      setSendCooldown(60)
    } catch (err) {
      const retryAfter = retryAfterSeconds(err)
      if (retryAfter) setSendCooldown(retryAfter)
      setError(err instanceof Error ? err.message : '验证码发送失败')
    } finally {
      setSending(false)
    }
  }

  async function loginWithPhone(event?: React.FormEvent<HTMLFormElement>) {
    event?.preventDefault()
    setSubmitting(true)
    setError('')
    try {
      try {
        const result = await backend.staffPhoneLogin(phone, code)
        saveStaffToken(result.token)
        const target = staffTarget ? redirect : staffDefaultPath(result.account)
        navigateReliably(target === '/' ? staffDefaultPath(result.account) : target, (href) => router.replace(href))
        return
      } catch (staffError) {
        if (staffTarget) throw staffError
      }

      clearStaffToken()
      const profile = await login(phone, 'phone', code)
      navigateReliably(profile.onboardingCompleted ? redirect : onboardingHomeHref, (href) => router.replace(href))
    } catch (err) {
      setError(err instanceof Error ? err.message : '登录失败')
    } finally {
      setSubmitting(false)
    }
  }

  function refreshPcScan() {
    setPcScanSessionId('')
    setPcScanQr('')
    setPcScanStatus('pending')
    setPcScanRefreshKey((current) => current + 1)
  }

  return (
    <section className="overflow-hidden bg-white">
      <div className="grid h-[calc(100dvh-71px)] min-h-0 md:h-[calc(100dvh-107px)] lg:grid-cols-[minmax(0,1fr)_460px]">
        <div className="relative hidden min-h-full overflow-hidden lg:block">
          <LoginVisualCarousel slides={loginSlides} />
        </div>

        <div className="flex min-h-0 flex-col items-center justify-center overflow-y-auto border-l border-line bg-white px-6 py-6 sm:px-8 lg:px-12">
          <div className="flex h-[560px] w-full max-w-[420px] flex-col lg:max-w-none">
            <div className="shrink-0">
              <h1 className="text-2xl font-extrabold leading-tight text-ink lg:text-3xl">登录 / 注册</h1>
              <p className="mt-2 text-[13px] leading-6 text-muted">
                {staffTarget ? '管理端、员工端和顾问端统一使用手机号验证码登录。' : '欢迎来到大连市大数据研究院，登录后继续使用会员权益、专家服务与数据产品。'}
              </p>
            </div>

            {!staffTarget && (
              <div className="mt-6 flex shrink-0 border-b border-line">
                <button
                  type="button"
                  onClick={() => { setMode('wechat'); setError('') }}
                  className={`relative flex h-10 flex-1 items-center justify-center gap-2 text-[13px] font-bold transition-colors after:absolute after:bottom-[-1px] after:left-6 after:right-6 after:h-0.5 after:bg-brand after:transition-transform ${
                    mode === 'wechat' ? 'text-brand after:scale-x-100' : 'text-muted after:scale-x-0 hover:text-brand'
                  }`}
                >
                  <QrCode className="h-4 w-4" />
                  小程序
                </button>
                <button
                  type="button"
                  onClick={() => { setMode('phone'); setError('') }}
                  className={`relative flex h-10 flex-1 items-center justify-center gap-2 text-[13px] font-bold transition-colors after:absolute after:bottom-[-1px] after:left-6 after:right-6 after:h-0.5 after:bg-brand after:transition-transform ${
                    mode === 'phone' ? 'text-brand after:scale-x-100' : 'text-muted after:scale-x-0 hover:text-brand'
                  }`}
                >
                  <Smartphone className="h-4 w-4" />
                  手机号
                </button>
              </div>
            )}

            <div className="flex h-[350px] shrink-0 items-center justify-center">
              {mode === 'wechat' && !staffTarget ? (
                <div className="flex w-full flex-col items-center justify-center space-y-4">
                  <div className="relative grid h-[240px] w-[240px] place-items-center overflow-hidden bg-white">
                    {pcScanQr ? (
                      // eslint-disable-next-line @next/next/no-img-element
                      <img src={pcScanQr} alt="小程序扫码登录" className="h-[220px] w-[220px] object-contain" />
                    ) : (
                      <QrCode className="h-14 w-14 text-soft" />
                    )}
                  </div>
                  <div className="text-center text-[13px] font-bold text-muted">{pcScanStatusText(pcScanStatus)}</div>
                  {pcScanStatus === 'expired' && (
                    <button type="button" onClick={refreshPcScan} className="h-9 rounded-[4px] border border-line px-5 text-[13px] font-extrabold text-brand hover:border-brand">
                      刷新二维码
                    </button>
                  )}
                  {error && <div className="rounded-[4px] bg-red-50 px-3 py-2 text-sm font-bold text-red-700">{error}</div>}
                </div>
              ) : (
                <form onSubmit={loginWithPhone} className="flex w-full -translate-y-8 flex-col justify-center space-y-3">
                  <div>
                    <label className="mb-2 block text-[13px] font-bold text-ink">手机号</label>
                    <div className="flex h-10 items-center rounded-[4px] border border-line bg-white px-3 focus-within:border-brand">
                      <Smartphone className="mr-2 h-4 w-4 text-soft" />
                      <input type="tel" value={phone} onChange={(event) => setPhone(event.target.value)} placeholder="请输入手机号" className="h-full min-w-0 flex-1 border-0 bg-transparent text-[13px] text-ink outline-none placeholder:text-soft" />
                    </div>
                  </div>

                  <div>
                    <div className="mb-2 flex items-center justify-between">
                      <label className="block text-[13px] font-bold text-ink">短信验证码</label>
                      <button type="button" onClick={() => void sendCode()} disabled={sending || sendCooldown > 0} className="text-xs font-extrabold text-brand hover:underline disabled:text-soft disabled:no-underline">
                        {sending ? '发送中...' : sendCooldown > 0 ? `${sendCooldown}s 后重发` : '获取验证码'}
                      </button>
                    </div>
                    <div className="flex h-10 items-center rounded-[4px] border border-line bg-white px-3 focus-within:border-brand">
                      <MessageSquareText className="mr-2 h-4 w-4 text-soft" />
                      <input type="text" value={code} onChange={(event) => setCode(event.target.value)} placeholder="请输入 6 位验证码" className="h-full min-w-0 flex-1 border-0 bg-transparent text-[13px] text-ink outline-none placeholder:text-soft" />
                    </div>
                  </div>

                  {error && <div className="rounded-[4px] bg-red-50 px-3 py-2 text-sm font-bold text-red-700">{error}</div>}

                  <button disabled={submitting} className="h-10 w-full rounded-[4px] bg-brand text-[13px] font-extrabold text-white hover:bg-brand-dark disabled:bg-line-dark">
                    {submitting ? '登录中...' : staffTarget ? '进入工作台' : '登录已有账号'}
                  </button>
                </form>
              )}
            </div>

            <p className="mt-auto shrink-0 text-center text-xs text-soft">
              登录即代表同意
              <Link href="/registration-terms" className="mx-1 font-bold text-brand hover:underline">注册协议</Link>
              和
              <Link href="/privacy" className="ml-1 font-bold text-brand hover:underline">隐私政策</Link>
            </p>
          </div>
        </div>
      </div>
    </section>
  )
}
