"use client";

import { useEffect, useMemo, useState } from "react";
import { CalendarDays, ArrowUp } from "lucide-react";
import Footer from "@/src/components/layout/Footer";
import Breadcrumbs from "@/src/components/layout/Breadcrumbs";
import BackButton from "@/src/components/layout/BackButton";
import { useLanguage } from "@/src/lib/context/LanguageContext";
import { withCDN } from "@/src/lib/utils";
import type { ProcessedHeaderFooterHomeData } from "@/src/lib/types/header";

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

type PolicyContent = {
  privacyPolicy?: PolicySection;
  termsOfUse?: PolicySection;
};

interface PolicyPageClientProps {
  headerFooterHomeData: ProcessedHeaderFooterHomeData;
  data: {
    default?: PolicyContent | null;
    translated?: PolicyContent | null;
  };
  /** Primary key the content is stored under. */
  sectionKey: "privacyPolicy" | "termsOfUse";
  fallbackHeading: string;
}

interface ParsedSection {
  id: string;
  number: string;
  title: string;
  body: string;
}

const HEADING_RE = /^\s*(\d+)\.\s+(.+?)\s*$/;

/**
 * Normalize policy copy to plain text with meaningful line breaks. The CMS may
 * store the content as HTML (rich-text editor) instead of plain text — in that
 * case the numbered headings sit inside tags (e.g. `<p>1. Who We Are</p>`) and
 * would never match HEADING_RE. Convert block elements to newlines, strip the
 * remaining tags, and decode common entities so parsing works either way.
 */
