"use client";

import Checkbox from "@/components/form/input/Checkbox";
import Input from "@/components/form/input/InputField";
import Label from "@/components/form/Label";
import Button from "@/components/ui/button/Button";
import ModalTnC from "@/modules/authModule/signin/components/ModalTnC";
import { isValidEmail } from "@/lib/utils.client";
import { hasPortableTextContent } from "@/lib/tenantContent";
import { getSignupErrorMessage } from "@/modules/authModule/signup/signupErrorMessage";
import { getSignupSuccessMessage } from "@/modules/authModule/signup/signupSuccessMessage";
import { Loader2 } from "lucide-react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import React, { useEffect, useMemo, useState } from "react";
import toast from "react-hot-toast";

export default function SignUpForm({ terms }: { terms?: any }) {
  const TERMS_READ_KEY = "tiar_terms_read";
  const router = useRouter();
  const searchParams = useSearchParams();

  const prefilledEmail = useMemo(
    () => searchParams.get("email")?.trim().toLowerCase() || "",
    [searchParams],
  );
  const signupReason = useMemo(() => searchParams.get("reason") || "", [searchParams]);
  const hasTermsContent = hasPortableTextContent(terms?.body);

  const [email, setEmail] = useState(prefilledEmail);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [acceptTnC, setAcceptTnC] = useState(false);
  const [showTerms, setShowTerms] = useState(false);
  const [canAcceptTerms, setCanAcceptTerms] = useState(false);
  const [hasReadTerms, setHasReadTerms] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (prefilledEmail) {
      setEmail(prefilledEmail);
    }
  }, [prefilledEmail]);

  useEffect(() => {
    if (!hasTermsContent) {
      setHasReadTerms(false);
      setCanAcceptTerms(false);
      setAcceptTnC(false);
      return;
    }

    try {
      const stored = localStorage.getItem(TERMS_READ_KEY);
      if (stored === "true") {
        setHasReadTerms(true);
        setCanAcceptTerms(true);
        setAcceptTnC(true);
      }
    } catch {}
  }, [hasTermsContent]);

  const handleTermsScroll = (e: React.UIEvent<HTMLDivElement>) => {
    if (!hasTermsContent) {
      return;
    }

    const target = e.currentTarget;
    const threshold = 8;
    const reachedBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - threshold;
    if (!reachedBottom) {
      return;
    }

    if (!hasReadTerms) {
      setHasReadTerms(true);
      try {
        localStorage.setItem(TERMS_READ_KEY, "true");
      } catch {}
    }
    setCanAcceptTerms(true);
  };

  const handleTermsContentReady = (container: HTMLDivElement) => {
    if (!hasTermsContent) {
      return;
    }

    const threshold = 8;
    const reachedBottom =
      container.scrollTop + container.clientHeight >= container.scrollHeight - threshold;
    if (!reachedBottom) {
      return;
    }

    if (!hasReadTerms) {
      setHasReadTerms(true);
      try {
        localStorage.setItem(TERMS_READ_KEY, "true");
      } catch {}
    }
    setCanAcceptTerms(true);
  };

  const handleTermsClose = () => {
    setAcceptTnC(false);
    setCanAcceptTerms(false);
    setShowTerms(false);
  };

  const handleTermsAgree = () => {
    setHasReadTerms(true);
    setCanAcceptTerms(true);
    setAcceptTnC(true);
    setShowTerms(false);
  };

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setError(null);

    const normalizedEmail = email.trim().toLowerCase();

    if (!normalizedEmail || !isValidEmail(normalizedEmail)) {
      setError("Enter a valid email address.");
      return;
    }
    if (!hasTermsContent) {
      setError("Terms and Conditions are currently unavailable. Please try again later.");
      return;
    }
    if (!acceptTnC) {
      setError("You need to accept the Terms and Conditions first.");
      return;
    }

    try {
      setIsSubmitting(true);

      const signUpResponse = await fetch("/api/auth/sign-up", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          email: normalizedEmail,
        }),
      });
      const signUpData = await signUpResponse.json().catch(() => ({}));

      if (signUpResponse.status === 409) {
        toast.error(
          getSignupErrorMessage(signUpData?.error || signUpData?.message || "email already exists"),
        );
        return;
      }
      if (!signUpResponse.ok) {
        throw new Error(signUpData?.error || "Failed to create your account");
      }
      toast.success(getSignupSuccessMessage(signUpData));
      router.push(`/check-email?email=${encodeURIComponent(normalizedEmail)}`);
    } catch (submitError) {
      setError(
        getSignupErrorMessage(
          submitError instanceof Error ? submitError.message : "Failed to create your account",
        ),
      );
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div>
      <div className="mb-5 sm:mb-8">
        <h1 className="mb-2 font-semibold text-gray-800 text-title-sm dark:text-white/90 sm:text-title-md">
          Create your account
        </h1>
        <p className="text-sm text-gray-500 dark:text-gray-400">
          Enter your email, accept the Terms, and we’ll send you a verification link to continue.
        </p>
      </div>

      <form onSubmit={handleSubmit}>
        <div className="space-y-5">
          {signupReason === "unregistered-email" && (
            <div className="rounded-lg border border-blue-200 bg-blue-50 p-3">
              <p className="text-sm text-blue-700">
                This email is not registered yet. Create your account to continue.
              </p>
            </div>
          )}
          {error && (
            <div role="alert" className="rounded-lg border border-red-200 bg-red-50 p-3">
              <p className="text-sm text-red-600">{error}</p>
            </div>
          )}

          <div>
            <Label>
              Email <span className="text-error-500">*</span>
            </Label>
            <Input
              placeholder="you@example.com"
              type="email"
              name="email"
              value={email}
              onChange={(e) => setEmail(e.target.value.toLowerCase())}
              disabled={isSubmitting}
            />
          </div>

          <div className="flex items-start gap-3">
            <Checkbox
              className="h-5 w-5"
              checked={canAcceptTerms ? acceptTnC : false}
              onChange={setAcceptTnC}
              disabled={!hasTermsContent || !canAcceptTerms}
            />
            <div>
              <p className="text-theme-sm font-normal text-gray-700 dark:text-gray-400">
                By signing up you agree to the{" "}
                <button
                  type="button"
                  className="text-gray-800 underline hover:text-brand-500 focus:outline-none dark:text-white/90"
                  onClick={() => {
                    if (!hasReadTerms) {
                      setAcceptTnC(false);
                      setCanAcceptTerms(false);
                    }
                    setShowTerms(true);
                  }}
                >
                  Terms and Conditions
                </button>{" "}
                and our <span className="text-gray-800 dark:text-white">Privacy Policy</span>.
              </p>
              <p
                className={`mt-1 text-xs ${canAcceptTerms ? "text-green-600 dark:text-green-400" : "text-gray-500 dark:text-gray-400"}`}
              >
                {!hasTermsContent
                  ? "Terms and Conditions are currently unavailable. Please try again later."
                  : canAcceptTerms
                  ? "You can now tick the checkbox to continue."
                  : "Open the terms and scroll to the bottom to enable the checkbox."}
              </p>
            </div>
          </div>

          <Button
            className="w-full"
            size="sm"
            type="submit"
            disabled={isSubmitting || !email.trim() || !hasTermsContent || !acceptTnC}
          >
            {isSubmitting && <Loader2 className="mr-2 inline h-4 w-4 animate-spin" />}
            {isSubmitting ? "Sending verification..." : "Create account"}
          </Button>

          <div className="text-center text-sm text-gray-500 dark:text-gray-400">
            Already have an account?{" "}
            <Link
              href={
                email.trim()
                  ? `/signin?email=${encodeURIComponent(email.trim().toLowerCase())}`
                  : "/signin"
              }
              className="font-medium text-brand-500 hover:text-brand-600"
            >
              Sign in
            </Link>
          </div>
        </div>
      </form>

      <ModalTnC
        isOpen={showTerms}
        onClose={handleTermsClose}
        onAgree={handleTermsAgree}
        onScroll={handleTermsScroll}
        onContentReady={handleTermsContentReady}
        title={terms?.title}
        body={terms?.body}
      />
    </div>
  );
}
