"use client";

import React, { useState, useRef, useEffect } from "react";
import { useRouter } from "next/navigation";
import Script from "next/script";
import { HiOutlineEnvelope, HiOutlinePhone } from "react-icons/hi2";
import { motion, AnimatePresence } from "framer-motion";
import Image from "next/image";
import { playfair, montserrat } from "@/lib/fonts";
import styles from "./RequestForm.module.css";

interface FormFields {
  firstName: string;
  lastName: string;
  email: string;
  mobile: string;
  subscribe: boolean;
}

export default function RequestForm({ data }: { data?: any }) {
  const form = data?.included?.forms?.["2"];
  const router = useRouter();
  const sectionRef = useRef<HTMLElement>(null);

  const getField = (name: string) => form?.fields?.find((f: any) => f.name === name);
  const fNameField = getField("firstName");
  const lNameField = getField("lastName");
  const emailField = getField("email");
  const phoneField = getField("phone");
  const subscribeField = getField("subscribe");

  const [formData, setFormData] = useState<FormFields>({
    firstName: "",
    lastName: "",
    email: "",
    mobile: "",
    subscribe: false,
  });

  const [errors, setErrors] = useState<Partial<Record<keyof FormFields, string>>>({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isSubmitted, setIsSubmitted] = useState(false);
  const [successMsg, setSuccessMsg] = useState("");
  const [bgTooltipPos, setBgTooltipPos] = useState<{ x: number; y: number } | null>(null);
  const [textTooltipPos, setTextTooltipPos] = useState<{ x: number; y: number } | null>(null);
  const bgTimerRef = useRef<NodeJS.Timeout | null>(null);
  const textTimerRef = useRef<NodeJS.Timeout | null>(null);
  const [loadRecaptcha, setLoadRecaptcha] = useState(false);

  // Clear any saved form redirect state on mount
  useEffect(() => {
    sessionStorage.removeItem("formRedirectSlug");
    sessionStorage.removeItem("formRedirectOrigin");
    if (window.location.search) {
      window.history.replaceState(null, "", window.location.pathname);
    }
  }, []);

  // Load reCAPTCHA only when the form section scrolls into view
  useEffect(() => {
    const node = sectionRef.current;
    if (!node) return;
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setLoadRecaptcha(true);
          observer.disconnect();
        }
      },
      { rootMargin: "200px" }
    );
    observer.observe(node);
    return () => observer.disconnect();
  }, []);

  // Ensure reCAPTCHA script is loaded and ready. Used as a fallback when users
  // submit without prior interaction (ensures window.grecaptcha.execute exists).
  const ensureRecaptchaLoaded = async () => {
    if (typeof window === "undefined") return;
    const win = window as any;
    if (win.grecaptcha && typeof win.grecaptcha.execute === "function") return;
    if (win.__grecaptchaLoading) return await win.__grecaptchaLoading;

    win.__grecaptchaLoading = new Promise<void>((resolve, reject) => {
      const src = `https://www.google.com/recaptcha/api.js?render=${process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}`;
      const s = document.createElement("script");
      s.src = src;
      s.async = true;
      s.defer = true;
      s.onload = () => {
        const start = Date.now();
        const check = () => {
          if (win.grecaptcha && typeof win.grecaptcha.execute === "function") {
            resolve();
          } else if (Date.now() - start > 5000) {
            reject(new Error("reCAPTCHA failed to load in time"));
          } else {
            setTimeout(check, 50);
          }
        };
        check();
      };
      s.onerror = (e) => reject(e);
      document.head.appendChild(s);
    });

    return await win.__grecaptchaLoading;
  };

  const validate = () => {
    const newErrors: Partial<Record<keyof FormFields, string>> = {};
    if (!formData.firstName.trim()) newErrors.firstName = "First name is required";
    if (!formData.lastName.trim()) newErrors.lastName = "Last name is required";
    if (!formData.email.trim()) {
      newErrors.email = "Email is required";
    } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
      newErrors.email = "Please enter a valid email address";
    }
    if (!formData.mobile.trim()) {
      newErrors.mobile = "Mobile number is required";
    } else if (!/^\+?[\d\s-]{8,}$/.test(formData.mobile)) {
      newErrors.mobile = "Please enter a valid mobile number";
    }
    return newErrors;
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value, type, checked } = e.target;
    setFormData((prev) => ({
      ...prev,
      [name]: type === "checkbox" ? checked : value,
    }));
    if (errors[name as keyof FormFields]) {
      setErrors((prev) => ({ ...prev, [name]: "" }));
    }
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const validationErrors = validate();
    if (Object.keys(validationErrors).length > 0) {
      setErrors(validationErrors);
      return;
    }

    setIsSubmitting(true);

      try {
        // Ensure grecaptcha is available (load on-demand as a fallback)
        if (!loadRecaptcha) setLoadRecaptcha(true);
        // Wait for grecaptcha to be ready (either loaded by Script or loaded here)
        // @ts-ignore
        await ensureRecaptchaLoaded();
        // @ts-ignore
        const token = await window.grecaptcha.execute(process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY, { action: "submit" });

      const payload = {
        form: String(form?.id || "2"),
        submissionData: [
          { field: "firstName", value: formData.firstName },
          { field: "lastName", value: formData.lastName },
          { field: "email", value: formData.email },
          { field: "phone", value: formData.mobile },
          { field: "subscribe", value: formData.subscribe ? "on" : "off" },
        ],
        recaptchaToken: token,
      };

      const res = await fetch("/api/scilly/newsletter", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });

      if (!res.ok) throw new Error("Failed to submit");

      const resData = await res.json();

      if (form?.confirmationType === "redirect" && form?.redirect) {
        const { redirectType, url, slug } = form.redirect;
        const cleanSlug = slug?.replace(/^#+/, "") ?? "";
        const targetUrl = redirectType === "internal" ? `/${cleanSlug}` : url;
        if (targetUrl) {
          setIsSubmitted(true);
          if (redirectType === "internal") {
            const origin = window.location.pathname;
            sessionStorage.setItem("formRedirectSlug", cleanSlug);
            sessionStorage.setItem("formRedirectOrigin", origin);
            window.history.pushState({}, "", `?${cleanSlug}`);
            setTimeout(() => {
              window.history.replaceState(null, "", origin);
              sessionStorage.removeItem("formRedirectSlug");
              sessionStorage.removeItem("formRedirectOrigin");
              setIsSubmitted(false);
              setSuccessMsg("");
              setFormData({ firstName: "", lastName: "", email: "", mobile: "", subscribe: false });
            }, 10000);
          } else {
            setTimeout(() => { router.push(targetUrl); }, 2000);
          }
          return;
        }
      }

      setSuccessMsg(resData.message || form?.successMessage || "Request submitted successfully!");
      setIsSubmitted(true);
      setFormData({ firstName: "", lastName: "", email: "", mobile: "", subscribe: false });
    } catch (error) {
      console.error("Form submission error:", error);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <section ref={sectionRef} className={`${styles.section} ${montserrat.className}`} style={{ position: "relative", overflow: "hidden", minHeight: "451px" }}>
      {loadRecaptcha && (
        <Script
          src={`https://www.google.com/recaptcha/api.js?render=${process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}`}
          strategy="afterInteractive"
        />
      )}
      <div className={styles.container} style={{ position: "relative" }}>
        <AnimatePresence>
          {!isSubmitted && (
            <motion.div
              key="form"
              initial={{ x: 0, opacity: 1 }}
              exit={{ x: -100, opacity: 0 }}
              transition={{ duration: 0.5, ease: "easeInOut" }}
            >
              <h2 className={`${styles.title} ${playfair.className}`}>{form?.title}</h2>
              <p className={styles.subtitle}>{form?.description}</p>

              <form onSubmit={handleSubmit} onFocus={() => setLoadRecaptcha(true)} onMouseEnter={() => setLoadRecaptcha(true)} className={styles.form} noValidate>
                <div className={styles.row}>
                  <div className={styles.fieldGroup}>
                    <input
                      type="text"
                      name="firstName"
                      placeholder={`${fNameField?.label}*`}
                      value={formData.firstName}
                      onChange={handleChange}
                      className={`${styles.input} ${errors.firstName ? styles.inputError : ""}`}
                    />
                    {errors.firstName && <span className={styles.errorText}>{errors.firstName}</span>}
                  </div>
                  <div className={styles.fieldGroup}>
                    <input
                      type="text"
                      name="lastName"
                      placeholder={`${lNameField?.label}*`}
                      value={formData.lastName}
                      onChange={handleChange}
                      className={`${styles.input} ${errors.lastName ? styles.inputError : ""}`}
                    />
                    {errors.lastName && <span className={styles.errorText}>{errors.lastName}</span>}
                  </div>
                </div>

                <div className={styles.row}>
                  <div className={styles.fieldGroup}>
                    <div className={styles.inputWrapper}>
                      <HiOutlineEnvelope className={styles.icon} />
                      <input
                        type="email"
                        name="email"
                        placeholder={`${emailField?.label}*`}
                        value={formData.email}
                        onChange={handleChange}
                        className={`${styles.input} ${styles.inputWithIcon} ${errors.email ? styles.inputError : ""}`}
                      />
                    </div>
                    {errors.email && <span className={styles.errorText}>{errors.email}</span>}
                  </div>
                  <div className={styles.fieldGroup}>
                    <div className={styles.inputWrapper}>
                      <HiOutlinePhone className={styles.icon} />
                      <input
                        type="tel"
                        name="mobile"
                        placeholder={`${phoneField?.label}*`}
                        value={formData.mobile}
                        onChange={handleChange}
                        className={`${styles.input} ${styles.inputWithIcon} ${errors.mobile ? styles.inputError : ""}`}
                      />
                    </div>
                    {errors.mobile && <span className={styles.errorText}>{errors.mobile}</span>}
                  </div>
                </div>

                <div className={styles.checkboxGroup}>
                  <label className={styles.checkboxLabel}>
                    <input
                      type="checkbox"
                      name="subscribe"
                      checked={formData.subscribe}
                      onChange={handleChange}
                      className={styles.checkbox}
                    />
                    <span className={styles.checkboxText}>{subscribeField?.label}</span>
                  </label>
                  {errors.subscribe && <span className={styles.errorText} style={{ display: "block", marginTop: "5px" }}>{errors.subscribe}</span>}
                </div>

                <div className="flex justify-center">
                  <div className={styles.buttonWrapper}>
                    <button type="submit" id={form?.submitButtonId ?? undefined} disabled={isSubmitting} className={styles.button}>
                      {isSubmitting ? "Submitting..." : form?.submitButtonLabel}
                      <svg
                        viewBox="0 0 39 14"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                        className="h-auto w-[20px] transition-transform duration-300 group-hover:translate-x-1 sm:h-[14px] sm:w-[38.07px]"
                      >
                        <path d="M1 7H38M31 1L38 7L31 13" stroke="currentColor" strokeWidth="1.59" strokeLinecap="round" strokeLinejoin="round" />
                      </svg>
                    </button>
                  </div>
                </div>
              </form>
            </motion.div>
          )}
        </AnimatePresence>
      </div>

      <AnimatePresence>
        {isSubmitted && (
          <motion.div
            key="thankyou"
            initial={{ x: "100%", opacity: 0 }}
            animate={{ x: 0, opacity: 1 }}
            exit={{ x: "100%", opacity: 0 }}
            transition={{ duration: 0.6, ease: "easeInOut" }}
            className={styles.thankyouContainer}
          >
            <div
              className={styles.thankyouBackground}
              onMouseMove={(e) => {
                const r = e.currentTarget.getBoundingClientRect();
                if (bgTimerRef.current) clearTimeout(bgTimerRef.current);
                setBgTooltipPos(null);
                bgTimerRef.current = setTimeout(() => setBgTooltipPos({ x: e.clientX - r.left, y: e.clientY - r.top }), 1000);
              }}
              onMouseLeave={() => { if (bgTimerRef.current) clearTimeout(bgTimerRef.current); setBgTooltipPos(null); }}
            >
              <Image src="/scilly/Thank you Page.png" alt="Thank you background" fill className="object-cover opacity-80" />
              <div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent" />
              <AnimatePresence>
                {bgTooltipPos && (
                  <motion.div
                    initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.95 }}
                    transition={{ duration: 0.12 }}
                    style={{ position: "absolute", left: bgTooltipPos.x, top: bgTooltipPos.y, transform: "translate(-50%, calc(-100% - 8px))", pointerEvents: "none", zIndex: 200, whiteSpace: "nowrap" }}
                    className="rounded border border-black bg-white px-3 py-1.5 text-sm font-semibold text-black shadow-sm"
                  >
                    Thank you background
                  </motion.div>
                )}
              </AnimatePresence>
            </div>

            <div className={styles.thankyouContent}>
              <div
                className="relative"
                onMouseMove={(e) => {
                  const r = e.currentTarget.getBoundingClientRect();
                  if (textTimerRef.current) clearTimeout(textTimerRef.current);
                  setTextTooltipPos(null);
                  textTimerRef.current = setTimeout(() => setTextTooltipPos({ x: e.clientX - r.left, y: e.clientY - r.top }), 1000);
                }}
                onMouseLeave={() => { if (textTimerRef.current) clearTimeout(textTimerRef.current); setTextTooltipPos(null); }}
              >
                <Image src="/scilly/text-1-thank-you.png" alt="Thank You" width={320} height={120} className="h-auto w-[240px] sm:w-[320px] object-contain mb-[68px]" />
                <AnimatePresence>
                  {textTooltipPos && (
                    <motion.div
                      initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.95 }}
                      transition={{ duration: 0.12 }}
                      style={{ position: "absolute", left: textTooltipPos.x, top: textTooltipPos.y, transform: "translate(-50%, calc(-100% - 8px))", pointerEvents: "none", zIndex: 200, whiteSpace: "nowrap" }}
                      className="rounded border border-black bg-white px-3 py-1.5 text-sm font-semibold text-black shadow-sm"
                    >
                      Thank You
                    </motion.div>
                  )}
                </AnimatePresence>
              </div>
              <p className={`${styles.thankyouText} ${playfair.className}`}>
                {successMsg || form?.successMessage}
              </p>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </section>
  );
}
