import React, {
  useCallback,
  useEffect,
  useLayoutEffect,
  useMemo,
  useState,
} from 'react';
import {
  Image,
  Keyboard,
  SafeAreaView,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { StackScreenProps } from '@react-navigation/stack';
import { useHeaderHeight } from '@react-navigation/elements';
import { LoginParamList } from '@app/routes/login/LoginParamList.ts';
import SubmitButton from '@common/components/SubmitButton';
import { useQuickClicks } from '@szyx-mobile/hooks';
import LoginTextInputItem from '../components/LoginTextInputItem';
import AgreementChecking from '../components/AgreementChecking';
import { useSMSVerifyCode } from '../api';
import Spinner from '@common/components/Spinner';
import { PHONE_PATTERN } from '@common/constants';
import { useLoginWithPassword } from './api';
import { useCommon } from '@common/contexts/useCommon';
import LinearGradient from 'react-native-linear-gradient';
import { ValidationError } from '@szyx-mobile/use-axios';
import { RequestError } from '@szyx-mobile/use-request';
import { useLogin } from '@app/hooks/useLogin';
import { showErrorMessage, showMessage } from '@common/ToastHelper.ts';
import Alert from '@common/components/Alert.tsx';

const USER_NOT_FOUND = '017x003';
const USER_NOT_REGISTER = '017x036';

type Props = StackScreenProps<LoginParamList, 'Login'>;

export default function LoginScreen(props: Props) {
  const {navigation} = props;
  const headerHeight = useHeaderHeight();

  useLayoutEffect(() => {
    navigation.setOptions({
      title: '',
      headerTransparent: true,
    });
  }, [navigation]);

  const {click} = useQuickClicks(10, () => {
    navigation.navigate('Environment');
  });

  const login = useLogin();

  const {
    state: {info},
  } = useCommon();

  // 如果用户协议没有同意，则展示用户协议同意页
  useEffect(() => {
    if (info.policyAccepted !== true) {
      navigation.navigate('Agreement');
    }
  }, [info.policyAccepted, navigation]);

  // 【工具函数】

  // 将手机号格式化成中间有空格的样式
  const formatPhoneNumber = (text: string) => {
    // 移除所有非数字字符
    const cleaned = ('' + text).replace(/\D/g, '');

    // 分段格式化
    let formatted = '';
    if (cleaned.length > 0) {
      formatted = cleaned.slice(0, 3);
    }
    if (cleaned.length >= 4) {
      formatted += ' ' + cleaned.slice(3, 7);
    }
    if (cleaned.length >= 8) {
      formatted += ' ' + cleaned.slice(7, 11);
    }

    return formatted;
  };

  const handleChange = (text: string) => {
    const formatted = formatPhoneNumber(text);
    setPhone(formatted);
  };

  // 【状态】

  const [loginType, setLoginType] = useState<'sms' | 'password'>('sms'); // 登录类型
  const [phone, setPhone] = useState(
    info.lastLoginPhoneNumber
      ? formatPhoneNumber(info.lastLoginPhoneNumber)
      : '',
  ); // 手机号（用作展示，包含空格）
  const [password, setPassword] = useState(''); // 密码
  const [agreementChecked, setAgreementChecked] = useState(false); // 是否同意隐私声明

  const phoneNumber = useMemo(() => {
    return phone.replace(/\s+/g, '');
  }, [phone]); // 去掉空格后的手机号

  // 【接口】
  const {loading: verifyCodeLoading, fetchAsync: verifyCodeFetch} =
    useSMSVerifyCode(phoneNumber, loginType === 'sms' ? 'login' : 'reset'); // 注意：这里的获取验证码的类型根据登录类型确定。如果是验证码登录，则这里是登录类型；如果是密码登录，则只可能是点击忘记密码获取的验证码，因此是重置密码类型
  const {loading: loginLoading, fetchAsync: loginFetch} = useLoginWithPassword(
    phoneNumber,
    password,
  ); // 账号密码登录

  // 处理需要注册的登录错误 - 用不不存在
  const handleLoginErrorNotFound = useCallback(() => {
    Alert.show(
      '温馨提示',
      <View>
        <Text style={styles.alertText}>用户不存在，是否立即注册？</Text>
        <Text style={styles.alertSubText}>
          电子签名用户请联系管理员注册，请勿自行注册
        </Text>
      </View>,
      {
        title: '立即注册',
        action: () => {
          navigation.navigate('Register');
        },
      },
      {
        title: '重新输入',
      },
    );
    return;
  }, [navigation]);

  // 处理需要注册的登录错误 - 用户手机号非注册手机号为关联手机号
  const handleLoginErrorNotRegister = useCallback(
    (message?: string) => {
      Alert.show(
        '温馨提示',
        <View>
          <Text style={styles.alertText}>{message ?? ''}</Text>
        </View>,
        {
          title: '更换手机号',
          action: () => {
            navigation.navigate('ChangePhone');
          },
        },
        {
          title: '我知道了',
        },
      );
      return;
    },
    [navigation],
  );

  return (
    <View style={styles.container}>
      <LinearGradient
        style={styles.background}
        colors={['rgba(197, 234, 255, 1)', 'rgba(197, 234, 255, 0)']}
      />
      <ScrollView
        style={styles.scroll}
        scrollIndicatorInsets={{right: 1}}
        keyboardShouldPersistTaps={'handled'}>
        <TouchableOpacity
          style={[styles.header, {marginTop: headerHeight}]}
          activeOpacity={1}
          onPress={() => {
            click();
          }}>
          <Image
            style={styles.logo}
            source={require('@app/assets/images/login/login_logo.png')}
          />
          <Text style={styles.title}>欢迎使用医网信</Text>
        </TouchableOpacity>
        <SafeAreaView>
          <View>
            <LoginTextInputItem
              placeholder="请输入手机号"
              keyboardType="phone-pad"
              maxLength={13}
              value={phone}
              onChangeText={value => {
                handleChange(value);
              }}
              clearButton={true}
            />
            {loginType === 'password' && (
              <LoginTextInputItem
                placeholder="请输入密码"
                keyboardType="ascii-capable"
                secureTextEntry={true}
                maxLength={12}
                value={password}
                onChangeText={value => {
                  setPassword(value);
                }}
                clearButton={true}
                rightButton={{
                  title: '忘记密码',
                  color: '#302F57',
                  onPress: () => {
                    if (PHONE_PATTERN.test(phoneNumber) === false) {
                      showErrorMessage('请输入正确的手机号码');
                      return;
                    }
                    Keyboard.dismiss();
                    verifyCodeFetch()
                      .then(() => {
                        navigation.navigate('ForgotPassword', {
                          phoneNumber: phoneNumber,
                        });
                      })
                      .catch(e => {
                        showErrorMessage(e.message);
                      });
                  },
                }}
              />
            )}
          </View>
          <AgreementChecking
            checked={agreementChecked}
            onPress={() => {
              setAgreementChecked(checked => !checked);
            }}
          />
          <SubmitButton
            style={styles.loginButton}
            title={loginType === 'sms' ? '获取验证码' : '登录'}
            theme="dark"
            disabled={
              phone.length !== 13 ||
              agreementChecked === false ||
              (loginType === 'password' && password.length === 0)
            }
            onPress={() => {
              if (PHONE_PATTERN.test(phoneNumber) === false) {
                showErrorMessage('请输入正确的手机号码');
                return;
              }

              if (loginType === 'password') {
                // 前端登录时候不校验密码规则，只在注册和重置密码的时候校验
                Keyboard.dismiss();
                // 登录逻辑
                loginFetch()
                  .then(r => {
                    showMessage('登录成功');
                    login(r.sessionId, {
                      userId: r.userId,
                      userType: r.userType,
                      moduleList: [],
                      isFirstLogin: true,
                      currentUserType:
                        r.userType === 'general' ? 'general' : 'guanxin',
                      realNameStatus: r.realNameStatus,
                      enableCert: r.enableCert,
                      phone: phoneNumber,
                      gxLeader: r.gxLeader,
                      hasBindFirm: r.hasBindFirm,
                      hasFaceDetect: r.hasFaceDetect,
                      nickname: undefined,
                      picUrl: undefined,
                      faceDetectFirms: undefined,
                      userIdCardNum: undefined,
                    });
                  })
                  .catch(e => {
                    if (
                      e instanceof RequestError &&
                      e.type === 'ValidationError' &&
                      e.error instanceof ValidationError
                    ) {
                      if (e.error.response.data?.status === USER_NOT_FOUND) {
                        handleLoginErrorNotFound();
                        return;
                      }
                      if (e.error.response.data?.status === USER_NOT_REGISTER) {
                        handleLoginErrorNotRegister(
                          e.error.response.data?.message,
                        );
                        return;
                      }
                    }
                    showErrorMessage(e.message);
                  });
              } else {
                Keyboard.dismiss();
                verifyCodeFetch()
                  .then(() => {
                    navigation.navigate('LoginWithSMS', {
                      phoneNumber: phoneNumber,
                    });
                  })
                  .catch(e => {
                    if (
                      e instanceof RequestError &&
                      e.type === 'ValidationError' &&
                      e.error instanceof ValidationError
                    ) {
                      if (e.error.response.data?.status === '017x003') {
                        handleLoginErrorNotFound();
                        return;
                      }
                      if (e.error.response.data?.status === USER_NOT_REGISTER) {
                        handleLoginErrorNotRegister(
                          e.error.response.data?.message,
                        );
                        return;
                      }
                    }
                    showErrorMessage(e.message);
                  });
              }
            }}
          />
          {/* 切换登录和快速注册 */}
          <View style={styles.bottom}>
            <TouchableOpacity
              onPress={() => {
                Keyboard.dismiss();
                setLoginType(type => {
                  if (type === 'sms') {
                    return 'password';
                  }
                  return 'sms';
                });
                setPassword('');
              }}>
              <Text style={styles.bottomText}>
                {loginType === 'sms' ? '密码登录' : '验证码登录'}
              </Text>
            </TouchableOpacity>
            <Text style={styles.bottomText}>{' ｜ '}</Text>
            <TouchableOpacity
              onPress={() => {
                Keyboard.dismiss();
                navigation.navigate('Register');
              }}>
              <Text style={styles.bottomText}>快速注册</Text>
            </TouchableOpacity>
          </View>
        </SafeAreaView>
      </ScrollView>
      {(verifyCodeLoading || loginLoading) && <Spinner />}
    </View>
  );
}

const styles = StyleSheet.create({
  alertText: {
    textAlign: 'center',
    color: '#333333',
    fontSize: 14,
  },
  alertSubText: {
    textAlign: 'center',
    color: '#E51C23',
    fontSize: 10,
    marginTop: 4,
  },
  container: {
    flex: 1,
    backgroundColor: '#FFFFFF',
  },
  background: {
    position: 'absolute',
    left: 0,
    top: 0,
    right: 0,
    height: 168,
  },
  scroll: {
    flex: 1,
  },
  header: {
    paddingHorizontal: 25,
    marginBottom: 35,
    alignItems: 'center',
  },
  logo: {
    width: 75,
    height: 75,
    marginBottom: 10,
  },
  title: {
    fontSize: 24,
    color: '#17171A',
    fontWeight: '600',
  },
  loginButton: {
    marginHorizontal: 25,
    marginBottom: 20,
    marginTop: 20,
  },
  bottom: {
    flexDirection: 'row',
    justifyContent: 'center',
    marginBottom: 64,
  },
  bottomText: {
    color: '#666666',
    fontSize: 14,
  },
});
