import { useState } from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { ArrowRight, Check, Eye, EyeOff, X } from "lucide-react";
import { Controller, useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { z } from "zod";
import RPNInput from "react-phone-number-input";
import "react-phone-number-input/style.css";

import { userType } from "@/enums/userType";
import useAuth from "@/hooks/useAuth";
import type { SignupPayload } from "@/types/auth";
import AuthShell, { fieldClass, primaryButtonClass } from "@/components/auth/AuthShell";
import { isValidPhone } from "@/components/PhoneField";
import "@/components/phone-field.css";

const EDR_LOGO = "/assets/edr-logo.png";

const passwordRequirements = [
  { label: "At least 8 characters", test: (v: string) => v.length >= 8 },
  { label: "One uppercase letter", test: (v: string) => /[A-Z]/.test(v) },
  { label: "One lowercase letter", test: (v: string) => /[a-z]/.test(v) },
  { label: "One number", test: (v: string) => /\d/.test(v) },
  { label: "One special character", test: (v: string) => /[^A-Za-z0-9]/.test(v) },
] as const;

const userSchema = z
  .object({
    email: z.string().email("Invalid email address"),
    phone: z
      .string()
      .min(1, "Phone number is required")
      .refine(isValidPhone, "Enter a valid phone number"),
    userType: z.string(),
    firstName: z.object({ en: z.string().min(2, "Name is required"), am: z.string().nullable() }),
    lastName: z.object({ en: z.string().min(2, "Name is required"), am: z.string().nullable() }),
    password: z
      .string()
      .min(8, "Password must be at least 8 characters")
      .regex(/[A-Z]/, "Password must include an uppercase letter")
      .regex(/[a-z]/, "Password must include a lowercase letter")
      .regex(/\d/, "Password must include a number")
      .regex(/[^A-Za-z0-9]/, "Password must include a special character"),
    confirmPassword: z.string().min(1, "Please confirm your password"),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: "Passwords do not match",
    path: ["confirmPassword"],
  });

type FormData = z.infer<typeof userSchema>;

const errorText = (msg?: string) =>
  msg ? <p className="mt-1 text-xs text-red-600">{msg}</p> : null;

export default function SignupPage() {
  const navigate = useNavigate();
  const { signup } = useAuth();
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [showPassword, setShowPassword] = useState(false);
  const [showConfirm, setShowConfirm] = useState(false);

  const {
    register,
    handleSubmit,
    watch,
    control,
    formState: { errors },
  } = useForm<FormData>({
    resolver: zodResolver(userSchema),
    defaultValues: {
      email: "",
      phone: "",
      userType: userType.individual,
      firstName: { en: "", am: "" },
      lastName: { en: "", am: "" },
      password: "",
      confirmPassword: "",
    },
  });

  const onSubmit = async (data: FormData) => {
    setError(null);
    setLoading(true);
    try {
      const payload: SignupPayload = {
        email: data.email,
        username: data.email,
        // Already a canonical E.164 string from the phone field (e.g. +251912345678).
        phoneNumber: data.phone,
        userType: data.userType,
        name: {
          en: `${data.firstName.en} ${data.lastName.en}`,
          am: `${data.firstName.en} ${data.lastName.en}`,
        },
        password: data.password,
        confirmPassword: data.confirmPassword,
      };
      const result = await signup(payload);
      if (result.success) {
        navigate("/portal");
      } else {
        setError(result.error.message);
      }
    } catch {
      setError("An unexpected error occurred");
    } finally {
      setLoading(false);
    }
  };

  const passwordValue = watch("password") ?? "";

  return (
    <AuthShell
      tagline="Smart Freight Operations"
      taglineBody="Join EDR Freight to manage shipments, track consignments, and streamline logistics workflows across Ethiopia and Djibouti."
    >
      <form className="flex w-full flex-col" onSubmit={handleSubmit(onSubmit)}>
        <div className="mb-4 flex justify-center sm:mb-6">
          <img src={EDR_LOGO} alt="EDR Freight" className="h-9 w-auto sm:h-11" />
        </div>

        <div className="mb-4 space-y-1.5 text-center sm:mb-5">
          <h1 className="text-xl font-bold tracking-tight text-gray-900 sm:text-2xl">
            Create account
          </h1>
          <p className="text-sm leading-relaxed text-gray-500">
            Register to access EDR Freight services.
          </p>
        </div>

        <div className="flex w-full flex-col gap-4">
          <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
            <div className="space-y-1.5">
              <label className="text-sm font-medium text-gray-800">
                First name <span className="text-red-500">*</span>
              </label>
              <input
                placeholder="John"
                disabled={loading}
                className={fieldClass}
                {...register("firstName.en")}
              />
              {errorText(errors.firstName?.en?.message)}
            </div>
            <div className="space-y-1.5">
              <label className="text-sm font-medium text-gray-800">
                Last name <span className="text-red-500">*</span>
              </label>
              <input
                placeholder="Doe"
                disabled={loading}
                className={fieldClass}
                {...register("lastName.en")}
              />
              {errorText(errors.lastName?.en?.message)}
            </div>
          </div>

          <div className="space-y-1.5">
            <label className="text-sm font-medium text-gray-800">
              Email <span className="text-red-500">*</span>
            </label>
            <input
              type="email"
              placeholder="john@example.com"
              disabled={loading}
              className={fieldClass}
              {...register("email")}
            />
            {errorText(errors.email?.message)}
          </div>

          <div className="space-y-1.5">
            <label htmlFor="signup-phone" className="text-sm font-medium text-gray-800">
              Phone <span className="text-red-500">*</span>
            </label>
            <Controller
              control={control}
              name="phone"
              render={({ field }) => (
                <div
                  className={`edr-phone-wrapper${
                    errors.phone ? " edr-phone-wrapper--error" : ""
                  }`}
                >
                  <RPNInput
                    international
                    defaultCountry="ET"
                    countryCallingCodeEditable={false}
                    addInternationalOption
                    id="signup-phone"
                    placeholder="912 345 678"
                    disabled={loading}
                    value={field.value || undefined}
                    onChange={(v) => field.onChange(v ?? "")}
                    onBlur={field.onBlur}
                  />
                </div>
              )}
            />
            {errorText(errors.phone?.message)}
          </div>

          <div className="space-y-1.5">
            <label className="text-sm font-medium text-gray-800">
              Password <span className="text-red-500">*</span>
            </label>
            <div className="relative">
              <input
                type={showPassword ? "text" : "password"}
                placeholder="Create a strong password"
                disabled={loading}
                className={`${fieldClass} pr-11`}
                {...register("password")}
              />
              <button
                type="button"
                onClick={() => setShowPassword((current) => !current)}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 transition-colors hover:text-gray-600"
                aria-label={showPassword ? "Hide password" : "Show password"}
              >
                {showPassword ? <EyeOff className="h-5 w-5" /> : <Eye className="h-5 w-5" />}
              </button>
            </div>
            {errorText(errors.password?.message)}
            {passwordValue.length > 0 ? (
              <div className="mt-2 space-y-1">
                {passwordRequirements.map((req) => {
                  const met = req.test(passwordValue);
                  return (
                    <div key={req.label} className="flex items-center gap-2">
                      <span
                        className={`flex h-4 w-4 shrink-0 items-center justify-center rounded-full ${
                          met ? "bg-primary text-primary-foreground" : "bg-gray-200 text-gray-500"
                        }`}
                      >
                        {met ? <Check className="h-2.5 w-2.5" /> : <X className="h-2.5 w-2.5" />}
                      </span>
                      <span className={`text-xs ${met ? "text-primary" : "text-gray-500"}`}>
                        {req.label}
                      </span>
                    </div>
                  );
                })}
              </div>
            ) : null}
          </div>

          <div className="space-y-1.5">
            <label className="text-sm font-medium text-gray-800">
              Confirm password <span className="text-red-500">*</span>
            </label>
            <div className="relative">
              <input
                type={showConfirm ? "text" : "password"}
                placeholder="Re-enter your password"
                disabled={loading}
                className={`${fieldClass} pr-11`}
                {...register("confirmPassword")}
              />
              <button
                type="button"
                onClick={() => setShowConfirm((current) => !current)}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 transition-colors hover:text-gray-600"
                aria-label={showConfirm ? "Hide password" : "Show password"}
              >
                {showConfirm ? <EyeOff className="h-5 w-5" /> : <Eye className="h-5 w-5" />}
              </button>
            </div>
            {errorText(errors.confirmPassword?.message)}
          </div>

          {error ? (
            <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2.5 text-sm text-red-700">
              {error}
            </div>
          ) : null}

          <button
            type="submit"
            disabled={loading}
            className={`${primaryButtonClass} flex items-center justify-center gap-2`}
          >
            {loading ? "Creating account..." : "Create Account"}
            {!loading ? <ArrowRight className="h-4 w-4" /> : null}
          </button>

          <p className="text-center text-sm text-gray-500">
            Already have an account?{" "}
            <button
              type="button"
              onClick={() => navigate("/login")}
              className="font-semibold text-primary hover:underline"
            >
              Sign In
            </button>
          </p>
        </div>
      </form>
    </AuthShell>
  );
}
