"use client";

import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Eye, EyeOff, User, Lock, Smartphone, Store } from "lucide-react";
import Link from "next/link";

import {
  loginSchema,
  type LoginFormValues,
} from "@/lib/validations/auth.schema";
import { AuthType } from "@/types/auth";
import { useLogin } from "@/hooks/auth/useLogin";
import { useSendOtp } from "@/hooks/auth/useSendOtp";
import { useTranslation } from "@/hooks/useTranslation";
import { ROUTES } from "@/lib/constants/routes";

import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupButton,
  InputGroupText,
} from "@/components/ui/input-group";
import { OtpInput } from "@/components/auth/OtpInput";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  CardDescription,
} from "@/components/ui/card";
import { Typography } from "@/components/ui/typography";
import { LegalConsent } from "@/components/legal/LegalConsent";
import { useRouter } from "next/navigation";

export function LoginForm() {
  const { t } = useTranslation();
  const [showPassword, setShowPassword] = useState(false);
  const [otpSent, setOtpSent] = useState(false);
  const router = useRouter();
  const loginMutation = useLogin();
  const sendOtpMutation = useSendOtp({ onSuccess: () => setOtpSent(true) });

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    formState: { errors, touchedFields, isValid },
  } = useForm<LoginFormValues>({
    resolver: zodResolver(loginSchema),
    defaultValues: {
      identifier: "",
      authType: AuthType.PASSWORD,
      password: "",
      otpCode: "",
    },
    mode: "onTouched",
  });

  const authType = watch("authType");
  const identifier = watch("identifier");
  const isPasswordMode = authType === AuthType.PASSWORD;
  const isOtpMode = authType === AuthType.OTP;

  function handleAuthTypeChange(type: AuthType) {
    setValue("authType", type, { shouldValidate: false });
    setValue("password", "", { shouldValidate: false });
    setValue("otpCode", "", { shouldValidate: false });
    setOtpSent(false);
  }

  function handleSendOtp() {
    if (!identifier.trim()) return;
    const isEmail = identifier.includes("@");
    sendOtpMutation.mutate(
      isEmail
        ? { email: identifier.trim() }
        : { phoneNumber: identifier.trim() },
    );
  }

  function onSubmit(values: LoginFormValues) {
    if (values.authType === AuthType.PASSWORD) {
      delete values.otpCode;
    } else if (values.authType === AuthType.OTP) {
      delete values.password;
    }

    loginMutation.mutate(values);
  }

  return (
    <Card className="w-full max-w-md">
      <CardHeader className="flex flex-col items-center gap-3 text-center">
        <div className="flex size-16 items-center justify-center rounded-full bg-background">
          <Lock className="size-8 text-primary-blue" />
        </div>
        <CardTitle>{t("auth.login.title")}</CardTitle>
        <CardDescription>{t("auth.login.subtitle")}</CardDescription>
      </CardHeader>

      <CardContent className="flex flex-col gap-5">
        <form
          onSubmit={handleSubmit(onSubmit)}
          noValidate
          className="flex flex-col gap-5"
        >
          {/* ── Identifier ──────────────────────────────────────────── */}
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="identifier">{t("auth.login.identifier")}</Label>
            <InputGroup>
              <InputGroupAddon align="inline-start">
                <InputGroupText className="pr-2">
                  <User className="size-4 text-muted-foreground" />
                </InputGroupText>
              </InputGroupAddon>
              <InputGroupInput
                id="identifier"
                type="text"
                placeholder={t("auth.login.identifierPlaceholder")}
                aria-invalid={touchedFields.identifier && !!errors.identifier}
                {...register("identifier")}
              />
            </InputGroup>
            {touchedFields.identifier && errors.identifier && (
              <Typography
                as="p"
                variant="caption"
                className="text-destructive mt-0.5"
              >
                {t(errors.identifier.message as any)}
              </Typography>
            )}
          </div>

          {/* ── Auth Type Toggle ─────────────────────────────────────── */}
          <div className="flex flex-col gap-1.5">
            <Label>{t("auth.login.chooseSignInMethod")}</Label>
            <div className="grid grid-cols-2 gap-2">
              <Button
                type="button"
                id="auth-type-password"
                variant={isPasswordMode ? "default" : "secondary"}
                className="gap-2"
                onClick={() => handleAuthTypeChange(AuthType.PASSWORD)}
              >
                <Lock className="size-4" />
                {t("auth.login.authType.password")}
              </Button>
              <Button
                type="button"
                id="auth-type-otp"
                variant={isOtpMode ? "default" : "secondary"}
                className="gap-2"
                onClick={() => handleAuthTypeChange(AuthType.OTP)}
              >
                <Smartphone className="size-4" />
                {t("auth.login.authType.otp")}
              </Button>
            </div>
          </div>

          {/* ── Password Mode ────────────────────────────────────────── */}
          {isPasswordMode && (
            <div className="flex flex-col gap-1.5">
              <div className="flex items-center justify-between">
                <Label htmlFor="password">{t("auth.login.password")}</Label>
                <Link href={ROUTES.AUTH.FORGOT_PASSWORD}>
                  <Typography
                    as="span"
                    variant="caption"
                    className="text-primary-blue hover:underline"
                  >
                    {t("auth.login.forgotPassword")}
                  </Typography>
                </Link>
              </div>
              <InputGroup>
                <InputGroupAddon align="inline-start">
                  <InputGroupText className="pr-2">
                    <Lock className="size-4 text-muted-foreground" />
                  </InputGroupText>
                </InputGroupAddon>
                <InputGroupInput
                  id="password"
                  type={showPassword ? "text" : "password"}
                  placeholder={t("auth.login.passwordPlaceholder")}
                  aria-invalid={touchedFields.password && !!errors.password}
                  {...register("password")}
                />
                <InputGroupAddon align="inline-end">
                  <InputGroupButton
                    type="button"
                    aria-label={
                      showPassword
                        ? t("auth.login.hidePassword")
                        : t("auth.login.showPassword")
                    }
                    onClick={() => setShowPassword((v) => !v)}
                  >
                    {showPassword ? (
                      <EyeOff className="size-4 text-muted-foreground" />
                    ) : (
                      <Eye className="size-4 text-muted-foreground" />
                    )}
                  </InputGroupButton>
                </InputGroupAddon>
              </InputGroup>
              {touchedFields.password && errors.password && (
                <Typography
                  as="p"
                  variant="caption"
                  className="text-destructive mt-0.5"
                >
                  {t(errors.password.message as any)}
                </Typography>
              )}
            </div>
          )}

          {/* ── OTP Mode ─────────────────────────────────────────────── */}
          {isOtpMode && (
            <div className="flex flex-col gap-3">
              {/* Send OTP button */}
              {!otpSent ? (
                <Button
                  type="button"
                  id="send-otp-btn"
                  variant="secondary"
                  className="w-full"
                  loading={sendOtpMutation.isPending}
                  disabled={!identifier.trim() || sendOtpMutation.isPending}
                  onClick={handleSendOtp}
                >
                  {t("auth.login.sendOtp")}
                </Button>
              ) : (
                <>
                  <Typography
                    as="p"
                    variant="body"
                    color="secondary"
                    className="text-center"
                  >
                    {t("auth.login.otpSent")}
                  </Typography>

                  {/* OTP Input */}
                  <div className="flex flex-col gap-1.5">
                    <Label htmlFor="otpCode">{t("auth.login.otpCode")}</Label>
                    <div className="flex justify-center">
                      <OtpInput
                        id="otpCode"
                        value={watch("otpCode") ?? ""}
                        onChange={(val) =>
                          setValue("otpCode", val, {
                            shouldValidate: touchedFields.otpCode,
                          })
                        }
                        hasError={touchedFields.otpCode && !!errors.otpCode}
                      />
                    </div>
                    {touchedFields.otpCode && errors.otpCode && (
                      <Typography
                        as="p"
                        variant="caption"
                        className="text-destructive text-center mt-0.5"
                      >
                        {t(errors.otpCode.message as any)}
                      </Typography>
                    )}
                  </div>

                  {/* Resend link */}
                  <button
                    type="button"
                    className="self-center"
                    onClick={() => {
                      setOtpSent(false);
                      handleSendOtp();
                    }}
                  >
                    <Typography
                      as="span"
                      variant="caption"
                      className="text-primary-blue hover:underline"
                    >
                      {t("auth.login.resendOtp")}
                    </Typography>
                  </button>
                </>
              )}
            </div>
          )}

          {/* ── Legal consent + Submit ───────────────────────────────── */}
          <div className="flex flex-col gap-3">
            <LegalConsent />
            <Button
              type="submit"
              id="login-submit"
              className="w-full"
              loading={loginMutation.isPending}
              disabled={loginMutation.isPending}
            >
              {t("auth.login.submit")}
            </Button>
          </div>
        </form>

        {/* Provider self-registration entry point (public route) */}
        <div className="flex flex-col items-center gap-2 text-center">
          <Typography as="p" variant="caption" color="secondary">
            {t("auth.login.providerPrompt")}
          </Typography>
          <Button
            type="button"
            variant="secondary"
            className="w-full gap-2"
            onClick={() => router.push(ROUTES.AUTH.REGISTER_PROVIDER)}
          >
            <Store className="size-4" />
            {t("auth.login.registerAsProvider")}
          </Button>
        </div>

        <Button
          variant="secondary"
          className="w-full"
          onClick={() => router.push(ROUTES.HOME)}
        >
          {t("common.backToHome")}
        </Button>
      </CardContent>
    </Card>
  );
}
