import { useState } from "react";
import {
  Alert,
  Anchor,
  Button,
  Checkbox,
  Divider,
  Group,
  PasswordInput,
  Stack,
  Text,
  TextInput,
  Title,
} from "@mantine/core";
import {
  IconArrowRight,
  IconDeviceMobile,
  IconLock,
  IconMail,
} from "@tabler/icons-react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { useNavigate, Link } from "react-router-dom";
import { useDispatch } from "react-redux";
import { useApiMutation } from "@ema-platform/api";
import { notify, useErrorHandler } from "@ema-platform/ui";
import { AuthShell } from "../components/AuthShell";
import { loginSuccess, setUser, setCurrentProfile } from "../store/auth.slice";
import type {
  LoginPayload,
  AuthUser,
  CurrentProfile,
} from "../types/auth.types";
import { useAuthConfig } from "../AuthConfig";
import { authStorage } from "../utils/auth-storage";
const emailOrPhone = z
  .string()
  .trim()
  .transform((value) => {
    // Convert 09xxxxxxxx -> +2519xxxxxxxx
    if (/^09\d{8}$/.test(value)) {
      return `+251${value.substring(1)}`;
    }

    return value;
  })
  .refine(
    (value) => {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      const phoneRegex = /^\+2519\d{8}$/;

      return emailRegex.test(value) || phoneRegex.test(value);
    },
    {
      message: "Enter a valid email or phone number (+2519xxxxxxxx)",
    },
  );
const schema = z.object({
  email: emailOrPhone,
  password: z
    .string()
    .min(8, { message: "Password must be at least 8 characters" }),
});

type FormValues = z.infer<typeof schema>;

export function LoginPage() {
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const { appName, loginRedirectPath, enableSignup, enableForgotPassword } =
    useAuthConfig();
  const [isLoading, setIsLoading] = useState(false);
  const [rememberMe, setRememberMe] = useState(true);
  const [serverError, setServerError] = useState<string | null>(null);
  const { handleError } = useErrorHandler();
  const [loginTrigger] = useApiMutation<LoginPayload>();
  const [meTrigger] = useApiMutation<AuthUser>();
  const [profileTrigger] = useApiMutation<{ profile: CurrentProfile | null }>();

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: zodResolver(schema),
  });

  const onSubmit = async (values: FormValues) => {
    setIsLoading(true);
    try {
      const data = await loginTrigger({
        url: "/auth/login",
        method: "POST",
        body: values,
      }).unwrap();
      dispatch(loginSuccess(data));

      const me = await meTrigger({
        url: "/auth/me",
        method: "GET",
      }).unwrap();
      dispatch(setUser(me));

      // Warm the profile so screens that need an id have one on first paint.
      // `/profiles/me` provisions an empty profile when the user has none, so
      // unlike the old filtered lookup this cannot come back empty-handed.
      // Sign-in is still never gated on it — a failure here is ignored and
      // `useCurrentProfile` resolves it again on demand.
      try {
        const { profile } = await profileTrigger({
          url: "/profiles/me",
          method: "GET",
        }).unwrap();
        if (profile) {
          authStorage.setProfileId(profile.id);
          dispatch(setCurrentProfile(profile));
        }
      } catch {
        // Offline or a 5xx — the portal still works; the resolver retries.
      }

      if (!me.isPhoneNumberVerified) {
        navigate("/otp-verify", {
          state: {
            email: me.email,
            phoneNumber: me.phoneNumber,
          },
        });
        return;
      }

      navigate(loginRedirectPath);
    } catch (err: unknown) {
      setServerError(handleError(err));
    } finally {
      localStorage.setItem("rememberMe", String(rememberMe));
      setIsLoading(false);
    }
  };

  return (
    <AuthShell>
      <Stack gap="lg">
        <div>
          <Title order={2} fz={30}>
            Welcome to {appName}
          </Title>
          <Text c="dimmed" mt={6}>
            Sign in to access your account.
          </Text>
        </div>

        {serverError && (
          <Alert
            variant="light"
            color="red"
            withCloseButton
            onClose={() => setServerError(null)}
          >
            {serverError}
          </Alert>
        )}

        <form onSubmit={handleSubmit(onSubmit)}>
          <Stack gap="md">
            <TextInput
              label="Email or phone"
              placeholder="you@example.com"
              size="md"
              leftSection={<IconMail size={18} />}
              error={errors.email?.message}
              {...register("email")}
            />
            <PasswordInput
              label="Password"
              placeholder="Your password"
              size="md"
              leftSection={<IconLock size={18} />}
              error={errors.password?.message}
              {...register("password")}
            />

            <Group justify="space-between">
              <Checkbox
                label="Remember me"
                size="sm"
                checked={rememberMe}
                onChange={(e) => setRememberMe(e.currentTarget.checked)}
              />
              {enableForgotPassword && (
                <Anchor
                  component={Link}
                  to="/forgot-password"
                  size="sm"
                  fw={600}
                >
                  Forgot password?
                </Anchor>
              )}
            </Group>

            <Button
              type="submit"
              loading={isLoading}
              fullWidth
              size="md"
              rightSection={<IconArrowRight size={18} />}
            >
              Sign in
            </Button>
          </Stack>
        </form>
        {enableSignup && (
          <Text ta="center" size="sm" c="dimmed">
            Don&apos;t have an account?{" "}
            <Anchor component={Link} to="/signup" fw={700}>
              Create one
            </Anchor>
          </Text>
        )}
      </Stack>
    </AuthShell>
  );
}