function normalizeContent(raw: string): string {
  if (!/<[a-z][\s\S]*?>/i.test(raw)) return raw; // already plain text

  return raw
    .replace(/<\s*br\s*\/?>/gi, "\n")
    .replace(/<\/\s*(p|div|h[1-6]|li|ul|ol|section|article)\s*>/gi, "\n\n")
    .replace(/<[^>]+>/g, "") // strip any remaining tags
    .replace(/&nbsp;/gi, " ")
    .replace(/&amp;/gi, "&")
    .replace(/&lt;/gi, "<")
    .replace(/&gt;/gi, ">")
    .replace(/&quot;/gi, '"')
    .replace(/&#0?39;|&apos;|&rsquo;/gi, "'")
    .replace(/\n{3,}/g, "\n\n") // collapse excess blank lines
    .trim();
}

/** Split a plain-text (or HTML) policy into an intro + numbered sections (if any). */
function parsePolicy(rawContent: string): { intro: string; sections: ParsedSection[] } {
  const content = normalizeContent(rawContent);
  const lines = content.split(/\r?\n/);
  const sections: ParsedSection[] = [];
  const intro: string[] = [];
  let current: ParsedSection | null = null;

  for (const line of lines) {
    const match = line.match(HEADING_RE);
    if (match) {
      if (current) sections.push(current);
      current = {
        id: `section-${match[1]}`,
        number: match[1],
        title: match[2],
        body: "",
      };
    } else if (current) {
      current.body += (current.body ? "\n" : "") + line;
    } else {
      intro.push(line);
    }
  }
  if (current) sections.push(current);

  return { intro: intro.join("\n").trim(), sections };
}

/** Render a text block as spaced paragraphs, preserving single line breaks. */
function Paragraphs({ text, className = "" }: { text: string; className?: string }) {
  const paragraphs = text.split(/\n\s*\n/).map((p) => p.trim()).filter(Boolean);
  return (
    <>
      {paragraphs.map((para, i) => (
        <p
          key={i}
          className={`text-[#4B4B4D] font-[Signika] text-[15px] md:text-[17px] leading-[1.9] whitespace-pre-line ${className}`}
        >
          {para}
        </p>
      ))}
    </>
  );
}

export default function PolicyPageClient({
  headerFooterHomeData,
  data,
  sectionKey,
  fallbackHeading,
}: PolicyPageClientProps) {
  const { currentLanguage } = useLanguage();
  const [activeId, setActiveId] = useState<string | null>(null);

  const section = useMemo<PolicySection | null>(() => {
    const preferTranslated = !!currentLanguage && currentLanguage !== "default";
    const pick = (src?: PolicyContent | null) =>
      // Some franchisees store the copy under a generic `privacyPolicy` key even
      // for Terms of Use, so fall back to it before giving up.
      src?.[sectionKey] || src?.privacyPolicy || null;

    if (preferTranslated) {
      return pick(data.translated) || pick(data.default);
    }
    return pick(data.default) || pick(data.translated);
  }, [data, sectionKey, currentLanguage]);

  const heading = section?.heading || fallbackHeading;
  const rawContent =
    section?.content ||
    `${fallbackHeading} content is not available at this time. Please contact us for more information.`;

  const { intro, sections } = useMemo(() => parsePolicy(rawContent), [rawContent]);
  const hasSections = sections.length > 0;

  // Scrollspy — highlight the active section in the table of contents.
  useEffect(() => {
    if (!hasSections) return;
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) setActiveId(entry.target.id);
        });
      },
      { rootMargin: "-25% 0px -65% 0px", threshold: 0 },
    );
    sections.forEach((s) => {
      const el = document.getElementById(s.id);
      if (el) observer.observe(el);
    });
    return () => observer.disconnect();
  }, [sections, hasSections]);

  const scrollToTop = () => window.scrollTo({ top: 0, behavior: "smooth" });

  return (
    <main className="w-full">
      {/*==============Hero-banner================*/}
      <section
        className="relative w-full overflow-hidden flex items-center
          min-h-[280px] md:min-h-[330px] lg:min-h-[360px]"
      >
        {/* Background image */}
        <div className="absolute inset-0 z-0">
          <div
            className="block md:hidden w-full h-full bg-cover bg-[position:50%_-36%]"
            style={{ backgroundImage: `url('${withCDN("/About/bg_hero%20screen%20(2).png")}')` }}
          />
          <div
            className="hidden md:block w-full h-full bg-cover bg-[position:50%_0%]"
            style={{ backgroundImage: `url('${withCDN("/About/hero%20section.png")}')` }}
          />
        </div>
        {/* Left-to-right dark overlay for text legibility */}
        <div className="absolute inset-0 z-0 bg-gradient-to-r from-[#00294A]/80 via-[#00294A]/35 to-transparent" />

        <div className="max-w-[1150px] mx-auto w-full relative z-10 flex flex-col justify-center gap-4 px-5 md:px-8 lg:px-6 pt-20 pb-16 md:pt-16 md:pb-20">
          <BackButton />
          <Breadcrumbs currentTitle={heading} />

          <h1 className="heading-hero text-[34px] md:text-[52px] lg:text-[56px] text-white uppercase font-bold leading-[1.05] tracking-wide break-words max-w-[720px]">
            {heading}
          </h1>

          {section?.effectiveDate && (
            <div className="inline-flex items-center gap-2 self-start bg-white/15 backdrop-blur-sm border border-white/25 rounded-full px-4 py-1.5">
              <CalendarDays size={16} className="flex-shrink-0 text-white" />
              <span className="text-[13px] md:text-[15px] font-medium text-white font-[Signika]">
                Effective Date: {section.effectiveDate}
              </span>
            </div>
          )}
        </div>

        {/* Curved white transition into the content */}
        <div className="absolute bottom-0 left-0 w-full z-10 leading-[0] pointer-events-none">
          <svg
            viewBox="0 0 1440 110"
            preserveAspectRatio="none"
            className="w-full h-[55px] md:h-[90px] block"
            aria-hidden="true"
          >
            <path
              fill="#ffffff"
              d="M0,50 C280,120 560,10 820,44 C1080,78 1280,30 1440,52 L1440,110 L0,110 Z"
            />
          </svg>
        </div>
      </section>

      {/*==============Content================*/}
      <section className="relative z-10 -mt-[2px] w-full bg-white pb-16 md:pb-24">
        <div className="max-w-[1150px] mx-auto w-full px-5 md:px-8 lg:px-6">
          <div
            className={
              hasSections
                ? "grid grid-cols-1 lg:grid-cols-[260px_1fr] gap-10 xl:gap-16"
                : "max-w-[820px] mx-auto"
            }
          >
            {/* Table of contents */}
            {hasSections && (
              <aside className="hidden lg:block">
                <div className="sticky top-28">
                  <p className="text-[12px] font-bold uppercase tracking-[0.12em] text-[#0097DC] mb-4">
                    On this page
                  </p>
                  <nav className="flex flex-col gap-1 border-l border-[#E5EEF4]">
                    {sections.map((s) => {
                      const isActive = activeId === s.id;
                      return (
                        <a
                          key={s.id}
                          href={`#${s.id}`}
                          className={`-ml-px border-l-2 pl-4 py-1.5 text-[14px] leading-snug transition-colors ${
                            isActive
                              ? "border-[#0097DC] text-[#0097DC] font-semibold"
                              : "border-transparent text-[#6B7280] hover:text-[#0097DC]"
                          }`}
                        >
                          {s.number}. {s.title}
                        </a>
                      );
                    })}
                  </nav>
                </div>
              </aside>
            )}

            {/* Body */}
            <article className="min-w-0">
              {intro && (
                <div className="mb-10 space-y-4">
                  <Paragraphs
                    text={intro}
                    className="md:text-[18px] text-[#3F3F41] first:mt-0"
                  />
                </div>
              )}

              {hasSections ? (
                <div className="space-y-10">
                  {sections.map((s) => (
                    <section key={s.id} id={s.id} className="scroll-mt-28">
                      <div className="flex items-start gap-3 mb-3">
                        <span className="flex-shrink-0 flex items-center justify-center min-w-8 h-8 px-2 rounded-full bg-[#E8F6FD] text-[#0097DC] font-bold text-[14px] font-[Signika]">
                          {s.number}
                        </span>
                        <h2 className="text-[20px] md:text-[24px] font-bold text-[#1F2937] font-[Signika] leading-snug pt-0.5">
                          {s.title}
                        </h2>
                      </div>
                      <div className="pl-0 md:pl-11 space-y-4">
                        <Paragraphs text={s.body} />
                      </div>
                    </section>
                  ))}
                </div>
              ) : (
                !intro && <Paragraphs text={rawContent} />
              )}

              {/* Back to top */}
              <div className="mt-14 pt-8 border-t border-[#EDF2F6]">
                <button
                  onClick={scrollToTop}
                  className="inline-flex items-center gap-2 text-[14px] font-semibold text-[#0097DC] hover:gap-3 transition-all cursor-pointer"
                >
                  <ArrowUp size={16} />
                  Back to top
                </button>
              </div>
            </article>
          </div>
        </div>
      </section>

      {/* Clip only the footer (its `width: 100vw` is the horizontal-scroll
          source) so no overflow-clipping ancestor sits above the sticky TOC. */}
      <div className="overflow-x-clip">
        <Footer footerData={headerFooterHomeData} />
      </div>
    </main>
  );
}
