import { ComponentType, FC, useCallback, useEffect, useMemo, useRef, useState } from "react"
// eslint-disable-next-line no-restricted-imports
import { Image, ImageStyle, TextInput, TextStyle, View, ViewStyle } from "react-native"
import { useFocusEffect } from "@react-navigation/native"

import { Button } from "@/components/Button"
import { Icon, PressableIcon } from "@/components/Icon"
import { Screen } from "@/components/Screen"
import { Text } from "@/components/Text"
import { TextField, type TextFieldAccessoryProps } from "@/components/TextField"
import { useAuth } from "@/context/AuthContext"
import type { AppStackScreenProps } from "@/navigators/navigationTypes"
import { useAppTheme } from "@/theme/context"
import type { ThemedStyle } from "@/theme/types"
import { s } from "@/utils/responsive"

interface LoginScreenProps extends AppStackScreenProps<"Login"> {}

export const LoginScreen: FC<LoginScreenProps> = ({ navigation }) => {
  const authPasswordInput = useRef<TextInput>(null)
  const verificationCodeInput = useRef<TextInput>(null)

  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")
  const [verificationCode, setVerificationCode] = useState("")
  const [isPasswordHidden, setIsPasswordHidden] = useState(true)
  const [resendCountdown, setResendCountdown] = useState(0)

  const {
    loginStep,
    pendingEmail,
    isLoading,
    error,
    preLogin,
    resendCode,
    verifyLogin,
    googleLogin,
    resetLoginStep,
    clearError,
  } = useAuth()

  const {
    themed,
    theme: { colors },
  } = useAppTheme()

  // Email validation
  const emailError = useMemo(() => {
    if (!email || email.length === 0) return ""
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) return "Please enter a valid email"
    return ""
  }, [email])

  // Password validation - requires uppercase, lowercase, number, and special character
  const passwordError = useMemo(() => {
    if (!password || password.length === 0) return ""
    if (password.length < 8) return "Password must be at least 8 characters"
    if (!/[A-Z]/.test(password)) return "Password must contain an uppercase letter"
    if (!/[a-z]/.test(password)) return "Password must contain a lowercase letter"
    if (!/[0-9]/.test(password)) return "Password must contain a number"
    if (!/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password))
      return "Password must contain a special character"
    return ""
  }, [password])

  // Countdown timer for resend button
  useEffect(() => {
    if (resendCountdown > 0) {
      const timer = setTimeout(() => setResendCountdown(resendCountdown - 1), 1000)
      return () => clearTimeout(timer)
    }
    return undefined
  }, [resendCountdown])

  // Auto-focus verification code input when entering verification step
  useEffect(() => {
    if (loginStep === "verification") {
      // Small delay to ensure the input is rendered
      const timer = setTimeout(() => {
        verificationCodeInput.current?.focus()
      }, 100)
      return () => clearTimeout(timer)
    }
    return undefined
  }, [loginStep])

  // Reset state when screen comes into focus (e.g., navigating back from another screen)
  useFocusEffect(
    useCallback(() => {
      // Clear any lingering errors from previous screens
      clearError()
      // Reset countdown and verification code when screen is focused
      // but only if we're on credentials step (not in the middle of verification)
      if (loginStep === "credentials") {
        setResendCountdown(0)
        setVerificationCode("")
      }
    }, [loginStep, clearError]),
  )

  // Clear error when inputs change (not when error changes)
  const prevInputsRef = useRef({ email, password, verificationCode })
  useEffect(() => {
    const prev = prevInputsRef.current
    // Only clear error if one of the input fields actually changed
    if (
      prev.email !== email ||
      prev.password !== password ||
      prev.verificationCode !== verificationCode
    ) {
      if (error) clearError()
      prevInputsRef.current = { email, password, verificationCode }
    }
  }, [email, password, verificationCode, error, clearError])

  // Handle pre-login (step 1)
  const handlePreLogin = useCallback(async () => {
    if (!email || emailError || !password) return

    const success = await preLogin(email, password)
    if (success) {
      setResendCountdown(60)
    }
  }, [email, emailError, password, preLogin])

  // Handle verify login (step 2)
  const handleVerifyLogin = useCallback(async () => {
    if (!verificationCode || verificationCode.length !== 6) return

    await verifyLogin(verificationCode)
  }, [verificationCode, verifyLogin])

  // Handle resend code
  const handleResendCode = useCallback(async () => {
    if (resendCountdown > 0) return

    const success = await resendCode()
    if (success) {
      setResendCountdown(60)
    }
  }, [resendCountdown, resendCode])

  // Handle Google login
  const handleGoogleLogin = useCallback(async () => {
    await googleLogin()
  }, [googleLogin])

  // Handle back to credentials step
  const handleBackToCredentials = useCallback(() => {
    resetLoginStep()
    setVerificationCode("")
  }, [resetLoginStep])

  // Navigate to register
  const handleGoToRegister = useCallback(() => {
    navigation.navigate("Register")
  }, [navigation])

  // Navigate to forgot password
  const handleGoToForgotPassword = useCallback(() => {
    navigation.navigate("ForgotPassword")
  }, [navigation])

  // Password visibility toggle
  const PasswordRightAccessory: ComponentType<TextFieldAccessoryProps> = useMemo(
    () =>
      function PasswordRightAccessory(props: TextFieldAccessoryProps) {
        return (
          <PressableIcon
            icon={isPasswordHidden ? "view" : "hidden"}
            color={colors.palette.neutral800}
            containerStyle={props.style}
            size={s(20)}
            onPress={() => setIsPasswordHidden(!isPasswordHidden)}
          />
        )
      },
    [isPasswordHidden, colors.palette.neutral800],
  )

  // Render credentials step (step 1)
  const renderCredentialsStep = () => (
    <>
      <Text testID="login-heading" text="Log In" preset="heading" style={themed($logIn)} />
      <Text
        text="Enter your credentials to continue"
        preset="subheading"
        style={themed($enterDetails)}
      />

      {error ? <Text text={error} size="sm" style={themed($errorText)} /> : null}

      <TextField
        value={email}
        onChangeText={setEmail}
        containerStyle={themed($textField)}
        autoCapitalize="none"
        autoComplete="email"
        autoCorrect={false}
        keyboardType="email-address"
        label="Email"
        placeholder="Enter your email"
        helper={emailError}
        status={emailError ? "error" : undefined}
        onSubmitEditing={() => authPasswordInput.current?.focus()}
      />

      <TextField
        ref={authPasswordInput}
        value={password}
        onChangeText={setPassword}
        containerStyle={themed($textField)}
        autoCapitalize="none"
        autoComplete="password"
        autoCorrect={false}
        secureTextEntry={isPasswordHidden}
        label="Password"
        placeholder="Enter your password"
        helper={passwordError}
        status={passwordError ? "error" : undefined}
        onSubmitEditing={handlePreLogin}
        RightAccessory={PasswordRightAccessory}
      />

      <View style={themed($forgotPasswordContainer)}>
        <Button
          testID="forgot-password-button"
          text="Forgot Password?"
          preset="link"
          onPress={handleGoToForgotPassword}
        />
      </View>

      <Button
        testID="login-button"
        text="Log In"
        style={themed($tapButton)}
        preset="reversed"
        onPress={handlePreLogin}
        disabled={isLoading || !email || !!emailError || !password || !!passwordError}
        loading={isLoading}
      />

      <View style={themed($dividerContainer)}>
        <View style={themed($dividerLine)} />
        <Text text="OR" size="xs" style={themed($dividerText)} />
        <View style={themed($dividerLine)} />
      </View>

      <Button
        testID="google-login-button"
        style={themed($googleButton)}
        preset="default"
        onPress={handleGoogleLogin}
        disabled={isLoading}
        LeftAccessory={() => (
          <Image source={require("@assets/images/google-logo.png")} style={themed($googleLogo)} />
        )}
      >
        <Text text="Continue with Google" style={themed($googleButtonText)} />
      </Button>

      <View style={themed($registerLinkContainer)}>
        <Text text="Don't have an account? " size="sm" />
        <Button
          testID="go-to-register-button"
          text="Register"
          preset="link"
          onPress={handleGoToRegister}
        />
      </View>
    </>
  )

  // Render verification step (step 2)
  const renderVerificationStep = () => (
    <>
      <Text
        testID="verification-heading"
        text="Verify Your Email"
        preset="heading"
        style={themed($logIn)}
      />
      <Text
        text={`We've sent a verification code to ${pendingEmail}`}
        preset="subheading"
        style={themed($enterDetails)}
      />

      {error ? <Text text={error} size="sm" style={themed($errorText)} /> : null}

      <TextField
        ref={verificationCodeInput}
        value={verificationCode}
        onChangeText={(text) => setVerificationCode(text.replace(/[^0-9]/g, "").slice(0, 6))}
        containerStyle={themed($textField)}
        autoCapitalize="none"
        autoComplete="one-time-code"
        autoCorrect={false}
        keyboardType="number-pad"
        label="Verification Code"
        placeholder="Enter 6-digit code"
        maxLength={6}
        onSubmitEditing={handleVerifyLogin}
      />

      <Button
        testID="verify-button"
        text="Verify"
        style={themed($tapButton)}
        preset="reversed"
        onPress={handleVerifyLogin}
        disabled={isLoading || verificationCode.length !== 6}
        loading={isLoading}
      />

      <View style={themed($resendContainer)}>
        <Text text="Didn't receive the code? " size="sm" />
        <Button
          testID="resend-button"
          text={resendCountdown > 0 ? `Resend in ${resendCountdown}s` : "Resend Code"}
          preset="link"
          onPress={handleResendCode}
          disabled={isLoading || resendCountdown > 0}
        />
      </View>

      <Button
        testID="back-button"
        text="Back to Login"
        preset="default"
        style={themed($backButton)}
        onPress={handleBackToCredentials}
        disabled={isLoading}
      />
    </>
  )

  return (
    <Screen
      preset="auto"
      contentContainerStyle={themed($screenContentContainer)}
      safeAreaEdges={["top", "bottom"]}
    >
      {loginStep === "credentials" ? renderCredentialsStep() : renderVerificationStep()}
    </Screen>
  )
}

