"use client";

// src/app/components/ProgramsLazyWrapper.tsx
import { useState, useEffect, useRef } from "react";
import dynamic from "next/dynamic";
import { getProgramsAction } from "@/src/lib/actions/programsAction";
import { ProcessedProgram } from "@/src/lib/types/programs";
import { ProgramsSectionData } from "@/src/lib/types/home";
import ProgramSkeleton from "../ui/skeletons/ProgramSkeleton";
import { scrollToId } from "@/src/lib/utils/scrollToId";
import { useLanguage } from "@/src/lib/context/LanguageContext";
import type { GeneralSettings } from "@/src/lib/types/header";
import { usePrograms } from "@/src/lib/context/ProgramsContext";

const ClientPrograms = dynamic(
  () => import("./Program/Client"),
  {
    ssr: false,
    loading: () => <ProgramSkeleton />,
  },
);

export default function ProgramsLazyWrapper({
  sectionData,
  generalSettings,
  programs, // Optional: if provided, skips self-fetch
  isLoading: externalLoading, // Optional
}: {
  sectionData: ProgramsSectionData;
  generalSettings?: GeneralSettings;
  programs?: ProcessedProgram[] | null;
  isLoading?: boolean;
}) {
  const globalPrograms = usePrograms().programs;
  
  const containerRef = useRef<HTMLDivElement>(null);
  const [internalPrograms, setInternalPrograms] = useState<ProcessedProgram[] | null>(null);
  const [internalLoading, setInternalLoading] = useState(false);
  const [hasLoaded, setHasLoaded] = useState(false);
  
  const { currentLanguage, isInitialized } = useLanguage();
  const prevLanguageRef = useRef<string>(currentLanguage);

  // We prioritize external props if they are provided (Centralized Mode)
  // Otherwise, we fallback directly to the universally fetched globalPrograms
  // Otherwise, we fallback to our own internal state (if needed for translated fetches client side)
  const isSelfContained = programs === undefined;
  const initialPrograms = globalPrograms.length > 0 ? globalPrograms : internalPrograms;
  const programsToRender = isSelfContained ? initialPrograms : programs;
  const programsLoading = isSelfContained ? internalLoading : externalLoading;

  useEffect(() => {
    if (globalPrograms.length > 0 && !hasLoaded) {
      setHasLoaded(true);
      setInternalPrograms(globalPrograms);
    }
  }, [globalPrograms, hasLoaded]);

  /**
   * FALLBACK MODE: Handle language changes
   * Only triggers if no programs are passed as props
   */
  useEffect(() => {
    if (!isSelfContained || !hasLoaded || !isInitialized) return;

    if (prevLanguageRef.current !== currentLanguage) {
      prevLanguageRef.current = currentLanguage;
      fetchProgramsInternal();
    }
  }, [currentLanguage, hasLoaded, isInitialized, isSelfContained]);

  /**
   * FALLBACK MODE: Initial lazy load using Intersection Observer
   * Only triggers if no programs are passed as props and we somehow have no global programs
   */
  useEffect(() => {
    if (!isSelfContained || hasLoaded || internalLoading || !isInitialized || globalPrograms.length > 0) return;

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          fetchProgramsInternal();
          if (containerRef.current) {
            observer.unobserve(containerRef.current);
          }
        }
      },
      { rootMargin: "200px" }
    );

    if (containerRef.current) {
      observer.observe(containerRef.current);
    }

    return () => observer.disconnect();
  }, [hasLoaded, internalLoading, isInitialized, isSelfContained]);

  const fetchProgramsInternal = async () => {
    try {
      setInternalLoading(true);
      
      const params = new URLSearchParams(window.location.search);
      const franchiseeId = params.get("franchiseeId");

      // Resolve language code
      const languageCode = currentLanguage === "translated" && generalSettings?.language_code
        ? generalSettings.language_code
        : (currentLanguage === "default" ? "default" : currentLanguage);

      console.log(`[ProgramsLazyWrapper] Self-contained fetch. Code: ${languageCode}`);
      
      const response = await getProgramsAction(franchiseeId, languageCode);
      
      if (response.success && Array.isArray(response.data)) {
        setInternalPrograms(response.data);
        setHasLoaded(true);
        prevLanguageRef.current = currentLanguage;
      }
    } catch (error) {
      console.error("[ProgramsLazyWrapper] Fallback fetch failed:", error);
    } finally {
      setInternalLoading(false);
    }
  };

  return (
    <div ref={containerRef} style={{ minHeight: "1400px" }}>
      {programsToRender ? (
        <ClientPrograms 
          programs={programsToRender} 
          sectionData={sectionData} 
          onClick={() => {
            scrollToId("program-all");
          }} 
        />
      ) : (
        <ProgramSkeleton />
      )}
    </div>
  );
}
