import { Link, useRouter } from "expo-router";
import { useCallback, useState } from "react";
import {
  Alert,
  Image,
  KeyboardAvoidingView,
  Platform,
  ScrollView,
  Text,
  TouchableOpacity,
  View,
} from "react-native";
import ReactNativeModal from "react-native-modal";

import { CustomButton } from "@/components/custom-button";
import { InputField } from "@/components/input-field";
import { OAuth } from "@/components/oauth";
import { icons, images } from "@/constants";
import { fetchAPI } from "@/lib/fetch";
import { useSession } from "@/lib/session";

const SignIn = () => {
  const router = useRouter();
  const { isLoaded, setSession } = useSession();
  const [form, setForm] = useState({
    email: "",
    password: "",
  });

  // Forgot-password flow: "request" collects the email, "reset" collects the
  // emailed code and a new password.
  const [reset, setReset] = useState({
    state: "closed" as "closed" | "request" | "reset",
    email: "",
    code: "",
    password: "",
    devCode: "",
    error: "",
    busy: false,
  });

  const openReset = () =>
    setReset({
      state: "request",
      email: form.email,
      code: "",
      password: "",
      devCode: "",
      error: "",
      busy: false,
    });

  const closeReset = () =>
    setReset((prev) => ({ ...prev, state: "closed" }));

  const onRequestReset = async () => {
    if (!reset.email.trim()) {
      setReset((prev) => ({ ...prev, error: "Enter your email address." }));
      return;
    }

    setReset((prev) => ({ ...prev, busy: true, error: "" }));

    try {
      const response = await fetchAPI("/(api)/auth/forgot-password", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: reset.email.trim() }),
      });

      setReset((prev) => ({
        ...prev,
        state: "reset",
        busy: false,
        devCode:
          (response as { data?: { devCode?: string } })?.data?.devCode ?? "",
      }));
    } catch {
      // The endpoint hides whether the email exists, so move on regardless.
      setReset((prev) => ({ ...prev, state: "reset", busy: false }));
    }
  };

  const onSubmitReset = async () => {
    if (!/^\d{6}$/.test(reset.code)) {
      setReset((prev) => ({ ...prev, error: "Enter the 6-digit code." }));
      return;
    }

    if (reset.password.length < 8) {
      setReset((prev) => ({
        ...prev,
        error: "Password must be at least 8 characters.",
      }));
      return;
    }

    setReset((prev) => ({ ...prev, busy: true, error: "" }));

    try {
      const response = await fetchAPI("/(api)/auth/reset-password", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          email: reset.email.trim(),
          code: reset.code,
          password: reset.password,
        }),
      });

      await setSession(response.data);
      setReset((prev) => ({ ...prev, state: "closed", busy: false }));
      router.replace("/");
    } catch (err: any) {
      setReset((prev) => ({
        ...prev,
        busy: false,
        error: String(err?.message ?? "").includes("400")
          ? "Invalid or expired reset code."
          : "Could not reset your password. Please try again.",
      }));
    }
  };

  const onSignInPress = useCallback(async () => {
    try {
      const response = await fetchAPI("/(api)/auth/login", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          email: form.email,
          password: form.password,
        }),
      });

      await setSession(response.data);
      router.replace("/");
    } catch (err: any) {
      const status = String(err?.message ?? "");
      const message = status.includes("403")
        ? "Please verify your email first."
        : status.includes("401")
          ? "Invalid email or password."
          : "Could not sign in. Please try again.";

      Alert.alert("Error", message);
      setForm((prevForm) => ({
        ...prevForm,
        password: "",
      }));
    }
  }, [isLoaded, form.email, form.password, setSession, router]);

  return (
    <KeyboardAvoidingView
      className="flex-1 bg-white"
      behavior={Platform.OS === "ios" ? "padding" : "height"}
      keyboardVerticalOffset={Platform.OS === "ios" ? 40 : 0}
    >
    <ScrollView
      className="flex-1 bg-white"
      keyboardShouldPersistTaps="handled"
      contentContainerStyle={{ flexGrow: 1 }}
      showsVerticalScrollIndicator={false}
    >
      <View className="flex-1 bg-white">
        <View className="relative w-full h-[250px]">
          <Image
            source={images.signUpCar}
            alt="Car"
            className="z-0 w-full h-[250px]"
            resizeMode="contain"
          />

          <Text className="text-2xl text-black font-JakartaSemiBold absolute bottom-5 left-5">
            Welcome 👋
          </Text>
        </View>

        <View className="p-5">
          <InputField
            label="Email"
            placeholder="karim@email.com"
            icon={icons.email}
            value={form.email}
            onChangeText={(value) =>
              setForm((prevForm) => ({
                ...prevForm,
                email: value,
              }))
            }
            keyboardType="email-address"
          />

          <InputField
            label="Password"
            placeholder="••••••••"
            icon={icons.lock}
            secureTextEntry
            value={form.password}
            onChangeText={(value) =>
              setForm((prevForm) => ({
                ...prevForm,
                password: value,
              }))
            }
          />

          <CustomButton
            title="Sign In"
            onPress={onSignInPress}
            className="mt-6"
          />

          <TouchableOpacity onPress={openReset} className="mt-4">
            <Text className="text-primary-500 text-center font-JakartaMedium">
              Forgot password?
            </Text>
          </TouchableOpacity>

          <OAuth title="Sign in with Google" />

          <Link
            href="/sign-up"
            className="text-base text-center text-general-200 mt-10"
          >
            <Text>Don&apos;t have an account? </Text>
            <Text className="text-primary-500">Sign up</Text>
          </Link>
        </View>

        <ReactNativeModal
          isVisible={reset.state === "request"}
          onBackdropPress={closeReset}
        >
          <View className="bg-white px-7 py-9 rounded-2xl min-h-[280px]">
            <Text className="text-2xl font-JakartaExtraBold mb-2">
              Reset password
            </Text>

            <Text className="font-Jakarta mb-5">
              Enter your email and we&apos;ll send you a 6-digit reset code.
            </Text>

            <InputField
              label="Email"
              placeholder="karim@email.com"
              icon={icons.email}
              value={reset.email}
              keyboardType="email-address"
              onChangeText={(email) =>
                setReset((prev) => ({ ...prev, email }))
              }
            />

            {reset.error ? (
              <Text className="text-rose-500 text-sm mt-1">{reset.error}</Text>
            ) : null}

            <CustomButton
              title={reset.busy ? "Sending…" : "Send Code"}
              onPress={onRequestReset}
              disabled={reset.busy}
              className="mt-5"
            />
          </View>
        </ReactNativeModal>

        <ReactNativeModal
          isVisible={reset.state === "reset"}
          onBackdropPress={closeReset}
        >
          <View className="bg-white px-7 py-9 rounded-2xl min-h-[300px]">
            <Text className="text-2xl font-JakartaExtraBold mb-2">
              Enter new password
            </Text>

            <Text className="font-Jakarta mb-5">
              We&apos;ve sent a reset code to {reset.email}
            </Text>

            {reset.devCode ? (
              <View className="bg-amber-50 border border-amber-300 rounded-xl p-3 mb-5">
                <Text className="text-sm text-amber-700 font-Jakarta">
                  Email delivery is not configured on this server. Your reset
                  code is <Text className="font-JakartaBold">{reset.devCode}</Text>
                </Text>
              </View>
            ) : null}

            <InputField
              label="Code"
              icon={icons.lock}
              placeholder="••••••"
              value={reset.code}
              maxLength={6}
              keyboardType="numeric"
              onChangeText={(code) => setReset((prev) => ({ ...prev, code }))}
            />

            <InputField
              label="New password"
              icon={icons.lock}
              placeholder="••••••••"
              secureTextEntry
              value={reset.password}
              onChangeText={(password) =>
                setReset((prev) => ({ ...prev, password }))
              }
            />

            {reset.error ? (
              <Text className="text-rose-500 text-sm mt-1">{reset.error}</Text>
            ) : null}

            <CustomButton
              title={reset.busy ? "Resetting…" : "Reset Password"}
              onPress={onSubmitReset}
              disabled={reset.busy}
              className="mt-5 bg-emerald-500"
            />
          </View>
        </ReactNativeModal>
      </View>
    </ScrollView>
    </KeyboardAvoidingView>
  );
};

export default SignIn;
