"use client";

import Image from "next/image";
import React, { FormEvent, useState } from "react";
import logo from "@/assets/icons/logo-icon.svg";
import bg from "@/assets/icons/forgot-bg.svg";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { ArrowRight } from "lucide-react";
import Link from "next/link";
import { toast } from "sonner";
import { PasswordInput } from "@/components/ui/password-input";
import {
  useForgotPasswordMutation,
  useResetPasswordMutation,
} from "@/redux/api";
import { getApiErrorMessage } from "@/lib/api-error";

type ForgotStep = "email" | "otp" | "reset" | "done";

function rtkErrorToApiShape(err: unknown): unknown {
  if (typeof err === "object" && err !== null && "data" in err) {
    return { response: { data: (err as { data: unknown }).data } };
  }
  return err;
}

const Page = () => {
  const [step, setStep] = useState<ForgotStep>("email");
  const [email, setEmail] = useState("");
  const [otp, setOtp] = useState("");
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");

  const [forgotPassword, { isLoading: sendingCode }] =
    useForgotPasswordMutation();
  const [resetPassword, { isLoading: resettingPw }] =
    useResetPasswordMutation();

  const isLoading = sendingCode || resettingPw;

  const submitEmail = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (!email.trim()) return;

    try {
      const result = await forgotPassword({
        email: email.trim(),
      }).unwrap();
      toast.success(
        typeof result?.message === "string" && result.message.trim()
          ? result.message
          : "Reset code sent to your email.",
      );
      setStep("otp");
    } catch (err: unknown) {
      toast.error(
        getApiErrorMessage(
          rtkErrorToApiShape(err),
          "Could not send reset code. Please try again.",
        ),
      );
    }
  };

  const submitOtp = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (!otp.trim()) return;

    if (!/^[A-Za-z0-9]{6}$/.test(otp.trim())) {
      toast.error(
        "Enter the 6-character code from your email (letters and numbers).",
      );
      return;
    }

    setStep("reset");
  };

  const submitPassword = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (!password || !confirmPassword) return;

    if (password.length < 8) {
      toast.error("Password must be at least 8 characters.");
      return;
    }

    if (password !== confirmPassword) {
      toast.error("Passwords do not match.");
      return;
    }

    try {
      const result = await resetPassword({
        email: email.trim(),
        code: otp.trim().toUpperCase(),
        password,
      }).unwrap();
      toast.success(
        typeof result?.message === "string" && result.message.trim()
          ? result.message
          : "Password reset successfully.",
      );
      setStep("done");
    } catch (err: unknown) {
      toast.error(
        getApiErrorMessage(
          rtkErrorToApiShape(err),
          "Could not reset password. Check your code and try again.",
        ),
      );
    }
  };

  return (
    <div className="min-h-screen flex items-center bg-gradient-to-br from-primary to-gray-700">
      <div className="md:flex container gap-10 w-full items-center">
        <div className="md:basis-1/2">
          <Image
            src={logo}
            alt=""
            className="mx-auto max-h-80 w-1/2"
            width={400}
            height={400}
          />
        </div>
        <div className="xl:p-10 p-5 md:basis-1/2 flex justify-start relative h-fit">
          <Card className="p-5 shadow z-10 w-full max-w-md">
            <CardContent className="flex flex-col gap-4 p-5 text-center">
              <h1 className="font-bold text-lg">Forgot Password</h1>
              <p className="text-gray-500 text-sm">
                {step === "email" && "Enter your email to receive a reset code"}
                {step === "otp" &&
                  "Enter the 6-character code sent to your email"}
                {step === "reset" && "Set your new password"}
                {step === "done" && "Your password has been reset"}
              </p>

              {step === "email" && (
                <form className="flex flex-col gap-3" onSubmit={submitEmail}>
                  <div className="text-left flex flex-col gap-3">
                    <Label htmlFor="email">Enter Email</Label>
                    <Input
                      id="email"
                      type="email"
                      placeholder="you@example.com"
                      name="email"
                      value={email}
                      onChange={(e) => setEmail(e.target.value)}
                      required
                    />
                  </div>
                  <Button className="w-full" disabled={isLoading}>
                    {isLoading ? "Sending..." : "Send reset code"}
                  </Button>
                </form>
              )}

              {step === "otp" && (
                <form className="flex flex-col gap-3" onSubmit={submitOtp}>
                  <div className="text-left flex flex-col gap-3">
                    <Label htmlFor="otp">Reset code</Label>
                    <Input
                      id="otp"
                      type="text"
                      inputMode="text"
                      autoComplete="one-time-code"
                      placeholder="e.g. A1B2C3"
                      name="otp"
                      value={otp}
                      onChange={(e) =>
                        setOtp(
                          e.target.value
                            .replace(/[^A-Za-z0-9]/g, "")
                            .slice(0, 6)
                            .toUpperCase(),
                        )
                      }
                      required
                    />
                  </div>
                  <Button className="w-full" disabled={isLoading}>
                    Continue
                  </Button>
                </form>
              )}

              {step === "reset" && (
                <form className="flex flex-col gap-3" onSubmit={submitPassword}>
                  <div className="text-left flex flex-col gap-3">
                    <Label htmlFor="password">New Password</Label>
                    <PasswordInput
                      id="password"
                      name="password"
                      value={password}
                      onChange={(e) => setPassword(e.target.value)}
                      required
                    />
                    <Label htmlFor="confirmPassword">Confirm Password</Label>
                    <PasswordInput
                      id="confirmPassword"
                      name="confirmPassword"
                      value={confirmPassword}
                      onChange={(e) => setConfirmPassword(e.target.value)}
                      required
                    />
                  </div>
                  <Button className="w-full" disabled={isLoading}>
                    {isLoading ? "Updating..." : "Reset Password"}
                  </Button>
                </form>
              )}

              {step === "done" && (
                <Button asChild className="w-full">
                  <Link href="/sign-in">Go to Sign In</Link>
                </Button>
              )}

              <div className="flex items-center justify-between">
                <span className="text-xs text-gray-600 uppercase">remember password?</span>
                <Link href="/sign-in" className="flex items-center gap-1 text-sm">
                  Sign In <ArrowRight className="w-4 h-4" />
                </Link>
              </div>

              <div className="pt-2 flex justify-center">
                <Button asChild variant="link" className="h-auto p-0">
                  <Link href="/">Back to Home</Link>
                </Button>
              </div>
            </CardContent>
          </Card>
          <Image
            src={bg}
            alt=""
            className="hidden md:block absolute left-32 align-middle h-full top-0"
            width={400}
            height={400}
          />
        </div>
      </div>
    </div>
  );
};

export default Page;