import { Link, router } 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 { OtpField } from "@/components/otp-field";
import { icons, images } from "@/constants";
import { ApiError, fetchAPI } from "@/lib/fetch";
import { useT } from "@/lib/i18n";
import { useSession } from "@/lib/session";

const ROLES = [
  {
    value: "rider",
    titleKey: "auth.signUp.riderTitle",
    descKey: "auth.signUp.riderDesc",
    icon: "map" as const,
  },
  {
    value: "driver",
    titleKey: "auth.signUp.driverTitle",
    descKey: "auth.signUp.driverDesc",
    icon: "dollar" as const,
  },
] as const;

type Role = (typeof ROLES)[number]["value"];

const SignUp = () => {
  const { setSession } = useSession();
  const t = useT();

  const [role, setRole] = useState<Role>("rider");
  const [form, setForm] = useState({
    name: "",
    email: "",
    phone: "",
    password: "",
  });

  // "verified" is a hand-off state: it hides the code modal so its onModalHide
  // can bring up the success modal, since two modals can't cross-fade.
  const [verification, setVerification] = useState({
    state: "default" as "default" | "pending" | "verified" | "success",
    error: "",
    code: "",
    devCode: "",
    busy: false,
  });

  const onSignUpPress = async () => {
    if (!form.name.trim() || !form.email.trim() || !form.password) {
      Alert.alert(
        t("auth.signUp.alertMissingTitle"),
        t("auth.signUp.alertMissingBody"),
      );
      return;
    }

    if (form.phone.trim() && !/^[0-9\s\-()+.]+$/.test(form.phone)) {
      Alert.alert(
        t("auth.signUp.alertPhoneTitle"),
        t("auth.signUp.alertPhoneBody"),
      );
      return;
    }

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

      setVerification({
        state: "pending",
        error: "",
        code: "",
        busy: false,
        devCode:
          (response as { data?: { devCode?: string } })?.data?.devCode ?? "",
      });

      setForm((prevForm) => ({
        ...prevForm,
        password: "",
      }));
    } catch (err: any) {
      setForm((prevForm) => ({
        ...prevForm,
        password: "",
      }));
      Alert.alert(
        t("auth.signUp.alertErrorTitle"),
        err instanceof ApiError && err.status < 500
          ? err.message
          : t("auth.signUp.alertErrorFallback"),
      );
    }
  };

  const onPressVerify = useCallback(
    async (code: string) => {
      if (!/^\d{6}$/.test(code)) {
        setVerification((prevVerification) => ({
          ...prevVerification,
          error: t("auth.signUp.errCode"),
        }));
        return;
      }

      setVerification((prevVerification) =>
        // Guard the double submit that auto-verify + a button tap would cause.
        prevVerification.busy
          ? prevVerification
          : { ...prevVerification, busy: true, error: "" },
      );

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

        await setSession(response.data);
        setVerification((prevVerification) => ({
          ...prevVerification,
          state: "verified",
          busy: false,
        }));
      } catch (err: any) {
        // Stay on the code modal so the user can retry; only a real success
        // advances the flow.
        setVerification((prevVerification) => ({
          ...prevVerification,
          code: "",
          busy: false,
          error:
            err instanceof ApiError && err.status < 500
              ? err.message
              : t("auth.signUp.errVerify"),
        }));
      }
    },
    [form.email, setSession, t],
  );

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

          <Text className="text-2xl text-black dark:text-white font-JakartaSemiBold absolute bottom-5 left-5">
            {t("auth.signUp.createAccount")}
          </Text>
        </View>

        <View className="p-5">
          <Text className="text-lg font-JakartaSemiBold mb-3 text-black dark:text-white">
            {t("auth.signUp.howUse")}
          </Text>
          <View className="flex-row gap-3 mb-4">
            {ROLES.map((option) => {
              const selected = role === option.value;
              return (
                <TouchableOpacity
                  key={option.value}
                  onPress={() => setRole(option.value)}
                  activeOpacity={0.8}
                  className={`flex-1 justify-center rounded-2xl border p-4 ${
                    selected
                      ? "border-primary-500 bg-primary-500/10"
                      : "border-neutral-100 dark:border-neutral-800 bg-neutral-100 dark:bg-neutral-900"
                  }`}
                >
                  <Image
                    source={option.value === "driver" ? icons.dollar : icons.map}
                    alt={t(`auth.signUp.${option.value === "driver" ? "driverTitle" : "riderTitle"}`)}
                    className="h-7 w-7 mb-2"
                    resizeMode="contain"
                  />
                  <Text
                    className={`text-[15px] font-JakartaBold ${
                      selected ? "text-primary-500" : "text-black dark:text-white"
                    }`}
                  >
                    {t(option.titleKey)}
                  </Text>
                  <Text className="text-xs text-neutral-400 dark:text-neutral-500 font-Jakarta mt-1">
                    {t(option.descKey)}
                  </Text>
                </TouchableOpacity>
              );
            })}
          </View>

          <InputField
            label={t("auth.signUp.name")}
            placeholder={t("auth.signUp.namePlaceholder")}
            icon={icons.person}
            value={form.name}
            onChangeText={(value) =>
              setForm((prevForm) => ({
                ...prevForm,
                name: value,
              }))
            }
            autoCapitalize="words"
          />

          <InputField
            label={t("auth.signUp.email")}
            placeholder={t("auth.signUp.emailPlaceholder")}
            icon={icons.email}
            value={form.email}
            onChangeText={(value) =>
              setForm((prevForm) => ({
                ...prevForm,
                email: value,
              }))
            }
            keyboardType="email-address"
          />

          <InputField
            label={t("auth.signUp.phoneOptional")}
            placeholder={t("auth.signUp.phonePlaceholder")}
            icon={icons.chat}
            value={form.phone}
            onChangeText={(value) =>
              setForm((prevForm) => ({
                ...prevForm,
                phone: value,
              }))
            }
            keyboardType="phone-pad"
          />

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

          <CustomButton
            title={t("auth.signUp.signUpBtn")}
            onPress={onSignUpPress}
            className="mt-6"
          />

          <OAuth title={t("auth.signUp.signUpGoogle")} />

          <Link
            href="/sign-in"
            className="text-base text-center text-general-200 dark:text-neutral-400 mt-10"
          >
            <Text className="text-black dark:text-white">{t("auth.signUp.haveAccount")}</Text>
            <Text className="text-primary-500">{t("auth.signUp.signInLink")}</Text>
          </Link>
        </View>

        <ReactNativeModal
          onModalHide={() =>
            setVerification((prevVerification) =>
              prevVerification.state === "verified"
                ? { ...prevVerification, state: "success" }
                : prevVerification,
            )
          }
          isVisible={verification.state === "pending"}
        >
          <View className="bg-white dark:bg-neutral-900 px-7 py-9 rounded-2xl min-h-[300px]">
            <Text className="text-2xl font-JakartaExtraBold mb-2 text-black dark:text-white">
              {t("auth.signUp.verify.title")}
            </Text>

            <Text className="font-Jakarta mb-5 text-black dark:text-white">
              {t("auth.signUp.verify.body", { email: form.email })}
            </Text>

            {verification.devCode ? (
              <View className="bg-amber-50 dark:bg-amber-950/40 border border-amber-300 dark:border-amber-800 rounded-xl p-3 mb-5">
                <Text className="text-sm text-amber-700 dark:text-amber-400 font-Jakarta">
                  {t("auth.signUp.verify.devBanner")}
                  <Text className="font-JakartaBold">{verification.devCode}</Text>
                </Text>
              </View>
            ) : null}

            <OtpField
              value={verification.code}
              onChange={(code) =>
                setVerification((prevVerification) => ({
                  ...prevVerification,
                  code,
                  error: "",
                }))
              }
              onComplete={onPressVerify}
            />

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

            <CustomButton
              title={verification.busy ? t("auth.signUp.verify.verifying") : t("auth.signUp.verify.verifyBtn")}
              onPress={() => onPressVerify(verification.code)}
              disabled={verification.busy}
              className="mt-5 bg-emerald-500"
            />
          </View>
        </ReactNativeModal>
        <ReactNativeModal isVisible={verification.state === "success"}>
          <View className="bg-white dark:bg-neutral-900 px-7 py-9 rounded-2xl min-h-[300px]">
            <Image
              source={images.check}
              alt={t("auth.signUp.verify.checkAlt")}
              className="w-[110px] h-[110px] mx-auto my-5"
            />

            <Text className="text-3xl font-JakartaBold text-center text-black dark:text-white">
              {t("auth.signUp.verified.title")}
            </Text>

            <Text className="text-base text-gray-400 dark:text-neutral-500 font-Jakarta text-center mt-2">
              {t("auth.signUp.verified.body")}
            </Text>

            <CustomButton
              title={t("common.browseHome")}
              onPress={() => router.push("/")}
              className="mt-5"
            />
          </View>
        </ReactNativeModal>
      </View>
    </ScrollView>
    </KeyboardAvoidingView>
  );
};

export default SignUp;