import React, { useState, useEffect, useRef } from "react";
import { View, Alert, TextInput } from "react-native";
import { useForm, Controller } from "react-hook-form";

import { MyButton, MyText, MyTextInput, tw, StorageServiceCasual, colors, MyTouchableOpacity } from "common-ui";
import { useAuth } from "@/src/contexts/AuthContext";
import { trpc } from '@/src/trpc-client';
import GoogleSignInPKCE from "common-ui/src/components/google-sign-in";
import { LinearGradient } from "expo-linear-gradient";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import { SafeAreaView } from "react-native-safe-area-context";

interface LoginFormInputs {
  mobile: string;
  otp?: string;
  password?: string;
}

function Login() {
  const { loginWithToken } = useAuth();
  const [isLoading, setIsLoading] = useState(false);
  const [step, setStep] = useState<'mobile' | 'choice' | 'otp' | 'password'>('mobile');
  const [selectedMobile, setSelectedMobile] = useState('');
  const [canResend, setCanResend] = useState(false);
  const [resendCountdown, setResendCountdown] = useState(0);
  const [otpCells, setOtpCells] = useState(['', '', '', '']);
  const intervalRef = useRef<any | null>(null);
  const inputRefs = useRef<(TextInput | null)[]>([null, null, null, null]);

  const loginMutation = trpc.user.auth.login.useMutation();
  // const loginMutation = useLogin();

  // Check for stored OTP timestamp on mount
  useEffect(() => {
    const checkStoredOtpTime = async () => {
      const storedTime = await StorageServiceCasual.getItem('otp_sent_time');
      if (storedTime) {
        const timeDiff = Date.now() - parseInt(storedTime);
        const remainingTime = Math.max(0, 120 - Math.floor(timeDiff / 1000));

        if (remainingTime > 0) {
          setResendCountdown(remainingTime);
          setCanResend(false);
        } else {
          setCanResend(true);
          setResendCountdown(0);
        }
      } else {
        setCanResend(true);
      }
    };

    checkStoredOtpTime();
  }, []);

  // Cleanup interval on unmount
  useEffect(() => {
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
    };
  }, []);

  // Countdown timer effect
  useEffect(() => {
    // Clear existing interval
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      intervalRef.current = null;
    }

    if (resendCountdown > 0) {
      // Set new interval and attach to ref
      intervalRef.current = setInterval(() => {
        setResendCountdown((prev) => {
          if (prev <= 1) {
            setCanResend(true);
            return 0;
          }
          return prev - 1;
        });
      }, 1000);
    }

    return () => {
      // Cleanup on unmount or dependency change
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
    };
  }, [resendCountdown]);



  const sendOtpMutation = trpc.user.auth.sendOtp.useMutation({
    onSuccess: async (data) => {
      if (data.success) {
        // Save the current timestamp for resend cooldown
        await StorageServiceCasual.setItem('otp_sent_time', Date.now().toString());
        setResendCountdown(120); // 2 minutes
        setCanResend(false);
        setStep('otp');
        Alert.alert('Success', data.message);
      } else {
        Alert.alert('Error', data.message);
      }
    },
    onError: (error: any) => {
      Alert.alert('Error', error.message || 'Failed to send OTP');
    },
  });

  const verifyOtpMutation = trpc.user.auth.verifyOtp.useMutation({
    onSuccess: (data) => {
      if (data.success && data.token && data.user) {
        loginWithToken(data.token, data.user);
      } else {
        Alert.alert('Error', 'Verification failed');
      }
    },
    onError: (error: any) => {
      Alert.alert('Error', error.message || 'Invalid OTP');
    },
  });



  const {
    control,
    handleSubmit,
    formState: { errors },
    setError,
    clearErrors,
    setValue,
  } = useForm<LoginFormInputs>({
    defaultValues: { mobile: "", otp: "", password: "" },
  });

  const validateMobile = (mobile: string): boolean => {
    // Remove all non-digit characters
    const cleanMobile = mobile.replace(/\D/g, '');
    // Check if it's a valid Indian mobile number (10 digits, starts with 6-9)
    return cleanMobile.length === 10 && /^[6-9]/.test(cleanMobile);
  };

  const handleOtpChange = (index: number, text: string) => {
    // Handle paste (multiple characters)
    if (text.length > 1) {
      const digits = text.replace(/\D/g, '').slice(0, 4);
      const newCells = digits.split('').concat(['', '', '', '']).slice(0, 4);
      setOtpCells(newCells);
      const combined = newCells.join('');
      setValue('otp', combined);
      // Focus last filled cell
      const lastIndex = Math.min(digits.length - 1, 3);
      inputRefs.current[lastIndex]?.focus();
      return;
    }

    // Handle single digit input
    const newCells = [...otpCells];
    newCells[index] = text;
    setOtpCells(newCells);
    const combined = newCells.join('');
    setValue('otp', combined);

    // Auto-focus logic
    if (text && index < 3) {
      // Move to next cell
      inputRefs.current[index + 1]?.focus();
    } else if (!text && index > 0) {
      // Move to previous cell on delete
      inputRefs.current[index - 1]?.focus();
    }
  };

  const onSubmit = async (data: LoginFormInputs) => {
    clearErrors();

    if (step === 'mobile') {
      const mobile = data.mobile.trim();
      // Validate mobile number
      if (!mobile) {
        console.log('no mobile number found')

        setError("mobile", {
          type: "manual",
          message: "Mobile number is required",
        });
        return;
      }

      if (!validateMobile(data.mobile)) {
        setError("mobile", {
          type: "manual",
          message: "Please enter a valid 10-digit mobile number",
        });
        return;
      }

      const cleanMobile = data.mobile.replace(/\D/g, '');
      setSelectedMobile(cleanMobile);
      sendOtpMutation.mutate({ mobile });
    } else if (step === 'otp') {
      // Verify OTP
      if (!data.otp || data.otp.length < 4) {
        setError("otp", {
          type: "manual",
          message: "Please enter a valid OTP",
        });
        return;
      }

      verifyOtpMutation.mutate({
        mobile: selectedMobile,
        otp: data.otp,
      });
    } else if (step === 'password') {
      // Login with password
      if (!data.password || data.password.length < 6) {
        setError("password", {
          type: "manual",
          message: "Password must be at least 6 characters",
        });
        return;
      }

      try {
        console.log('calling the login function')

        const response = await loginMutation.mutateAsync({
          identifier: selectedMobile,
          password: data.password,
        });
        loginWithToken(response.data.token, response.data.user);
      } catch (error: any) {
        Alert.alert('Error', error.message || 'Login failed');
      }
    }
  };

  return (
    <LinearGradient colors={[colors.brand400, colors.brand700]} style={tw`flex-1`}>
      <SafeAreaView style={tw`flex-1`}>
        <KeyboardAwareScrollView
          contentContainerStyle={tw`flex-grow justify-center p-4`}
          enableOnAndroid={true}
          keyboardShouldPersistTaps="handled"
          extraHeight={100}
          automaticallyAdjustKeyboardInsets={true}
        >
          <View style={tw`mb-8`}>
            <MyText
              weight="bold"
              style={tw`text-4xl mb-2 text-center text-white`}
            >
              Welcome
            </MyText>
            <MyText style={tw`text-lg text-center text-blue-100`}>
              Sign in to continue your journey
            </MyText>
          </View>

          <View style={tw`bg-white rounded-2xl p-8 shadow-xl mb-6 shadow-blue-900/20`}>
            {step === 'mobile' && (
              <>
                <Controller
                  control={control}
                  name="mobile"
                  rules={{
                    required: "Mobile number is required",
                  }}
                  render={({ field: { onChange, onBlur, value } }) => (
                    <View style={tw`mb-5`}>
                      <MyTextInput
                        topLabel="Mobile Number"
                        placeholder="Enter your mobile number"
                        value={value}
                        onChangeText={(text) => {
                          // Format mobile number as user types
                          const clean = text.replace(/\D/g, '');
                          if (clean.length <= 10) {
                            onChange(clean);
                          }
                        }}
                        onBlur={onBlur}
                        keyboardType="phone-pad"
                        maxLength={10}
                        style={tw`bg-gray-50`}
                        error={!!errors.mobile}
                      />
                    </View>
                  )}
                />
                {errors.mobile && (
                  <MyText style={tw`text-red-500 text-sm mb-4 text-center`}>
                    {errors.mobile.message}
                  </MyText>
                )}
              </>
            )}

            {step === 'choice' && (
              <View style={tw`mb-6`}>
                <MyText style={tw`text-center text-gray-600 mb-6 font-medium`}>
                  Choose your login method for {selectedMobile}
                </MyText>
                <View style={tw`flex-row justify-between mb-6`}>
                  <MyButton
                    textContent="Use Password"
                    onPress={() => setStep('password')}
                    fillColor="gray1"
                    textColor="black1"
                    style={tw`flex-1 mr-2 border border-gray-200`}
                  />
                  <MyButton
                    textContent="Use OTP"
                    onPress={() => sendOtpMutation.mutate({ mobile: selectedMobile })}
                    fillColor="brand500"
                    textColor="white1"
                    style={tw`flex-1 ml-2 shadow-sm`}
                    disabled={sendOtpMutation.isPending}
                  />
                </View>
                <MyTouchableOpacity
                  onPress={() => {
                    setStep('mobile');
                    setValue('mobile', '');
                    clearErrors();
                  }}
                  style={tw`mt-2`}
                >
                  <MyText weight="semibold" style={tw`text-brand600 text-center`}>
                    Change Number
                  </MyText>
                </MyTouchableOpacity>
              </View>
            )}

            {step === 'otp' && (
              <>
                <View style={tw`mb-6`}>
                  <MyText
                    weight="semibold"
                    style={tw`text-base mb-3 text-gray-800 text-center`}
                  >
                    Enter 4-digit OTP
                  </MyText>
                  <View style={tw`flex-row justify-center gap-2`}>
                    {[0, 1, 2, 3].map((i) => (
                      <TextInput
                        key={i}
                        ref={(ref) => { inputRefs.current[i] = ref; }}
                        style={tw`w-14 h-14 ${errors.otp ? 'border-red-500' : 'border-gray-200'} border-2 rounded-xl text-center text-2xl font-bold ${otpCells[i] ? 'bg-blue-50 border-brand500 text-brand700' : 'bg-gray-50'}`}
                        keyboardType="numeric"
                        maxLength={1}
                        value={otpCells[i]}
                        onChangeText={(text) => handleOtpChange(i, text)}
                        selectionColor={colors.brand500}
                      />
                    ))}
                  </View>
                </View>
                {errors.otp && (
                  <MyText style={tw`text-red-500 text-sm mb-4 text-center`}>
                    {errors.otp.message}
                  </MyText>
                )}

                <MyTouchableOpacity
                  onPress={() => {
                    setStep('password');
                    setValue('otp', '');
                    setOtpCells(['', '', '', '']);
                    clearErrors();
                  }}
                  style={tw`mb-6`}
                >
                  <MyText weight="semibold" style={tw`text-brand600 text-center`}>
                    Or login with Password
                  </MyText>
                </MyTouchableOpacity>

                <View style={tw`flex-row justify-between items-center mt-2 pt-4 border-t border-gray-100`}>
                  <MyTouchableOpacity
                    onPress={() => {
                      setStep('choice');
                      setValue('otp', '');
                      setOtpCells(['', '', '', '']);
                      clearErrors();
                    }}
                  >
                    <MyText weight="medium" style={tw`text-gray-500`}>
                      Back
                    </MyText>
                  </MyTouchableOpacity>

                  <MyTouchableOpacity
                    onPress={() => sendOtpMutation.mutate({ mobile: selectedMobile })}
                    disabled={!canResend || sendOtpMutation.isPending}
                  >
                    <MyText
                      weight="semibold"
                      style={tw`${canResend && !sendOtpMutation.isPending ? 'text-brand600' : 'text-gray-400'}`}
                    >
                      {sendOtpMutation.isPending
                        ? 'Sending...'
                        : canResend
                          ? 'Resend OTP'
                          : `Resend in ${resendCountdown}s`
                      }
                    </MyText>
                  </MyTouchableOpacity>
                </View>
              </>
            )}

            {step === 'password' && (
              <>
                <Controller
                  control={control}
                  name="password"
                  rules={{ required: "Password is required" }}
                  render={({ field: { onChange, onBlur, value } }) => (
                    <View style={tw`mb-4`}>
                      <MyTextInput
                        topLabel="Password"
                        placeholder="Enter your password"
                        value={value}
                        onChangeText={onChange}
                        onBlur={onBlur}
                        secureTextEntry
                        style={tw`bg-gray-50`}
                        error={!!errors.password}
                      />
                    </View>
                  )}
                />
                {errors.password && (
                  <MyText style={tw`text-red-500 text-sm mb-4 text-center`}>
                    {errors.password.message}
                  </MyText>
                )}

                <View style={tw`flex-row justify-center mb-6`}>
                  <MyTouchableOpacity
                    onPress={() => {
                      setStep('choice');
                      setValue('password', '');
                      clearErrors();
                    }}
                  >
                    <MyText weight="semibold" style={tw`text-gray-500 font-medium`}>
                      Back to options
                    </MyText>
                  </MyTouchableOpacity>
                </View>
              </>
            )}

            {(step === 'mobile' || step === 'otp' || step === 'password') && (
              <View style={tw`mt-4`}>
                <MyButton
                  onPress={handleSubmit(onSubmit)}
                  fillColor="brand600"
                  textColor="white1"
                  fullWidth
                  disabled={
                    isLoading ||
                    sendOtpMutation.isPending ||
                    verifyOtpMutation.isPending ||
                    loginMutation.isPending
                  }
                  style={tw`rounded-xl h-12 shadow-lg shadow-blue-500/30`}
                >
                  {isLoading || sendOtpMutation.isPending || verifyOtpMutation.isPending || loginMutation.isPending
                    ? (step === 'otp' ? "Verifying..." : step === 'password' ? "Logging in..." : "Processing...")
                    : (step === 'otp' ? "Verify & Login" : step === 'password' ? "Login" : "Continue")}
                </MyButton>
              </View>
            )}
          </View>
        </KeyboardAwareScrollView>
      </SafeAreaView>
    </LinearGradient>
  );
}

export default Login;