import { useEffect, useState } from 'react';
import { View, Text, Input, Button } from '@tarojs/components';
import { useRouter } from '@tarojs/taro';
import {
  SmsScene,
  isWxAuthorizeEnabled,
  type ClientRuntimeConfig,
  type WechatLoginResult,
} from '@dukang/shared-types';
import PageShell from '../../components/PageShell';
import WechatLoginButton from '../../components/WechatLoginButton';
import { finishLoginNavigate } from '../../lib/auth-nav';
import { request, saveAuth, toast, type SessionPayload } from '../../lib/api';
import { loginWithWechat } from '../../lib/wechat-auth';

function normalizePhone(value: string) {
  return value.replace(/\D/g, '').slice(0, 11);
}

function isValidPhone(phone: string) {
  return /^1[3-9]\d{9}$/.test(phone);
}

export default function LoginPage() {
  const router = useRouter();
  const returnTo = router.params.return || '';

  const [phone, setPhone] = useState('');
  const [code, setCode] = useState('');
  const [loading, setLoading] = useState(false);
  const [wxLoading, setWxLoading] = useState(false);
  const [sending, setSending] = useState(false);
  const [cooldown, setCooldown] = useState(0);
  const [agreed, setAgreed] = useState(true);
  const [msg, setMsg] = useState('');
  const [sentHint, setSentHint] = useState('');
  const [bindMode, setBindMode] = useState(false);
  const [wxSessionKey, setWxSessionKey] = useState<string | null>(null);
  const [wxAuthorize, setWxAuthorize] = useState(true);

  useEffect(() => {
    request<ClientRuntimeConfig>('/common/client-config')
      .then((config) => setWxAuthorize(isWxAuthorizeEnabled(config)))
      .catch(() => setWxAuthorize(true));
  }, []);

  useEffect(() => {
    if (cooldown <= 0) return;
    const timer = setTimeout(() => setCooldown((c) => Math.max(0, c - 1)), 1000);
    return () => clearTimeout(timer);
  }, [cooldown]);

  function ensureAgreed() {
    if (!agreed) {
      setMsg('请先勾选并同意用户协议');
      return false;
    }
    return true;
  }

  function applySessionAndLeave(data: SessionPayload | WechatLoginResult) {
    if (!data.accessToken) return;
    saveAuth({
      accessToken: data.accessToken,
      refreshToken: data.refreshToken,
    });
    toast('登录成功', 'success');
    finishLoginNavigate(returnTo);
  }

  function handleWechatLoginResult(result: WechatLoginResult) {
    if (result.needBindPhone && result.wxSessionKey) {
      setBindMode(true);
      setWxSessionKey(result.wxSessionKey);
      setMsg('微信授权成功，请绑定手机号完成登录');
      setSentHint('');
      return;
    }
    if (result.accessToken) {
      applySessionAndLeave(result);
      return;
    }
    setMsg('微信登录未完成，请重试或使用手机号登录');
  }

  async function onSendCode() {
    if (!ensureAgreed()) return;
    if (cooldown > 0 || sending) return;
    const normalized = phone.trim();
    if (!isValidPhone(normalized)) {
      setMsg('请输入正确的手机号');
      return;
    }
    setMsg('');
    setSentHint('');
    setSending(true);
    try {
      await request('/auth/sms/send', {
        method: 'POST',
        data: {
          phone: normalized,
          scene: bindMode ? SmsScene.BIND_PHONE : SmsScene.USER_LOGIN,
        },
      });
      setCooldown(60);
      setSentHint('验证码已发送');
    } catch (e) {
      setMsg(e instanceof Error ? e.message : '发送失败');
    } finally {
      setSending(false);
    }
  }

  async function login() {
    if (!ensureAgreed()) return;
    const normalized = phone.trim();
    if (!isValidPhone(normalized)) {
      setMsg('请输入正确的手机号');
      return;
    }
    if (!code.trim()) {
      setMsg('请输入验证码');
      return;
    }
    setLoading(true);
    setMsg('');
    setSentHint('');
    try {
      if (bindMode && wxSessionKey) {
        const data = await request<WechatLoginResult>('/auth/wechat/bind-phone', {
          method: 'POST',
          data: { wxSessionKey, phone: normalized, code: code.trim() },
        });
        handleWechatLoginResult(data);
        return;
      }
      const data = await request<SessionPayload>('/auth/login/sms', {
        method: 'POST',
        data: { phone: normalized, code: code.trim() },
      });
      applySessionAndLeave(data);
    } catch (e) {
      setMsg(e instanceof Error ? e.message : '登录失败');
    } finally {
      setLoading(false);
    }
  }

  async function wechatLogin() {
    if (!ensureAgreed()) return;
    setMsg('');
    setSentHint('');
    setWxLoading(true);
    try {
      const result = await loginWithWechat();
      handleWechatLoginResult(result);
    } catch (e) {
      const raw = e instanceof Error ? e.message : '微信登录失败';
      const hint = /invalid code/i.test(raw)
        ? '微信 code 无效：请确认后端 WX_MINI_APP_ID 与小程序 appid 一致，或本地联调使用 MOCK_WECHAT'
        : raw;
      setMsg(hint);
    } finally {
      setWxLoading(false);
    }
  }

  const displayMsg = msg || sentHint;
  const codeDisabled = cooldown > 0 || sending;
  const showWechatLogin =
    !bindMode && (process.env.TARO_ENV === 'weapp' || wxAuthorize);

  return (
    <PageShell variant="plain" className="login-page">
      <View className="login-header">
        <View className="login-logo-wrap">
          <View className="login-logo">
            <Text>康</Text>
          </View>
          <Text className="login-logo-badge">官方</Text>
        </View>
        <View className="login-welcome">
          <Text className="login-welcome-title">欢迎来到杜康好客</Text>
          <Text className="login-welcome-sub">买美酒，享好礼</Text>
        </View>
      </View>

      <View className="login-main">
        <View className="login-card">
          <Text className="login-card-title">
            {bindMode ? '绑定手机号' : '手机验证码登录'}
          </Text>

          <View className="login-field">
            <Text className="login-field-prefix">+86</Text>
            <Input
              className="login-field-input"
              type="number"
              maxlength={11}
              placeholder="请输入手机号"
              value={phone}
              onInput={(e) => {
                setPhone(normalizePhone(e.detail.value));
                setMsg('');
                setSentHint('');
              }}
            />
          </View>

          <View className="login-field">
            <Input
              className="login-field-input"
              type="number"
              maxlength={6}
              placeholder="请输入验证码"
              value={code}
              onInput={(e) => setCode(e.detail.value.replace(/\D/g, '').slice(0, 6))}
            />
            <Text
              className={`login-get-code${codeDisabled ? ' login-get-code--disabled' : ''}`}
              onClick={() => void onSendCode()}
            >
              {sending ? '发送中...' : cooldown > 0 ? `${cooldown}s 后重新获取` : '获取验证码'}
            </Text>
          </View>

          {displayMsg ? (
            <Text className={`login-msg${sentHint && !msg ? ' login-msg--hint' : ''}`}>
              {displayMsg}
            </Text>
          ) : null}

          <Button
            className="login-sms-btn"
            loading={loading}
            disabled={loading}
            onClick={() => void login()}
          >
            {loading ? '登录中...' : bindMode ? '绑定并登录' : '登录'}
          </Button>
        </View>

        {showWechatLogin ? (
          <>
            <View className="login-divider">
              <View className="login-divider-line" />
              <Text className="login-divider-text">或者</Text>
              <View className="login-divider-line" />
            </View>
            <WechatLoginButton
              loading={wxLoading}
              onClick={() => void wechatLogin()}
            />
          </>
        ) : null}
      </View>

      <View className="login-footer">
        <View className="login-agreement" onClick={() => setAgreed((v) => !v)}>
          <View className={`login-agreement-check${agreed ? ' login-agreement-check--on' : ''}`}>
            {agreed ? <Text>✓</Text> : null}
          </View>
          <Text className="login-agreement-text">
            我已阅读并同意
            <Text className="login-agreement-link">《用户协议》</Text>
            和
            <Text className="login-agreement-link">《隐私政策》</Text>
          </Text>
        </View>
      </View>
    </PageShell>
  );
}
