/*
Copyright (C) 2025 QuantumNous

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

For commercial licensing, please contact support@quantumnous.com
*/

import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import {
  API,
  getLogo,
  showError,
  showInfo,
  showSuccess,
  updateAPI,
  getSystemName,
  getOAuthProviderIcon,
  setUserData,
  onDiscordOAuthClicked,
  onCustomOAuthClicked,
} from '../../helpers';
import Turnstile from 'react-turnstile';
import {
  Button,
  Checkbox,
  Form,
  Icon,
  Modal,
} from '@douyinfe/semi-ui';
import {
  IconGithubLogo,
  IconMail,
} from '@douyinfe/semi-icons';
import {
  onGitHubOAuthClicked,
  onLinuxDOOAuthClicked,
  onOIDCClicked,
} from '../../helpers';
import OIDCIcon from '../common/logo/OIDCIcon';
import LinuxDoIcon from '../common/logo/LinuxDoIcon';
import WeChatIcon from '../common/logo/WeChatIcon';
import TelegramLoginButton from 'react-telegram-login/src';
import { UserContext } from '../../context/User';
import { StatusContext } from '../../context/Status';
import { useTranslation } from 'react-i18next';
import { SiDiscord } from 'react-icons/si';

const RegisterForm = () => {
  let navigate = useNavigate();
  const { t } = useTranslation();
  const githubButtonTextKeyByState = {
    idle: '使用 GitHub 继续',
    redirecting: '正在跳转 GitHub...',
    timeout: '请求超时，请刷新页面后重新发起 GitHub 登录',
  };
  const [inputs, setInputs] = useState({
    username: '',
    password: '',
    password2: '',
    email: '',
    verification_code: '',
    wechat_verification_code: '',
  });
  const { username, password, password2 } = inputs;
  const [userState, userDispatch] = useContext(UserContext);
  const [statusState] = useContext(StatusContext);
  const [turnstileEnabled, setTurnstileEnabled] = useState(false);
  const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
  const [turnstileToken, setTurnstileToken] = useState('');
  const [showWeChatLoginModal, setShowWeChatLoginModal] = useState(false);
  const [showEmailRegister, setShowEmailRegister] = useState(false);
  const [wechatLoading, setWechatLoading] = useState(false);
  const [githubLoading, setGithubLoading] = useState(false);
  const [discordLoading, setDiscordLoading] = useState(false);
  const [oidcLoading, setOidcLoading] = useState(false);
  const [linuxdoLoading, setLinuxdoLoading] = useState(false);
  const [emailRegisterLoading, setEmailRegisterLoading] = useState(false);
  const [registerLoading, setRegisterLoading] = useState(false);
  const [verificationCodeLoading, setVerificationCodeLoading] = useState(false);
  const [otherRegisterOptionsLoading, setOtherRegisterOptionsLoading] =
    useState(false);
  const [wechatCodeSubmitLoading, setWechatCodeSubmitLoading] = useState(false);
  const [customOAuthLoading, setCustomOAuthLoading] = useState({});
  const [disableButton, setDisableButton] = useState(false);
  const [countdown, setCountdown] = useState(30);
  const [agreedToTerms, setAgreedToTerms] = useState(false);
  const [hasUserAgreement, setHasUserAgreement] = useState(false);
  const [hasPrivacyPolicy, setHasPrivacyPolicy] = useState(false);
  const [githubButtonState, setGithubButtonState] = useState('idle');
  const [githubButtonDisabled, setGithubButtonDisabled] = useState(false);
  const githubTimeoutRef = useRef(null);
  const githubButtonText = t(githubButtonTextKeyByState[githubButtonState]);

  const logo = getLogo();
  const systemName = getSystemName();

  let affCode = new URLSearchParams(window.location.search).get('aff');
  if (affCode) {
    localStorage.setItem('aff', affCode);
  }

  const status = useMemo(() => {
    if (statusState?.status) return statusState.status;
    const savedStatus = localStorage.getItem('status');
    if (!savedStatus) return {};
    try {
      return JSON.parse(savedStatus) || {};
    } catch (err) {
      return {};
    }
  }, [statusState?.status]);
  const hasCustomOAuthProviders =
    (status.custom_oauth_providers || []).length > 0;
  const hasOAuthRegisterOptions = Boolean(
    status.github_oauth ||
      status.discord_oauth ||
      status.oidc_enabled ||
      status.wechat_login ||
      status.linuxdo_oauth ||
      status.telegram_oauth ||
      hasCustomOAuthProviders,
  );

  const [showEmailVerification, setShowEmailVerification] = useState(false);

  useEffect(() => {
    setShowEmailVerification(!!status?.email_verification);
    if (status?.turnstile_check) {
      setTurnstileEnabled(true);
      setTurnstileSiteKey(status.turnstile_site_key);
    }

    // 从 status 获取用户协议和隐私政策的启用状态
    setHasUserAgreement(status?.user_agreement_enabled || false);
    setHasPrivacyPolicy(status?.privacy_policy_enabled || false);
  }, [status]);

  useEffect(() => {
    let countdownInterval = null;
    if (disableButton && countdown > 0) {
      countdownInterval = setInterval(() => {
        setCountdown(countdown - 1);
      }, 1000);
    } else if (countdown === 0) {
      setDisableButton(false);
      setCountdown(30);
    }
    return () => clearInterval(countdownInterval); // Clean up on unmount
  }, [disableButton, countdown]);

  useEffect(() => {
    return () => {
      if (githubTimeoutRef.current) {
        clearTimeout(githubTimeoutRef.current);
      }
    };
  }, []);

  const onWeChatLoginClicked = () => {
    setWechatLoading(true);
    setShowWeChatLoginModal(true);
    setWechatLoading(false);
  };

  const onSubmitWeChatVerificationCode = async () => {
    if (turnstileEnabled && turnstileToken === '') {
      showInfo('请稍后几秒重试，Turnstile 正在检查用户环境！');
      return;
    }
    setWechatCodeSubmitLoading(true);
    try {
      const res = await API.get(
        `/api/oauth/wechat?code=${inputs.wechat_verification_code}`,
      );
      const { success, message, data } = res.data;
      if (success) {
        userDispatch({ type: 'login', payload: data });
        localStorage.setItem('user', JSON.stringify(data));
        setUserData(data);
        updateAPI();
        navigate('/');
        showSuccess('登录成功！');
        setShowWeChatLoginModal(false);
      } else {
        showError(message);
      }
    } catch (error) {
      showError('登录失败，请重试');
    } finally {
      setWechatCodeSubmitLoading(false);
    }
  };

  function handleChange(name, value) {
    setInputs((inputs) => ({ ...inputs, [name]: value }));
  }

  async function handleSubmit(e) {
    if (password.length < 8) {
      showInfo('密码长度不得小于 8 位！');
      return;
    }
    if (password !== password2) {
      showInfo('两次输入的密码不一致');
      return;
    }
    if (username && password) {
      if (turnstileEnabled && turnstileToken === '') {
        showInfo('请稍后几秒重试，Turnstile 正在检查用户环境！');
        return;
      }
      setRegisterLoading(true);
      try {
        if (!affCode) {
          affCode = localStorage.getItem('aff');
        }
        inputs.aff_code = affCode;
        const res = await API.post(
          `/api/user/register?turnstile=${turnstileToken}`,
          inputs,
        );
        const { success, message } = res.data;
        if (success) {
          navigate('/login');
          showSuccess('注册成功！');
        } else {
          showError(message);
        }
      } catch (error) {
        showError('注册失败，请重试');
      } finally {
        setRegisterLoading(false);
      }
    }
  }

  const sendVerificationCode = async () => {
    if (inputs.email === '') return;
    if (turnstileEnabled && turnstileToken === '') {
      showInfo('请稍后几秒重试，Turnstile 正在检查用户环境！');
      return;
    }
    setVerificationCodeLoading(true);
    try {
      const res = await API.get(
        `/api/verification?email=${encodeURIComponent(inputs.email)}&turnstile=${turnstileToken}`,
      );
      const { success, message } = res.data;
      if (success) {
        showSuccess('验证码发送成功，请检查你的邮箱！');
        setDisableButton(true); // 发送成功后禁用按钮，开始倒计时
      } else {
        showError(message);
      }
    } catch (error) {
      showError('发送验证码失败，请重试');
    } finally {
      setVerificationCodeLoading(false);
    }
  };

  const handleGitHubClick = () => {
    if (githubButtonDisabled) {
      return;
    }
    setGithubLoading(true);
    setGithubButtonDisabled(true);
    setGithubButtonState('redirecting');
    if (githubTimeoutRef.current) {
      clearTimeout(githubTimeoutRef.current);
    }
    githubTimeoutRef.current = setTimeout(() => {
      setGithubLoading(false);
      setGithubButtonState('timeout');
      setGithubButtonDisabled(true);
    }, 20000);
    try {
      onGitHubOAuthClicked(status.github_client_id, { shouldLogout: true });
    } finally {
      setTimeout(() => setGithubLoading(false), 3000);
    }
  };

  const handleDiscordClick = () => {
    setDiscordLoading(true);
    try {
      onDiscordOAuthClicked(status.discord_client_id, { shouldLogout: true });
    } finally {
      setTimeout(() => setDiscordLoading(false), 3000);
    }
  };

  const handleOIDCClick = () => {
    setOidcLoading(true);
    try {
      onOIDCClicked(
        status.oidc_authorization_endpoint,
        status.oidc_client_id,
        false,
        { shouldLogout: true },
      );
    } finally {
      setTimeout(() => setOidcLoading(false), 3000);
    }
  };

  const handleLinuxDOClick = () => {
    setLinuxdoLoading(true);
    try {
      onLinuxDOOAuthClicked(status.linuxdo_client_id, { shouldLogout: true });
    } finally {
      setTimeout(() => setLinuxdoLoading(false), 3000);
    }
  };

  const handleCustomOAuthClick = (provider) => {
    setCustomOAuthLoading((prev) => ({ ...prev, [provider.slug]: true }));
    try {
      onCustomOAuthClicked(provider, { shouldLogout: true });
    } finally {
      setTimeout(() => {
        setCustomOAuthLoading((prev) => ({ ...prev, [provider.slug]: false }));
      }, 3000);
    }
  };

  const handleEmailRegisterClick = () => {
    setEmailRegisterLoading(true);
    setShowEmailRegister(true);
    setEmailRegisterLoading(false);
  };

  const handleOtherRegisterOptionsClick = () => {
    setOtherRegisterOptionsLoading(true);
    setShowEmailRegister(false);
    setOtherRegisterOptionsLoading(false);
  };

  const onTelegramLoginClicked = async (response) => {
    const fields = [
      'id',
      'first_name',
      'last_name',
      'username',
      'photo_url',
      'auth_date',
      'hash',
      'lang',
    ];
    const params = {};
    fields.forEach((field) => {
      if (response[field]) {
        params[field] = response[field];
      }
    });
    try {
      const res = await API.get(`/api/oauth/telegram/login`, { params });
      const { success, message, data } = res.data;
      if (success) {
        userDispatch({ type: 'login', payload: data });
        localStorage.setItem('user', JSON.stringify(data));
        showSuccess('登录成功！');
        setUserData(data);
        updateAPI();
        navigate('/');
      } else {
        showError(message);
      }
    } catch (error) {
      showError('登录失败，请重试');
    }
  };

  const renderOAuthOptions = () => {
    return (
      <div className='lp-auth-card'>
        <div className='lp-auth-logo-row'>
          <img src={logo} alt='Logo' style={{width:'32px',height:'32px',borderRadius:'8px',objectFit:'cover'}} />
          <span className='lp-auth-brand'>{systemName}</span>
        </div>

        <h1 className='lp-auth-title'>{t('创建新账号')}</h1>
        <p className='lp-auth-sub'>或 <Link to='/login' className='lp-auth-link'>{t('登录已有账号')}</Link></p>

        <div className='lp-auth-oauth-list'>
          {status.wechat_login && (
            <Button
              theme='outline'
              className='lp-auth-oauth-btn'
              type='tertiary'
              icon={<Icon svg={<WeChatIcon />} style={{ color: '#07C160' }} />}
              onClick={onWeChatLoginClicked}
              loading={wechatLoading}
            >
              <span className='ml-3'>{t('使用 微信 继续')}</span>
            </Button>
          )}

          {status.github_oauth && (
            <Button
              theme='outline'
              className='lp-auth-oauth-btn'
              type='tertiary'
              icon={<IconGithubLogo size='large' />}
              onClick={handleGitHubClick}
              loading={githubLoading}
              disabled={githubButtonDisabled}
            >
              <span className='ml-3'>{githubButtonText}</span>
            </Button>
          )}

          {status.discord_oauth && (
            <Button
              theme='outline'
              className='lp-auth-oauth-btn'
              type='tertiary'
              icon={<SiDiscord style={{ color: '#5865F2', width: '20px', height: '20px' }} />}
              onClick={handleDiscordClick}
              loading={discordLoading}
            >
              <span className='ml-3'>{t('使用 Discord 继续')}</span>
            </Button>
          )}

          {status.oidc_enabled && (
            <Button
              theme='outline'
              className='lp-auth-oauth-btn'
              type='tertiary'
              icon={<OIDCIcon style={{ color: '#1877F2' }} />}
              onClick={handleOIDCClick}
              loading={oidcLoading}
            >
              <span className='ml-3'>{t('使用 OIDC 继续')}</span>
            </Button>
          )}

          {status.linuxdo_oauth && (
            <Button
              theme='outline'
              className='lp-auth-oauth-btn'
              type='tertiary'
              icon={<LinuxDoIcon style={{ color: '#E95420', width: '20px', height: '20px' }} />}
              onClick={handleLinuxDOClick}
              loading={linuxdoLoading}
            >
              <span className='ml-3'>{t('使用 LinuxDO 继续')}</span>
            </Button>
          )}

          {status.custom_oauth_providers &&
            status.custom_oauth_providers.map((provider) => (
              <Button
                key={provider.slug}
                theme='outline'
                className='lp-auth-oauth-btn'
                type='tertiary'
                icon={getOAuthProviderIcon(provider.icon || '', 20)}
                onClick={() => handleCustomOAuthClick(provider)}
                loading={customOAuthLoading[provider.slug]}
              >
                <span className='ml-3'>{t('使用 {{name}} 继续', { name: provider.name })}</span>
              </Button>
            ))}

          {status.telegram_oauth && (
            <div className='flex justify-center my-2'>
              <TelegramLoginButton
                dataOnauth={onTelegramLoginClicked}
                botName={status.telegram_bot_name}
              />
            </div>
          )}

          <div className='lp-auth-divider'><span>{t('或')}</span></div>

          <Button
            theme='solid'
            type='primary'
            className='lp-auth-oauth-btn'
            icon={<IconMail size='large' />}
            onClick={handleEmailRegisterClick}
            loading={emailRegisterLoading}
          >
            <span className='ml-3'>{t('使用 用户名 注册')}</span>
          </Button>
        </div>
      </div>
    );
  };

  const renderEmailRegisterForm = () => {
    return (
      <div className='lp-auth-card'>
        <div className='lp-auth-logo-row'>
          <img src={logo} alt='Logo' style={{width:'32px',height:'32px',borderRadius:'8px',objectFit:'cover'}} />
          <span className='lp-auth-brand'>{systemName}</span>
        </div>

        <h1 className='lp-auth-title'>{t('创建新账号')}</h1>
        <p className='lp-auth-sub'>或 <Link to='/login' className='lp-auth-link'>{t('登录已有账号')}</Link></p>

        <div className='lp-form-group'>
          <span className='lp-form-icon'>👤</span>
          <input
            type='text'
            placeholder={t('请输入用户名')}
            name='username'
            autoComplete='nickname'
            onChange={(e) => handleChange('username', e.target.value)}
            className='lp-input'
          />
        </div>

        <div className='lp-form-group'>
          <span className='lp-form-icon'>🔒</span>
          <input
            type='password'
            placeholder={t('输入密码，最短 8 位，最长 20 位')}
            name='password'
            autoComplete='new-password'
            onChange={(e) => handleChange('password', e.target.value)}
            className='lp-input'
          />
        </div>

        <div className='lp-form-group'>
          <span className='lp-form-icon'>🔒</span>
          <input
            type='password'
            placeholder={t('确认密码')}
            name='password2'
            autoComplete='new-password'
            onChange={(e) => handleChange('password2', e.target.value)}
            className='lp-input'
          />
        </div>

        {showEmailVerification && (
          <>
            <div className='lp-form-group'>
              <span className='lp-form-icon'>✉</span>
              <input
                type='email'
                placeholder={t('输入邮箱地址')}
                name='email'
                autoComplete='email'
                onChange={(e) => handleChange('email', e.target.value)}
                className='lp-input'
              />
            </div>
            <div className='lp-code-row'>
              <div className='lp-form-group' style={{flex:1,margin:0}}>
                <span className='lp-form-icon'>🔑</span>
                <input
                  type='text'
                  placeholder={t('输入验证码')}
                  name='verification_code'
                  onChange={(e) => handleChange('verification_code', e.target.value)}
                  className='lp-input'
                />
              </div>
              <button
                className='lp-btn-send-code'
                onClick={sendVerificationCode}
                disabled={disableButton || verificationCodeLoading}
              >
                {disableButton ? `${t('重新发送')} (${countdown})` : t('获取验证码')}
              </button>
            </div>
          </>
        )}

        {(hasUserAgreement || hasPrivacyPolicy) && (
          <div className='lp-terms-row'>
            <Checkbox checked={agreedToTerms} onChange={(e) => setAgreedToTerms(e.target.checked)}>
              <span className='lp-auth-terms-text'>
                {t('我已阅读并同意')}
                {hasUserAgreement && (
                  <a href='/user-agreement' target='_blank' rel='noopener noreferrer' className='lp-auth-link'> {t('用户协议')}</a>
                )}
                {hasUserAgreement && hasPrivacyPolicy && t('和')}
                {hasPrivacyPolicy && (
                  <a href='/privacy-policy' target='_blank' rel='noopener noreferrer' className='lp-auth-link'> {t('隐私政策')}</a>
                )}
              </span>
            </Checkbox>
          </div>
        )}

        <button
          className='lp-btn-submit'
          onClick={handleSubmit}
          disabled={registerLoading || ((hasUserAgreement || hasPrivacyPolicy) && !agreedToTerms)}
        >
          {registerLoading ? t('注册中...') : t('下一步')}
        </button>

        {hasOAuthRegisterOptions && (
          <>
            <div className='lp-auth-divider'><span>{t('或')}</span></div>
            <button className='lp-btn-other-options' onClick={handleOtherRegisterOptionsClick}>
              {t('其他注册选项')}
            </button>
          </>
        )}

        <div className='lp-benefits'>
          <div className='lp-benefits-title'>注册后您将获得：</div>
          <div className='lp-benefit-item'>使用量统计面板</div>
          <div className='lp-benefit-item'>灵活的订阅方案</div>
          <div className='lp-benefit-item'>200+ 模型一键接入</div>
          <div className='lp-benefit-item'>专属 API Token</div>
        </div>
      </div>
    );
  };

  const renderWeChatLoginModal = () => {
    return (
      <Modal
        title={t('微信扫码登录')}
        visible={showWeChatLoginModal}
        maskClosable={true}
        onOk={onSubmitWeChatVerificationCode}
        onCancel={() => setShowWeChatLoginModal(false)}
        okText={t('登录')}
        centered={true}
        okButtonProps={{
          loading: wechatCodeSubmitLoading,
        }}
      >
        <div className='flex flex-col items-center'>
          <img src={status.wechat_qrcode} alt='微信二维码' className='mb-4' />
        </div>

        <div className='text-center mb-4'>
          <p>
            {t('微信扫码关注公众号，输入「验证码」获取验证码（三分钟内有效）')}
          </p>
        </div>

        <Form>
          <Form.Input
            field='wechat_verification_code'
            placeholder={t('验证码')}
            label={t('验证码')}
            value={inputs.wechat_verification_code}
            onChange={(value) =>
              handleChange('wechat_verification_code', value)
            }
          />
        </Form>
      </Modal>
    );
  };

  return (
    <div className='lp-auth-page' style={{ minHeight: 'calc(100vh - 56px)' }}>
      <div className='lp-auth-main'>
        {showEmailRegister ||
        !hasOAuthRegisterOptions
          ? renderEmailRegisterForm()
          : renderOAuthOptions()}
        {renderWeChatLoginModal()}

        {turnstileEnabled && (
          <div className='flex justify-center mt-6'>
            <Turnstile
              sitekey={turnstileSiteKey}
              onVerify={(token) => {
                setTurnstileToken(token);
              }}
            />
          </div>
        )}
      </div>
    </div>
  );
};

export default RegisterForm;
