"use client";

import { ReactNode, useState } from "react";
import PrivacyPolicyModal from "@/src/components/ui/PrivacyPolicyModal";
import { getPrivacyPolicyDataAction } from "@/src/lib/actions/privacyPolicyAction";
import { getTermsOfUseDataAction } from "@/src/lib/actions/termsOfUseAction";

interface PolicySection {
  heading?: string;
  effectiveDate?: string;
  content?: string;
}

interface PolicyAgreementProps {
  /**
   * Full agreement sentence (e.g. "I agree to the terms of use and privacy policy").
   * Any occurrence of the privacy / terms phrases is turned into a clickable link.
   * Use this when the copy comes as a single string from the backend.
   */
  text?: string;
  /**
   * Structured alternative to `text` — renders "{prefixText} {privacy} {andText} {terms}".
   */
  prefixText?: string;
  andText?: string;
  /** Phrase used for the Privacy Policy link (also matched inside `text`). */
  privacyLinkText?: string;
  /** Phrase used for the Terms of Use link (also matched inside `text`). */
  termsLinkText?: string;
  franchiseeId?: string | null;
  language?: string | null;
  className?: string;
  linkClassName?: string;
}

const escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

export default function PolicyAgreement({
  text,
  prefixText,
  andText = " and ",
  privacyLinkText = "Privacy Policy",
  termsLinkText = "Terms of Use",
  franchiseeId,
  language,
  className = "text-[#58585A] text-[14px] md:text-[14px] font-light",
  linkClassName = "text-[#0097DC] cursor-pointer hover:underline",
}: PolicyAgreementProps) {
  // Privacy Policy modal state
  const [isPrivacyOpen, setIsPrivacyOpen] = useState(false);
  const [isPrivacyLoading, setIsPrivacyLoading] = useState(false);
  const [privacyContent, setPrivacyContent] = useState<PolicySection | null>(null);
  const [privacyFetched, setPrivacyFetched] = useState(false);

  // Terms of Use modal state
  const [isTermsOpen, setIsTermsOpen] = useState(false);
  const [isTermsLoading, setIsTermsLoading] = useState(false);
  const [termsContent, setTermsContent] = useState<PolicySection | null>(null);
  const [termsFetched, setTermsFetched] = useState(false);

  const openPrivacyPolicy = async () => {
    setIsPrivacyOpen(true);
    if (privacyFetched) return;
    setIsPrivacyLoading(true);
    try {
      const response = await getPrivacyPolicyDataAction(franchiseeId ?? undefined, language ?? undefined);
      if (response?.success && response.data) {
        setPrivacyContent(
          response.data.translated?.privacyPolicy ||
            response.data.default?.privacyPolicy ||
            null,
        );
      }
      setPrivacyFetched(true);
    } catch (error) {
      console.error("Error fetching privacy policy:", error);
    } finally {
      setIsPrivacyLoading(false);
    }
  };

  const openTermsOfUse = async () => {
    setIsTermsOpen(true);
    if (termsFetched) return;
    setIsTermsLoading(true);
    try {
      const response = await getTermsOfUseDataAction(franchiseeId ?? undefined, language ?? undefined);
      if (response?.success && response.data) {
        setTermsContent(
          (response.data.translated as any)?.termsOfUse ||
            (response.data.translated as any)?.privacyPolicy ||
            (response.data.default as any)?.termsOfUse ||
            (response.data.default as any)?.privacyPolicy ||
            null,
        );
      }
      setTermsFetched(true);
    } catch (error) {
      console.error("Error fetching terms of use:", error);
    } finally {
      setIsTermsLoading(false);
    }
  };

  const privacyLink = (label: string, key: string | number) => (
    <a
      key={key}
      className={linkClassName}
      onClick={(e) => {
        e.stopPropagation();
        openPrivacyPolicy();
      }}
    >
      {label}
    </a>
  );

  const termsLink = (label: string, key: string | number) => (
    <a
      key={key}
      className={linkClassName}
      onClick={(e) => {
        e.stopPropagation();
        openTermsOfUse();
      }}
    >
      {label}
    </a>
  );

  // Turn every occurrence of the privacy / terms phrases inside `text` into a link.
  const linkify = (source: string): ReactNode[] => {
    const regex = new RegExp(
      `(${escapeRegExp(privacyLinkText)}|${escapeRegExp(termsLinkText)})`,
      "gi",
    );
    const nodes: ReactNode[] = [];
    let lastIndex = 0;
    let key = 0;
    let match: RegExpExecArray | null;

    while ((match = regex.exec(source)) !== null) {
      if (match.index > lastIndex) {
        nodes.push(source.slice(lastIndex, match.index));
      }
      const matched = match[0];
      if (matched.toLowerCase() === privacyLinkText.toLowerCase()) {
        nodes.push(privacyLink(matched, key++));
      } else {
        nodes.push(termsLink(matched, key++));
      }
      lastIndex = match.index + matched.length;
    }
    if (lastIndex < source.length) {
      nodes.push(source.slice(lastIndex));
    }
    return nodes;
  };

  return (
    <>
      <span className={className}>
        {text !== undefined ? (
          linkify(text)
        ) : (
          <>
            {prefixText ? `${prefixText} ` : ""}
            {privacyLink(privacyLinkText, "p")}
            {andText}
            {termsLink(termsLinkText, "t")}
          </>
        )}
      </span>

      <PrivacyPolicyModal
        isOpen={isPrivacyOpen}
        onClose={() => setIsPrivacyOpen(false)}
        heading={privacyContent?.heading}
        effectiveDate={privacyContent?.effectiveDate}
        content={privacyContent?.content}
        isLoading={isPrivacyLoading}
        linkLabel={privacyLinkText}
      />

      <PrivacyPolicyModal
        isOpen={isTermsOpen}
        onClose={() => setIsTermsOpen(false)}
        heading={termsContent?.heading}
        effectiveDate={termsContent?.effectiveDate}
        content={termsContent?.content}
        isLoading={isTermsLoading}
        linkLabel={termsLinkText}
      />
    </>
  );
}
