import React, { useEffect, useMemo, useRef, useState } from "react";
import { Link, useSearchParams, useNavigate } from "react-router-dom";
import { motion } from "framer-motion";
import {
  ShieldCheck,
  ArrowLeft,
  RefreshCcw,
  EyeOff,
  Eye,
  Lock,
} from "lucide-react";
import { Button } from "@/shared/common/ui/button";
import { Card, CardContent, CardHeader } from "@/shared/common/ui/card";
import { Input } from "@/shared/common/ui/input";
import { cn } from "@/shared/lib/utils";
import { GenerateVerifcationCodePayload } from "@/shared/services/authService";
import { useAuthUser } from "@/shared/hooks/useAuthUser";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import { useTradeLicenseVerification } from "../hooks/useTradeLicenseVerification";
import { getEtradeLicenseNo } from "../utils/etradeAuthStorage";

interface VerifyOtpProps {
  email?: string;
  phone?: string;
  onComplete?: () => void;
  isExternalOrg?: boolean;
  userId?: string;
  isEtradeVerification?: boolean;
  licenseNo?: string;
}

const OTP_LENGTH = 6;
const RESEND_COOLDOWN_SECONDS = 30;

const VerifyOtp: React.FC<VerifyOtpProps> = ({
  email,
  phone,
  onComplete,
  isExternalOrg,
  userId: propUserId,
  isEtradeVerification,
  licenseNo,
}: VerifyOtpProps) => {
  const [searchParams] = useSearchParams();

  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [otpValues, setOtpValues] = useState<string[]>(
    Array(OTP_LENGTH).fill("")
  );
  const userID = propUserId || searchParams.get("userId") || "";
  const resolvedLicenseNo =
    licenseNo?.trim() ||
    searchParams.get("licenseNo")?.trim() ||
    getEtradeLicenseNo() ||
    "";
  const [message, setMessage] = useState<{
    type: "success" | "error";
    text: string;
  } | null>(null);
  const [error, setError] = useState("");
  const [resendLoading, setResendLoading] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [showPassword, setShowPassword] = useState(false);
  const [showConfirmPassword, setShowConfirmPassword] = useState(false);
  const [cooldown, setCooldown] = useState(0);
  const navigate = useNavigate();
  const { t } = useTranslation();
  const inputsRef = useRef<Array<HTMLInputElement | null>>([]);
  const [hasNavigated, setHasNavigated] = useState(false);
  const requersOtp =
    isExternalOrg || searchParams.get("isExternalOrg") === "true";
  const {
    setPassword,
    setFayidaPassword,
    resendOtpCode,
    setPasswordSuccess,
    setPasswordError,
  } = useAuthUser();
  const { verifyEtradeOtp, isVerifyingOtp } = useTradeLicenseVerification();

  useEffect(() => {
    inputsRef.current[0]?.focus();
  }, []);

  useEffect(() => {
    if (cooldown <= 0) return;
    const t = setInterval(() => setCooldown((s) => (s > 0 ? s - 1 : 0)), 1000);
    return () => clearInterval(t);
  }, [cooldown]);

  useEffect(() => {
    if (setPasswordSuccess && !setPasswordError?.message && !hasNavigated) {
      setMessage({
        type: "success",
        text: t("registration.verifyOtp.messages.success"),
      });
      setHasNavigated(true);
      onComplete?.();
      navigate("/verification_page");
    }
  }, [setPasswordSuccess, setPasswordError]);

  useEffect(() => {
    if (setPasswordError?.message) {
      setMessage({
        type: "error",
        text: setPasswordError.message.includes("OTP")
          ? setPasswordError.message
          : t("registration.verifyOtp.messages.passwordUpdateFailed"),
      });
    }
  }, [setPasswordError]);

  const focusInput = (idx: number) => {
    inputsRef.current[idx]?.focus();
    inputsRef.current[idx]?.select?.();
  };

  const handleOtpChange = (idx: number, value: string) => {
    const char = value.replace(/[^a-zA-Z0-9]/g, "").slice(0, 1);
    if (!char) return;

    const updated = [...otpValues];
    updated[idx] = char;
    setOtpValues(updated);

    if (idx < OTP_LENGTH - 1) {
      setTimeout(() => focusInput(idx + 1), 10); // give DOM time to settle
    }
  };

  const handleOtpKeyDown = (
    idx: number,
    e: React.KeyboardEvent<HTMLInputElement>
  ) => {
    if (e.key === "Backspace") {
      if (otpValues[idx]) {
        setOtpValues((prev) => {
          const next = [...prev];
          next[idx] = "";
          return next;
        });
      } else if (idx > 0) {
        focusInput(idx - 1);
      }
    } else if (e.key === "ArrowLeft" && idx > 0) {
      focusInput(idx - 1);
    } else if (e.key === "ArrowRight" && idx < OTP_LENGTH - 1) {
      focusInput(idx + 1);
    }
  };

  const handleOtpPaste = (e: React.ClipboardEvent<HTMLInputElement>) => {
    const pasted = e.clipboardData.getData("text").replace(/\D/g, "");
    if (!pasted) return;
    e.preventDefault();
    setOtpValues(
      Array(OTP_LENGTH)
        .fill("")
        .map((_, i) => pasted[i] ?? "")
    );
    const lastIndex = Math.min(pasted.length, OTP_LENGTH) - 1;
    focusInput(lastIndex >= 0 ? lastIndex : 0);
  };

  const handleResend = async () => {
    if (!email && !phone) {
      setMessage({
        type: "error",
        text: t("registration.verifyOtp.messages.missingEmailPhone"),
      });
      toast.error(t("registration.verifyOtp.errors.missingUserId"));
      return;
    }
    setResendLoading(true);
    try {
      const payload = {
        email: email || "",
        phoneNumber: phone || "",
      } satisfies GenerateVerifcationCodePayload;
      await resendOtpCode(payload);
      setMessage({
        type: "success",
        text: t("registration.verifyOtp.messages.verificationCodeResent"),
      });
      setCooldown(RESEND_COOLDOWN_SECONDS);
    } catch (err) {
      setMessage({
        type: "error",
        text: t("registration.verifyOtp.messages.resendFailed"),
      });
      toast.error(t("registration.verifyOtp.errors.resendFailed"));
    } finally {
      setResendLoading(false);
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsSubmitting(true);
    setError("");
    setMessage(null);

    if (!isEtradeVerification) {
      if (!newPassword || !confirmPassword) {
        setError(t("registration.verifyOtp.messages.fillPasswords"));
        setIsSubmitting(false);
        return;
      }
      if (newPassword.length < 8) {
        setError(t("registration.verifyOtp.messages.passwordLength"));
        setIsSubmitting(false);
        return;
      }
      if (newPassword !== confirmPassword) {
        setError(t("registration.verifyOtp.messages.passwordMismatch"));
        setIsSubmitting(false);
        return;
      }
    }
    if (requersOtp) {
      const code = otpValues.join("");

      if (isEtradeVerification) {
        if (!resolvedLicenseNo) {
          setError(t("registration.etrade.licenseNoRequired"));
          setIsSubmitting(false);
          return;
        }
        if (code.length !== OTP_LENGTH || !/^[a-zA-Z0-9]{6}$/.test(code)) {
          setError(t("registration.verifyOtp.messages.invalidOtp"));
          setIsSubmitting(false);
          return;
        }

        try {
          await verifyEtradeOtp({
            licenseNo: resolvedLicenseNo,
            otp: code,
          });
          onComplete?.();
          navigate("/login");
        } catch (err) {
          setError(t("registration.verifyOtp.messages.invalidOtp"));
        }
        setIsSubmitting(false);
        return;
      }

      if (code.length !== OTP_LENGTH || !/^[a-zA-Z0-9]{6}$/.test(code)) {
        setError(t("registration.verifyOtp.messages.invalidOtp"));
        setIsSubmitting(false);
        return;
      }

      if (!email && !phone) {
        setError(t("registration.verifyOtp.messages.missingEmailPhone"));
        setIsSubmitting(false);
        return;
      }
      const passwordPayload: any = {
        email: email || "",
        verificationCode: code,
        newPassword,
        confirmPassword,
      };
      if (userID) {
        passwordPayload.userId = userID;
      }
      await setPassword(passwordPayload);
    } else {
      await setFayidaPassword({
        userId: userID,
        newPassword,
        confirmPassword,
      });
      navigate("/login");
    }
    setIsSubmitting(false);
  };

  const pageFade = { initial: { opacity: 0 }, animate: { opacity: 1 } };

  return (
    <motion.div
      {...pageFade}
      className="min-h-screen w-full bg-gradient-to-b from-background to-muted/30 flex items-center justify-center p-4">
      <Card className="w-full max-w-md shadow-xl border-0">
        <CardHeader className="text-center">
          <img
            src="/assets/smart-office-logo.svg"
            alt="Smart Office Logo"
            className="h-10 mx-auto mb-2"
          />
          <h1 className="text-2xl font-bold">
            {t("registration.verifyOtp.title")}
          </h1>
          <p className="text-sm text-muted-foreground">
            {isEtradeVerification
              ? t("registration.etrade.otpVerificationDescription")
              : t("registration.verifyOtp.description", {
                  channel: email
                    ? t("registration.verifyOtp.channel.email")
                    : t("registration.verifyOtp.channel.phone"),
                })}
          </p>
        </CardHeader>
        <CardContent className="space-y-6">
          {requersOtp && (
            <div className="flex justify-center gap-2">
              {Array.from({ length: OTP_LENGTH }).map((_, idx) => (
                <Input
                  key={idx}
                  ref={(el) => {
                    inputsRef.current[idx] = el;
                  }}
                  inputMode="text"
                  pattern="[a-zA-Z0-9]{1}"
                  maxLength={1}
                  value={otpValues[idx]}
                  onChange={(e) => handleOtpChange(idx, e.target.value)}
                  onKeyDown={(e) => handleOtpKeyDown(idx, e)}
                  onPaste={handleOtpPaste}
                  className="w-10 h-12 text-center text-xl tracking-widest"
                  aria-label={t("registration.verifyOtp.otpInput.ariaLabel", {
                    index: idx + 1,
                  })}
                />
              ))}
            </div>
          )}

          <form onSubmit={handleSubmit} className="space-y-4">
            {!isEtradeVerification && (
              <>
            <div className="relative">
              <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                <Lock className="h-5 w-5 text-gray-400" />
              </div>
              <Input
                type={showPassword ? "text" : "password"}
                placeholder={t("registration.verifyOtp.password.newPassword")}
                className="h-10 rounded-md border px-4 text-sm ps-10"
                value={newPassword}
                onChange={(e) => setNewPassword(e.target.value)}
                required
              />
              <div
                className="absolute inset-y-0 right-0 pr-3 flex items-center cursor-pointer"
                onClick={() => setShowPassword(!showPassword)}>
                {showPassword ? (
                  <EyeOff className="h-4 w-4 text-gray-400" />
                ) : (
                  <Eye className="h-4 w-4 text-gray-400" />
                )}
              </div>
            </div>

            <div className="relative">
              <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                <Lock className="h-5 w-5 text-gray-400" />
              </div>
              <Input
                type={showConfirmPassword ? "text" : "password"}
                placeholder={t(
                  "registration.verifyOtp.password.confirmPassword"
                )}
                className="h-10 rounded-md border px-4 text-sm ps-10"
                value={confirmPassword}
                onChange={(e) => setConfirmPassword(e.target.value)}
                required
              />
              <div
                className="absolute inset-y-0 right-0 pr-3 flex items-center cursor-pointer"
                onClick={() => setShowConfirmPassword(!showConfirmPassword)}>
                {showConfirmPassword ? (
                  <EyeOff className="h-4 w-4 text-gray-400" />
                ) : (
                  <Eye className="h-4 w-4 text-gray-400" />
                )}
              </div>
            </div>
              </>
            )}

            {error && <p className="text-sm text-red-500">{error}</p>}

            <div className="flex flex-col gap-2">
              <Button
                type="submit"
                className="w-full"
                disabled={isSubmitting || isVerifyingOtp}>
                {isSubmitting || isVerifyingOtp
                  ? t("registration.verifyOtp.buttons.verifying")
                  : isEtradeVerification
                    ? t("registration.verifyOtp.buttons.verifyOtp")
                    : t("registration.verifyOtp.buttons.completeRegistration")}
              </Button>
            </div>
          </form>
          {!isEtradeVerification && (
          <Button
            variant="outline"
            className="w-full"
            onClick={() => void handleResend()}
            disabled={resendLoading || cooldown > 0}
            aria-label={
              resendLoading
                ? t("registration.verifyOtp.buttons.resendLoading")
                : cooldown > 0
                ? t("registration.verifyOtp.buttons.resendCooldown", {
                    seconds: cooldown,
                  })
                : t("registration.verifyOtp.buttons.resendCode")
            }>
            {resendLoading ? (
              <span className="inline-flex items-center gap-2">
                <RefreshCcw className="h-4 w-4 animate-spin" />
                {t("registration.verifyOtp.buttons.resending")}
              </span>
            ) : cooldown > 0 ? (
              t("registration.verifyOtp.buttons.resendIn", {
                seconds: cooldown,
              })
            ) : (
              t("registration.verifyOtp.buttons.resendCode")
            )}
          </Button>
          )}
          <div className="min-h-12" aria-live="polite" aria-atomic="true">
            {message && (
              <motion.div
                initial={{ opacity: 0, y: -8 }}
                animate={{ opacity: 1, y: 0 }}
                className={cn(
                  "p-3 rounded-lg flex items-start gap-3",
                  message.type === "success"
                    ? "bg-primary-50 text-primary-700"
                    : "bg-red-50 text-red-700"
                )}>
                <ShieldCheck
                  className={cn(
                    "h-5 w-5 flex-shrink-0 mt-0.5",
                    message.type === "success"
                      ? "text-primary-500"
                      : "text-red-500"
                  )}
                />
                <p className="text-sm font-medium">{message.text}</p>
              </motion.div>
            )}
          </div>
          <div className="text-center text-sm">
            <Link
              to="/support/resend-sms"
              className="text-muted-foreground hover:text-foreground">
              {t("registration.verifyOtp.support.needHelp")}
            </Link>
          </div>
        </CardContent>
      </Card>
    </motion.div>
  );
};

export default VerifyOtp;