const $screenContentContainer: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  paddingVertical: spacing.xxl,
  paddingHorizontal: spacing.lg,
})

const $logIn: ThemedStyle<TextStyle> = ({ spacing }) => ({
  marginBottom: spacing.sm,
})

const $enterDetails: ThemedStyle<TextStyle> = ({ spacing }) => ({
  marginBottom: spacing.lg,
})

const $errorText: ThemedStyle<TextStyle> = ({ colors, spacing }) => ({
  color: colors.error,
  marginBottom: spacing.md,
})

const $textField: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  marginBottom: spacing.lg,
})

const $tapButton: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  marginTop: spacing.xs,
})

const $dividerContainer: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  flexDirection: "row",
  alignItems: "center",
  marginVertical: spacing.xl,
})

const $dividerLine: ThemedStyle<ViewStyle> = ({ colors }) => ({
  flex: 1,
  height: 1,
  backgroundColor: colors.separator,
})

const $dividerText: ThemedStyle<TextStyle> = ({ colors, spacing }) => ({
  color: colors.textDim,
  marginHorizontal: spacing.md,
})

const $googleButton: ThemedStyle<ViewStyle> = ({ colors, spacing }) => ({
  borderWidth: 1,
  borderColor: colors.border,
  backgroundColor: colors.background,
  paddingVertical: spacing.sm,
})

const $googleLogo: ThemedStyle<ImageStyle> = ({ spacing }) => ({
  width: s(20),
  height: s(20),
  marginRight: spacing.xs,
})

const $googleButtonText: ThemedStyle<TextStyle> = ({ colors }) => ({
  color: colors.text,
})

const $resendContainer: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  flexDirection: "row",
  alignItems: "center",
  justifyContent: "center",
  marginTop: spacing.lg,
})

const $backButton: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  marginTop: spacing.lg,
})

const $registerLinkContainer: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  flexDirection: "row",
  alignItems: "center",
  justifyContent: "center",
  marginTop: spacing.xl,
})

const $forgotPasswordContainer: ThemedStyle<ViewStyle> = () => ({
  alignItems: "flex-end",
})
