'use client'

import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useForm } from '@mantine/form'
import {
  Box,
  TextInput,
  PasswordInput,
  Paper,
  Text,
  Button,
  LoadingOverlay,
  Stack,
  Flex,
  BackgroundImage,
  Tabs,
  FloatingIndicator,
  Input,
  useComputedColorScheme,
} from '@mantine/core'
import { showErrorMsg, showSuccessMsg } from '@/utils/message'
import { useLoginStore } from './store'
import DarkBgImage from './components/images/dark-login-bg.png'
import LightBgImage from './components/images/light-login-bg.png'
import loginBg2Dark from './components/images/login-bg2-dark.png'
import loginBg2Light from './components/images/login-bg2-light.png'
import LogoDigImage from './components/images/logo-dig.png'
import tabClasses from './Tab.module.css'
import { DigitalIcon } from './components/icons/digital'
import { encrypt, getQueryVariable, validatePhoneNumber } from './util'
import QrLogin from './components/login/qr-login'

const HeaderIcon = DigitalIcon
const headerTitle = '酷哇数字化平台'
const fixedTenant = 'coowa'

export default function LoginPage() {
  const colorScheme = useComputedColorScheme()
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [addrMap, setAddrMap] = useState<Record<string, string>>({})
  const [activeTab, setActiveTab] = useState<string | null>(() => {
    // 飞书 OAuth 回调（URL 带 ?code=xxx）时自动切到飞书 tab
    if (typeof window !== 'undefined' && getQueryVariable('code')) {
      return 'feishu'
    }
    return 'account'
  })
  const [rootRef, setRootRef] = useState<HTMLDivElement | null>(null)
  const controlsRefs = useRef<Record<string, HTMLButtonElement | null>>({})
  const setControlRef = (val: string) => (node: HTMLButtonElement) => {
    controlsRefs.current[val] = node
  }

  const { fingerprint, setFingerprint } = useLoginStore()

  // SSO 跳转参数
  const isClient = typeof window !== 'undefined'
  const appId = isClient ? (getQueryVariable('app_id') as string) || '' : ''
  const appUrl = isClient
    ? decodeURIComponent((getQueryVariable('app_url') as string) || '')
    : ''

  // 持久化 SSO 参数：飞书 OAuth 跳转后会丢失 URL 参数，存 localStorage
  useEffect(() => {
    if (appId && appUrl) {
      localStorage.setItem(appId, appUrl)          // app_id -> app_url
      localStorage.setItem('sso_app_id', appId)    // 记住当前 app_id
    }
  }, [appId, appUrl])

  // 获取租户简称列表（与 uirefbase 一致）
  useEffect(() => {
    fetch(`${process.env.NEXT_PUBLIC_BASE_PATH || ''}/api/front/getAbbrList`, {
      method: 'GET',
      headers: { 'Content-type': 'application/json' },
    })
      .then((response) => response.json())
      .then((res) => {
        setAddrMap(res?.data?.keys || {})
      })
      .catch(() => {})
  }, [])

  // 生成浏览器指纹
  useEffect(() => {
    const ua = navigator.userAgent
    const screenInfo = `${screen.width}x${screen.height}`
    const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone
    const raw = `${ua}|${screenInfo}|${timezone}`
    let hash = 0
    for (let i = 0; i < raw.length; i++) {
      hash = (hash << 5) - hash + raw.charCodeAt(i)
      hash |= 0
    }
    setFingerprint(Math.abs(hash).toString(36))
  }, [setFingerprint])

  // ============ 登录成功后跳转回外部应用 ============
  const handleLoginSuccess = useCallback((res: any) => {
    if (res?.error) {
      setError(res.error || '登录失败，请重试')
      return
    }

    if (!res?.user_info?.account) {
      setError('登录失败：后端未返回有效用户信息')
      return
    }

    // 从 localStorage 获取外部应用地址
    const storedAppId = appId || localStorage.getItem('sso_app_id') || ''
    const targetUrl =
      appUrl || (storedAppId ? localStorage.getItem(storedAppId) || '' : '')

    if (res?.code && targetUrl) {
      const separator = targetUrl.includes('?') ? '&' : '?'
      window.location.href = `${targetUrl}${separator}sso_code=${res.code}`
      return
    }

    // 无外部应用地址 — sso-mock 不提供本地登录
    setError('缺少外部应用回调地址（app_url），无法完成 SSO 跳转')
  }, [appId, appUrl])

  // ============ 统一调用 /api/login ============
  // SSO 参数优先取 URL，其次取 localStorage（飞书 OAuth 回调后 URL 参数丢失）
  const postLogin = async (payload: object) => {
    const effectiveAppId = appId || localStorage.getItem('sso_app_id') || ''
    const effectiveAppUrl =
      appUrl || (effectiveAppId ? localStorage.getItem(effectiveAppId) || '' : '')

    const res = await fetch(
      `${process.env.NEXT_PUBLIC_BASE_PATH || ''}/api/login`,
      {
        method: 'POST',
        body: JSON.stringify(
          encrypt(
            JSON.stringify({
              ...payload,
              fingerprint,
              ...(effectiveAppId ? { client_id: effectiveAppId } : {}),
              ...(effectiveAppUrl ? { client_redirect_uri: effectiveAppUrl } : {}),
            })
          )
        ),
      }
    )
      .then((r) => r.text())
      .then((t) => JSON.parse(t))

    return res
  }

  // ============ Tab 1: 账户登录 ============
  const accountForm = useForm({
    initialValues: { username: '', password: '' },
    validate: {
      username: (v) => (!v ? '账户名不能为空' : null),
      password: (v) => (!v ? '密码不能为空' : null),
    },
    validateInputOnChange: true,
    validateInputOnBlur: true,
    clearInputErrorOnChange: true,
  })

  const handleAccountSubmit = accountForm.onSubmit(async (values) => {
    setLoading(true)
    setError(null)
    try {
      const res = await postLogin({
        account: values.username,
        password: values.password,
        abbr: fixedTenant,
        type: 'account',
      })
      handleLoginSuccess(res)
    } catch (err) {
      setError(err instanceof Error ? err.message : '登录失败，请重试')
    } finally {
      setLoading(false)
    }
  })

  // ============ Tab 2: 手机号登录 ============
  const [codeTime, setCodeTime] = useState(0)

  const handleCountDown = () => {
    setCodeTime(60)
    const timer = setInterval(() => {
      setCodeTime((t) => {
        if (t <= 1) {
          clearInterval(timer)
          return 0
        }
        return t - 1
      })
    }, 1000)
  }

  const handleGetCode = async () => {
    if (!validatePhoneNumber(phoneForm.values.phone)) {
      setError('请输入正确的手机号')
      return
    }
    try {
      const tntkey = addrMap?.[fixedTenant] || ''
      if (!tntkey) {
        showErrorMsg('请输入正确的租户')
        return
      }
      const res: any = await fetch(
        `${process.env.NEXT_PUBLIC_BASE_PATH || ''}/api/getVerifyCode`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            phone: phoneForm.values.phone.startsWith('+86')
              ? phoneForm.values.phone
              : `+86${phoneForm.values.phone}`,
            tntkey,
          }),
        }
      ).then((r) => r.json())

      if (res?.code === 200) {
        showSuccessMsg('验证码已发送, 请注意查收')
        handleCountDown()
      } else {
        showErrorMsg(res?.message || '验证码发送失败')
      }
    } catch {
      showSuccessMsg('验证码已发送')
      handleCountDown()
    }
  }

  const phoneForm = useForm({
    initialValues: { phone: '', code: '' },
    validate: {
      phone: (v) => {
        if (!v) return '手机号不能为空'
        if (v.length !== 11) return '手机号必须为11位'
        return null
      },
      code: (v) => {
        if (!v) return '验证码不能为空'
        if (v.length !== 6) return '验证码必须为6位'
        return null
      },
    },
    validateInputOnChange: true,
    validateInputOnBlur: true,
    clearInputErrorOnChange: true,
  })

  const handlePhoneSubmit = phoneForm.onSubmit(async (values) => {
    setLoading(true)
    setError(null)
    try {
      const tntkey = addrMap?.[fixedTenant] || ''
      if (!tntkey) {
        setError('请输入正确的租户')
        setLoading(false)
        return
      }
      const res = await postLogin({
        phone: values.phone.startsWith('+86')
          ? values.phone
          : `+86${values.phone}`,
        verify_code: values.code,
        tntkey,
        type: 'phone',
      })
      handleLoginSuccess(res)
    } catch (err) {
      setError(err instanceof Error ? err.message : '登录失败，请重试')
    } finally {
      setLoading(false)
    }
  })

  // ============ 错误提示 ============
  useEffect(() => {
    if (error) showErrorMsg(error)
  }, [error])

  const bgImage = useMemo(
    () => (colorScheme === 'dark' ? DarkBgImage : LightBgImage),
    [colorScheme]
  )
  const stackBg2Image = useMemo(
    () => (colorScheme === 'dark' ? loginBg2Dark : loginBg2Light),
    [colorScheme]
  )

  // 飞书 OAuth 回调中：显示 loading，不渲染表单
  const isFeishuCallback = isClient && !!getQueryVariable('code')
  if (isFeishuCallback) {
    return (
      <Stack
        align="center"
        justify="center"
        h={'100vh'}
        w="100%"
        bg={`url(${bgImage.src})`}
        bgsz="cover"
        bgp="center"
        bgr="no-repeat">
        <Paper withBorder shadow="md" radius="md" p="xl">
          <Stack align="center" gap="md">
            <LoadingOverlay visible />
            <Text size="sm" c="dimmed">正在验证飞书登录...</Text>
          </Stack>
        </Paper>
        {/* QrLogin 仍在后台执行 feishuLogin */}
        <Box style={{ position: 'absolute', opacity: 0, pointerEvents: 'none' }}>
          <QrLogin onLoginSuccess={handleLoginSuccess} />
        </Box>
      </Stack>
    )
  }

  return (
    <Stack
      align="center"
      justify="center"
      h={'100vh'}
      w="100%"
      bg={`url(${bgImage.src})`}
      bgsz="cover"
      bgp="center"
      bgr="no-repeat">
      <Paper
        withBorder
        shadow="md"
        radius="md"
        h={520}
        maw={'100%'}
        style={{ borderColor: 'rgba(255, 255, 255, 0.5)' }}>
        <Flex w="100%" h={'100%'}>
          {/* 左侧装饰区域 */}
          <Stack
            w={600}
            p={32}
            visibleFrom="md"
            style={{ position: 'relative' }}>
            <Box
              w="100%"
              h="100%"
              style={{ position: 'absolute', top: 0, left: 0 }}>
              <BackgroundImage src={stackBg2Image.src} w="100%" h="100%" />
            </Box>
            <Flex
              justify="center"
              align="center"
              h="100%"
              style={{ zIndex: 11 }}>
              <BackgroundImage
                src={LogoDigImage.src}
                radius="xs"
                w={432}
                h={310}
                visibleFrom="md"
              />
            </Flex>
          </Stack>

          {/* 右侧登录表单 */}
          <Stack h={'100%'} w={380} p={'54px 32px'} gap={0}>
            <Flex mb={'2rem'} gap={8} justify="center" align={'center'}>
              <HeaderIcon />
              <Text size="xxl">{headerTitle}</Text>
            </Flex>

            {/* SSO 来源提示 */}
            {appId && (
              <Text size="xs" c="dimmed" ta="center" mb="sm">
                正在为应用 {appId} 进行登录认证
              </Text>
            )}

            <Tabs variant="none" value={activeTab} onChange={setActiveTab}>
              <Tabs.List ref={setRootRef} className={tabClasses.list}>
                <Tabs.Tab
                  value="account"
                  ref={setControlRef('account')}
                  className={tabClasses.tab}>
                  账户登录
                </Tabs.Tab>
                <Tabs.Tab
                  value="phone"
                  ref={setControlRef('phone')}
                  className={tabClasses.tab}>
                  手机号登录
                </Tabs.Tab>
                <Tabs.Tab
                  value="feishu"
                  ref={setControlRef('feishu')}
                  className={tabClasses.tab}>
                  飞书扫码
                </Tabs.Tab>
                <FloatingIndicator
                  target={activeTab ? controlsRefs.current[activeTab] : null}
                  parent={rootRef}
                  className={tabClasses.indicator}
                />
              </Tabs.List>

              {/* 账户登录 */}
              <Tabs.Panel value="account">
                <form
                  onSubmit={handleAccountSubmit}
                  style={{ marginTop: '30px' }}>
                  <LoadingOverlay visible={loading} />
                  <TextInput
                    withAsterisk
                    label="账户名"
                    placeholder="请输入账户名"
                    mt="md"
                    {...accountForm.getInputProps('username')}
                  />
                  <PasswordInput
                    withAsterisk
                    label="密码"
                    placeholder="请输入密码"
                    mt="md"
                    {...accountForm.getInputProps('password')}
                  />
                  <Button type="submit" fullWidth mt="xl" disabled={loading}>
                    {loading ? '登录中...' : '登录'}
                  </Button>
                </form>
              </Tabs.Panel>

              {/* 手机号登录 */}
              <Tabs.Panel value="phone">
                <form
                  onSubmit={handlePhoneSubmit}
                  style={{ marginTop: '30px' }}>
                  <LoadingOverlay visible={loading} />
                  <TextInput
                    withAsterisk
                    label="手机号"
                    placeholder="请输入手机号"
                    mt="md"
                    {...phoneForm.getInputProps('phone')}
                  />
                  <Input.Wrapper
                    label="验证码"
                    withAsterisk
                    mt="md"
                    error={phoneForm.errors.code}>
                    <Flex align="center" gap={18}>
                      <Input
                        placeholder="请输入验证码"
                        style={{ flex: 1 }}
                        {...phoneForm.getInputProps('code')}
                      />
                      <Button
                        style={{ flexShrink: 0 }}
                        type="button"
                        disabled={
                          !validatePhoneNumber(phoneForm.values.phone) ||
                          !!codeTime
                        }
                        onClick={handleGetCode}>
                        {codeTime !== 0 ? `${codeTime}秒后获取` : '获取验证码'}
                      </Button>
                    </Flex>
                  </Input.Wrapper>
                  <Button type="submit" fullWidth mt="xl" disabled={loading}>
                    {loading ? '登录中...' : '登录'}
                  </Button>
                </form>
              </Tabs.Panel>

              {/* 飞书扫码（真实二维码） */}
              <Tabs.Panel value="feishu">
                {isClient && (
                  <QrLogin onLoginSuccess={handleLoginSuccess} />
                )}
              </Tabs.Panel>
            </Tabs>
          </Stack>
        </Flex>
      </Paper>
    </Stack>
  )
}
