import type { CaptchaRes } from '@/components/captcha-box';
import CaptchaBox from '@/components/captcha-box';
import { site } from '@/config.json';
import { useInterval } from '@/hooks/hooks';
import api, { ApiError } from '@/utils/api';
import { signIn, smsSignIn, useAuth } from '@/utils/auth';
import { Button, Toast } from '@ant-design/react-native';
import { Ionicons } from '@expo/vector-icons';
import { Link, router, useLocalSearchParams } from 'expo-router';
import { openBrowserAsync } from 'expo-web-browser';
import React, { useEffect, useRef, useState } from 'react';
import {
  KeyboardAvoidingView,
  Platform,
  Pressable,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  View
} from 'react-native';
import Animated, {
  interpolateColor,
  useAnimatedStyle,
  useSharedValue,
  withSequence,
  withTiming,
} from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

function FieldLabel({ children }: { children: React.ReactNode }) {
  return (
    <Text className="mb-2 ml-1 text-xs font-bold uppercase tracking-widest text-outline">
      {children}
    </Text>
  );
}

export default function SignInScreen() {
  const [authMode, setAuthMode] = useState<'sms' | 'password'>('sms');
  const [agreed, setAgreed] = useState(false);
  const [agreementHighlight, setFlushAgree] = useState(false);
  const [loading, setLoading] = useState(false);
  const [mobile, setMobile] = useState('');
  const [code, setCode] = useState('');
  const [password, setPassword] = useState('');

  const { redirectTo } = useLocalSearchParams<{ redirectTo?: string }>();
  const { setToken } = useAuth();
  const scrollViewRef = useRef<ScrollView>(null);

  const agreeHighlight = useSharedValue(0);
  useEffect(() => {
    if (agreementHighlight) {
      agreeHighlight.value = withSequence(
        withTiming(1, { duration: 140 }),
        withTiming(0, { duration: 140 }),
        withTiming(1, { duration: 140 }),
        withTiming(0, { duration: 140 }),
        withTiming(1, { duration: 200 }),
      );
    } else {
      agreeHighlight.value = withTiming(0, { duration: 200 });
    }
  }, [agreementHighlight, agreeHighlight]);

  const agreeBoxStyle = useAnimatedStyle(() => ({
    borderColor: interpolateColor(
      agreeHighlight.value,
      [0, 1],
      ['rgba(37, 99, 235, 0)', 'rgba(37, 99, 235, 0.5)'],
    ),
  }));

  const [captchaVisible, setCaptchaVisible] = useState<boolean>(false);
  const [smsTtl, setSmsTtl] = useState(0);


  const waitCaptcha = useRef<(res: CaptchaRes) => void | null>(null);
  const needsCaptchaRef = useRef(false);
  const handleCaptcha = (res: CaptchaRes) => {
    const resolver = waitCaptcha.current;
    waitCaptcha.current = null;
    setCaptchaVisible(false);
    resolver?.(res);
  };
  const handleSendCode = async () => {
    if (mobile.trim().length !== 11) {
      Toast.fail('请先输入 11 位手机号');
      return;
    }
    let captcha: CaptchaRes = null!;
    while (true) {
      if (needsCaptchaRef.current) {
        setCaptchaVisible(true);
        captcha = await new Promise<CaptchaRes>((resolve) => {
          waitCaptcha.current = resolve;
        });
        if (!captcha || !captcha.ok) {
          return;
        }
      }
      try {
        const res = await api.post<{
          needsCaptcha?: boolean;
          timerout: number;
        }>(`sms/send?__session_id=${captcha?.sid ?? ''}`, {
          mobile: mobile,
          event: 'login',
          captcha_code: captcha?.code,
        });

        if (res.needsCaptcha) {
          needsCaptchaRef.current = true;
          continue;
        }
        setSmsTtl(res.timerout); // 后端字段拼写为 timerout，保留以兼容接口
        break;

      } catch (e) {
        if (ApiError.isApiError(e)) {
          if (e.code === -1) {
            Toast.fail("该手机已被注册");
            return;
          }
          if (e.code === -99) {
            Toast.fail("图形验证码无效");
            return;
          }
        }
        Toast.fail("发送验证码失败");
        return;
      }
    }
  };


  useInterval(() => {
    setSmsTtl((prev) => prev - 1)
  }, smsTtl > 0 ? 1000 : null);



  const handleLogin = async () => {
    setFlushAgree(false);
    scrollViewRef.current?.scrollTo({ y: 0, animated: true });
    if (mobile.trim().length !== 11) {
      Toast.fail('请输入正确的手机号');
      return;
    }


    if (authMode === 'sms' && code.trim().length !== 6) {
      Toast.fail('请输入 6 位验证码');
      return;
    }

    if (authMode === 'password' && password.length < 6) {
      Toast.fail('请输入不少于 6 位的密码');
      return;
    }

    if (!agreed) {
      scrollViewRef.current?.scrollToEnd({ animated: true });
      setFlushAgree(true);
      Toast.fail('请先阅读并同意协议');
      return;
    }


    setLoading(true);

    try {
      const token = authMode === 'sms' ? await smsSignIn(mobile, code) : await signIn(mobile, password);
      setToken(token);
      Toast.success('登录成功');

      if (redirectTo) {
        router.replace(redirectTo as never);
      } else {
        router.canGoBack() ? router.back() : router.replace('/');
      }
    } catch (error) {
      console.error('登录失败:', error);
      Toast.fail('登录失败，请稍后重试');
    } finally {
      setLoading(false);
    }
  };

  const insets = useSafeAreaInsets();
  return (
    <View className="flex-1 bg-surface">
      <KeyboardAvoidingView
        className="flex-1"
        behavior={Platform.OS === 'ios' ? 'padding' : undefined}
      >
        <ScrollView
          ref={scrollViewRef}
          className="flex-1"
          contentContainerClassName="px-8"
          keyboardShouldPersistTaps="handled"
          showsVerticalScrollIndicator={false}
        >
          <View className="absolute -top-24 -right-24 h-96 w-96 rounded-full bg-primary-container/10" />
          <View className="absolute top-32 -left-20 h-64 w-64 rounded-full bg-secondary-container/20" />
          <View className="absolute -bottom-16 right-0 h-48 w-48 rounded-full bg-primary-fixed/50" />

          <View className="flex-1 justify-between"
            style={{ paddingTop: (insets.top ?? 10) + 52, paddingBottom: (insets.bottom ?? 8) + 24 }}>
            <View>
              <View className="mb-6">
                <View className="mb-3 h-16 w-16 items-center justify-center rounded-2xl bg-primary-container shadow-lg">
                  <Ionicons name="business" size={30} color="#ffffff" />
                </View>
                <Text className="mb-2 text-4xl font-extrabold tracking-tight text-on-surface">
                  欢迎回来
                </Text>
                <Text className="text-base font-medium leading-6 text-on-surface-variant">
                  登录贷款助手，开启您的
                </Text>
              </View>

              <View className="mb-8 rounded-2xl bg-surface-container-lowest p-3 shadow-sm">
                <View className="mb-6 flex-row rounded-2xl bg-surface-container-low p-1">
                  {[
                    ['sms', '验证码登录'],
                    ['password', '密码登录'],
                  ].map(([mode, label]) => {
                    const active = authMode === mode;
                    return (
                      <Pressable
                        key={mode}
                        disabled={loading}
                        onPress={() => setAuthMode(mode as 'sms' | 'password')}
                        className={`flex-1 rounded-xl px-4 py-3 ${active ? 'bg-surface-container-lowest' : ''
                          }`}
                        style={({ pressed }) => ({
                          opacity: loading ? 0.5 : pressed ? 0.86 : 1,
                          transform: [{ scale: pressed ? 0.99 : 1 }],
                        })}
                      >
                        <Text
                          className={`text-center text-base font-bold ${active ? 'text-primary' : 'text-on-surface-variant'
                            }`}
                        >
                          {label}
                        </Text>
                      </Pressable>
                    );
                  })}
                </View>

                <View className="px-2 pb-2">
                  <FieldLabel>手机号码</FieldLabel>
                  <View className="mb-5 flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
                    <Text className="text-2xl font-bold text-on-surface">+86</Text>
                    <View
                      className="mx-4 h-5 bg-outline-variant/40"
                      style={{ width: StyleSheet.hairlineWidth }}
                    />
                    <TextInput
                      value={mobile}
                      onChangeText={setMobile}
                      editable={!loading}
                      keyboardType="phone-pad"
                      maxLength={11}
                      placeholder="请输入手机号"
                      placeholderTextColor="#9ca3af"
                      className="flex-1 p-0 text-xl font-medium text-on-surface"
                    />
                    <Ionicons
                      name="phone-portrait-outline"
                      size={22}
                      color="#c3c6d7"
                    />
                  </View>

                  <FieldLabel>{authMode === 'sms' ? '验证码' : '密码'}</FieldLabel>
                  <View className="flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
                    <TextInput
                      value={authMode === 'sms' ? code : password}
                      onChangeText={authMode === 'sms' ? setCode : setPassword}
                      editable={!loading}
                      keyboardType={authMode === 'sms' ? 'number-pad' : 'default'}
                      maxLength={authMode === 'sms' ? 6 : 20}
                      secureTextEntry={authMode === 'password'}
                      placeholder={
                        authMode === 'sms'
                          ? '请输入 6 位验证码'
                          : '请输入 6-20 位登录密码'
                      }
                      placeholderTextColor="#9ca3af"
                      className="flex-1 p-0 text-xl font-medium text-on-surface"
                    />
                    {authMode === 'sms' ? (
                      <Pressable
                        disabled={loading || smsTtl > 0}
                        hitSlop={8}
                        onPress={handleSendCode}

                      >
                        <Text className={`text-lg w-22 text-center font-bold leading-6 ${loading || smsTtl > 0 ? 'text-on-secondary-fixed/50' : 'text-primary'}`}>
                          {smsTtl > 0 ? `${smsTtl}s` : '发送验证码'}
                        </Text>
                      </Pressable>
                    ) : (
                      <Ionicons name="lock-closed-outline" size={22} color="#c3c6d7" />
                    )}
                  </View>
                </View>
              </View>

              <View className="mb-6 gap-3">
                <Button type='primary' loading={loading} onPress={handleLogin}>登录</Button>

                <View className="flex-row items-center justify-between px-3">
                  <Pressable hitSlop={8} onPress={() => router.push({ pathname: '/sign-up', params: { signIn: 1, redirectTo } })}>
                    <Text className="text-lg font-medium text-on-surface-variant">
                      注册账号
                    </Text>
                  </Pressable>
                  <Pressable hitSlop={8}>
                    <Text className="text-lg font-medium text-on-surface-variant">
                      遇到问题？
                    </Text>
                  </Pressable>
                </View>
              </View>
            </View>

            <View className="pt-1">
              <View className="mb-5 flex-row items-center gap-3">
                <View className="h-px flex-1 bg-surface-container-highest" />
                <Text className="text-sm font-bold tracking-widest text-outline">
                  其他方式登录
                </Text>
                <View className="h-px flex-1 bg-surface-container-highest" />
              </View>

              <View className="mb-6 flex-row justify-center gap-8">
                {[
                  ['chatbubble-ellipses-outline', '#6b7280'],
                  ['logo-apple', '#6b7280'],
                ].map(([icon, color]) => (
                  <Pressable
                    key={icon}
                    className="h-14 w-14 items-center justify-center rounded-full bg-surface-container-low"
                    style={({ pressed }) => ({
                      opacity: pressed ? 0.8 : 1,
                      transform: [{ scale: pressed ? 0.94 : 1 }],
                    })}
                  >
                    <Ionicons
                      name={icon as keyof typeof Ionicons.glyphMap}
                      size={24}
                      color={color}
                    />
                  </Pressable>
                ))}
              </View>

              <Animated.View
                style={agreeBoxStyle}
                className="flex-row items-start gap-3 px-2 rounded-lg border-2"
              >
                <Pressable
                  onPress={() => setAgreed((value) => !value)}
                  hitSlop={8}
                  className="pt-1"
                >
                  <View
                    className={`h-6 w-6 mt-2 items-center justify-center border-2 border-primary/50 rounded-full cursor-pointer ${agreed
                      ? 'border-primary bg-primary'
                      : 'border-outline-variant bg-surface-container-low'
                      }`}
                  >
                    {agreed ? (
                      <Ionicons name="checkmark" size={14} color="#ffffff" />
                    ) : null}
                  </View>
                </Pressable>
                <Text className="flex-1 text-sm leading-6 text-on-surface-variant">
                  登录即代表您已阅读并同意
                  <Link href={{
                    pathname: '/web',
                    params: { uri: site }
                  }}>
                    <Text className="font-semibold text-primary">《用户服务协议》</Text>
                  </Link>
                  、
                  <Text className="font-semibold text-primary cursor-pointer" onPress={() => openBrowserAsync(`${site}`)}>《隐私政策》</Text>
                  ，以及授权该应用获取您的公开信息。
                </Text>
              </Animated.View>
            </View>
          </View>
        </ScrollView>
      </KeyboardAvoidingView>
      <CaptchaBox visible={captchaVisible} onClose={handleCaptcha} />
      {loading && <View className="absolute left-0 right-0 top-0 bottom-0 z-1 bg-white/5" />}
    </View>
  );
}
