import { useEffect, useRef, useState } from 'react';
import { useNavigate, useSearchParams, Link } from 'react-router-dom';
import AppImage from '@dukang/shared-ui/AppImage';
import type { WechatLoginResult } from '@dukang/shared-types';
import { SmsScene } from '@dukang/shared-types';
import { request, type SessionPayload } from '../lib/api';
import { fetchClientConfig } from '../lib/pay-wechat';
import { isWxAuthorizeEnabled } from '@dukang/shared-types';
import { normalizePhoneInput, validateMobilePhone } from '../lib/phone';
import { useSmsCode } from '../lib/use-sms-code';
import { isWechatEnv } from '../lib/weixin';
import { loginWithWechatSdk, handleWechatAuthCallback as handleWechatOAuthCallback } from '../lib/wechat-auth';
import { useUserSession } from '../contexts/UserSessionContext';
import { touchPromoIfNeeded } from '../lib/promo';

async function finishLogin(navigate: (path: string) => void, returnTo: string) {
  await touchPromoIfNeeded();
  navigate(returnTo.startsWith('/') ? returnTo : '/');
}

export default function LoginPage() {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const returnTo = searchParams.get('return') || '/';
  const { applySession } = useUserSession();
  const [phone, setPhone] = useState('');
  const [code, setCode] = useState('');
  const [loading, setLoading] = useState(false);
  const [agreed, setAgreed] = useState(false);
  const [msg, setMsg] = useState('');
  const [wxSessionKey, setWxSessionKey] = useState<string | null>(null);
  const [bindMode, setBindMode] = useState(false);
  const [wxAuthorize, setWxAuthorize] = useState(false);
  const agreementRef = useRef<HTMLLabelElement>(null);
  const { sendCode, sending, codeCooldown, sentHint, error: smsError, setError: setSmsError, clearMessages } =
    useSmsCode();

  useEffect(() => {
    fetchClientConfig()
      .then((config) => setWxAuthorize(isWxAuthorizeEnabled(config)))
      .catch(() => setWxAuthorize(false));
  }, []);

  useEffect(() => {
    if (!isWechatEnv() || !wxAuthorize) return;
    handleWechatOAuthCallback()
      .then((result) => {
        if (!result) return;
        handleWechatLoginResult(result);
      })
      .catch((e) => setMsg(e instanceof Error ? e.message : '微信登录失败'));
  }, [wxAuthorize]);

  function handleWechatLoginResult(result: WechatLoginResult) {
    if (result.accessToken) {
      applySession({
        accessToken: result.accessToken,
        refreshToken: result.refreshToken ?? '',
        deviceKey: result.deviceKey,
        phoneVerified: !!result.phoneVerified,
        user: result.user as SessionPayload['user'],
      });
      void finishLogin(navigate, returnTo);
      return;
    }
    if (result.needBindPhone && result.wxSessionKey) {
      setBindMode(true);
      setWxSessionKey(result.wxSessionKey);
      setMsg('微信授权成功，可绑定手机号（也可跳过，稍后在下单时再绑定）');
      return;
    }
  }

  function ensureAgreed() {
    if (!agreed) {
      setMsg('请先勾选并同意用户协议');
      agreementRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });
      return false;
    }
    return true;
  }

  async function onSendCode() {
    if (!ensureAgreed()) return;
    clearMessages();
    setMsg('');
    await sendCode(phone, bindMode ? SmsScene.BIND_PHONE : SmsScene.USER_LOGIN);
  }

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

  async function wechatLogin() {
    if (!ensureAgreed()) return;
    setMsg('');
    try {
      const result = await loginWithWechatSdk();
      if (result) handleWechatLoginResult(result);
    } catch (e) {
      setMsg(e instanceof Error ? e.message : '微信登录失败');
    }
  }

  const displayMsg = msg || smsError;

  return (
    <div className="login-page">
      <header className="login-header">
        <div className="login-logo-wrap">
          <AppImage src="/logo.png" alt="杜康好客" wrapperClassName="login-logo" fit="contain" />
          <span className="login-logo-badge">官方</span>
        </div>
        <div className="login-welcome">
          <h1 className="login-welcome-title">欢迎来到杜康好客</h1>
          <p className="login-welcome-sub">买美酒，享好礼</p>
        </div>
      </header>

      <main className="login-main">
        <div className="login-card">
          <h3 className="login-card-title">{bindMode ? '绑定手机号' : '手机验证码登录'}</h3>
          <div className="login-field">
            <span className="login-field-prefix">+86</span>
            <input
              type="tel"
              className="login-field-input"
              placeholder="请输入手机号"
              maxLength={11}
              inputMode="numeric"
              value={phone}
              onChange={(e) => {
                setPhone(normalizePhoneInput(e.target.value));
                setMsg('');
                clearMessages();
              }}
            />
          </div>
          <div className="login-field">
            <input
              type="text"
              inputMode="numeric"
              className="login-field-input"
              placeholder="请输入验证码"
              maxLength={6}
              value={code}
              onChange={(e) => setCode(e.target.value.replace(/\D/g, '').slice(0, 6))}
            />
            <button
              type="button"
              className={`login-get-code${codeCooldown > 0 || sending ? ' disabled' : ''}`}
              disabled={codeCooldown > 0 || sending}
              onClick={onSendCode}
            >
              {sending
                ? '发送中...'
                : codeCooldown > 0
                  ? `${codeCooldown}s 后重新获取`
                  : '获取验证码'}
            </button>
          </div>
          {(displayMsg || sentHint) && (
            <p className={`login-msg${sentHint && !displayMsg ? ' login-msg--hint' : ''}`}>
              {displayMsg || sentHint}
            </p>
          )}
          <label className="login-agreement" ref={agreementRef}>
            <input
              type="checkbox"
              checked={agreed}
              onChange={(e) => setAgreed(e.target.checked)}
            />
            <span>
              我已阅读并同意
              <Link to="/legal/user-agreement" onClick={(e) => e.stopPropagation()}>
                《用户协议》
              </Link>
              和
              <Link to="/legal/privacy-policy" onClick={(e) => e.stopPropagation()}>
                《隐私政策》
              </Link>
            </span>
          </label>
          <button
            type="button"
            className="login-sms-btn"
            disabled={loading}
            onClick={login}
          >
            {loading ? '登录中...' : bindMode ? '绑定并登录' : '登录'}
          </button>
        </div>

        {!bindMode && wxAuthorize && (
          <>
            <div className="login-divider">
              <span className="login-divider-line" />
              <span className="login-divider-text">或者</span>
              <span className="login-divider-line" />
            </div>

            <button type="button" className="login-wechat-btn" onClick={wechatLogin}>
              <span className="material-symbols-outlined login-wechat-icon">chat</span>
              <span>微信一键授权</span>
            </button>
          </>
        )}
      </main>
    </div>
  );
}
