"use client";
import { useState, useEffect, useRef } from "react";
import { useRouter } from "next/navigation";
import "./page.css";
import "./stepsEventHub.css";
import {
  updateCampaignEventHubFormAlt,
  setCampaignForm,
  resetCampaignForm,
} from "@/app/redux/features/main/campaigns/eventHubAction";
import { fetchCommuneHubs } from "@/app/redux/services/main/campaigns/mycampaign";
import { useAppDispatch, useAppSelector } from "@/app/hooks/useDispatch";
import { useCommuneSearch } from "@/app/hooks/searchEventhub";
import { isValidUrl } from "@/app/utils/datehelpers";
import {
  useCityHubData,
  useSummaryData,
  useCategoryData,
  useSepData,
} from "@/app/hooks/useData";
import Swal from "sweetalert2";
import Cookies from "js-cookie";
import { getUserInfo } from "@/app/utils/token";
import { useCitySearch } from "./useCitySearch";
import ImageCropperEventHub from "./ImageCropperEventHub";
export default function page() {
  const router = useRouter();
  const dispatch = useAppDispatch();
  const [showUrlInput, setShowUrlInput] = useState(false);
  const [showDurationDropdown, setShowDurationDropdown] = useState(false);
  const [durationInputValue, setDurationInputValue] = useState("");
  const [selectedBooster, setSelectedBooster] = useState<string | null>(null);
  const { campaignFormEventHub } = useAppSelector((state) => state.eventhub);
  const [currentPrice, setCurrentPrice] = useState("75,00");
  const [currentDates, setCurrentDates] = useState({ start: "", end: "" });
  const [selectedMedia, setSelectedMedia] = useState<string>("");
  const [mediaType, setMediaType] = useState<
    "image" | "video" | "richtext" | null
  >(null);
  const [mediaFile, setMediaFile] = useState<File | null>(null);
  const { data: cityHubData } = useCityHubData();
  const { data: sepData } = useSepData();
  // const { data: summaryData } = useSummaryData();
  const { data: categoryData } = useCategoryData();
  const [isProcessing, setIsProcessing] = useState(false);
  const [isProcessingCallback, setIsProcessingCallback] = useState(false);
  const [requiredDimensions, setRequiredDimensions] = useState({
    width: 1008,
    height: 840,
  });
  const [isMounted, setIsMounted] = useState(false);

  const [showCropper, setShowCropper] = useState(false);
  const [imageToCrop, setImageToCrop] = useState<string | null>(null);
  const durationDropdownRef = useRef<HTMLDivElement>(null);
  const paymentCallbackProcessed = useRef(false);
  const previewContainerClasses = `
    border border-gray-300 
    rounded-lg p-4 
    bg-white shadow-sm 
    w-full 
    overflow-hidden
    ${selectedBooster === "booster" ? "lg:w-[600px] lg:mx-auto" : ""}
`;
  const {
    searchQuery,
    showDropdown,
    filteredCommunes,
    dropdownRef,
    handleSearchChange,
    handleCommuneSelect,
    handleInputFocus,
    setShowDropdown,
  } = useCommuneSearch();
  const {
    citySearchQuery,
    filteredCities,
    showCityDropdown,
    cityDropdownRef,
    handleCitySearchChange,
    handleCitySelect,
    handleCityInputFocus,
    setShowCityDropdown,
  } = useCitySearch();
  const [activityInputs, setActivityInputs] = useState({
    field1: "",
    field2: "",
    field3: "",
    field4: "",
    field5: "",
  });
  const slot = [
    {
      title: cityHubData?.summary?.format || "Format",
      content:
        campaignFormEventHub.format ||
        cityHubData?.summary?.format_default ||
        "LARGE (250 X 350px)",
    },
    {
      title: cityHubData?.summary?.file_type || "File Type",
      content:
        campaignFormEventHub.media_type ||
        cityHubData?.summary?.file_type_image ||
        "Image",
    },
    {
      title: cityHubData?.summary?.commune || "Commune",
      content: `${
        campaignFormEventHub.commune
          ? `${campaignFormEventHub.commune}, ${campaignFormEventHub.postcode}`
          : ""
      }`,
    },
    {
      title: cityHubData?.summary?.booster || "Booster",
      content: campaignFormEventHub.booster
        ? cityHubData?.summary?.booster_yes || "Yes (+10€)"
        : cityHubData?.summary?.booster_no || "No",
    },
  ];
  const handleBoosterSelect = (boosterType: string) => {
    if (boosterType === "booster") {
      if (selectedBooster === "booster") {
        setSelectedBooster(null);
        dispatch(
          updateCampaignEventHubFormAlt({ key: "booster", value: false })
        );
        dispatch(
          updateCampaignEventHubFormAlt({ key: "booster_price", value: "" })
        );
      } else {
        // Select booster
        setSelectedBooster("booster");
        dispatch(
          updateCampaignEventHubFormAlt({ key: "booster", value: true })
        );
        dispatch(
          updateCampaignEventHubFormAlt({ key: "booster_price", value: "10" })
        );
      }
    } else {
      setSelectedBooster(null);
      dispatch(updateCampaignEventHubFormAlt({ key: "booster", value: false }));
      dispatch(
        updateCampaignEventHubFormAlt({ key: "booster_price", value: "" })
      );
    }
  };
  const calculatePrice = (duration: number) => {
    const basePrice = 75.0;
    const pricePerDay = basePrice / 7;
    let totalPrice = pricePerDay * duration;
    if (campaignFormEventHub.booster) {
      totalPrice += 10;
    }

    const roundedPrice = Math.round(totalPrice * 100) / 100;
    dispatch(
      updateCampaignEventHubFormAlt({ key: "price", value: roundedPrice })
    );
    return totalPrice.toFixed(2).replace(".", ",");
  };
  const getAspectPadding = (boosterType: any) => {
    if (boosterType === "booster") {
      return "31.25%";
    }
    return "83.3333%";
  };
  // Calculate dates based on duration
  const calculateDates = (duration: number) => {
    const now = new Date();

    // Start date is today
    const startDate = new Date(now);

    // End date is start date + duration days
    const endDate = new Date(now);
    endDate.setDate(now.getDate() + duration);

    // Format dates in French style
    const formatDate = (date: Date) => {
      const day = date.getDate();
      const month = date.toLocaleString("fr-FR", { month: "long" });
      const year = date.getFullYear();
      const hours = date.getHours().toString().padStart(2, "0");
      const minutes = date.getMinutes().toString().padStart(2, "0");

      return `${day} ${month} ${year}, ${hours}h${minutes}`;
    };

    // Format dates in ISO format (YYYY-MM-DD) for backend
    const formatDateISO = (date: Date) => {
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, "0");
      const day = date.getDate().toString().padStart(2, "0");
      return `${year}-${month}-${day}`;
    };

    const formattedStart = formatDate(startDate);
    const formattedEnd = formatDate(endDate);

    dispatch(
      updateCampaignEventHubFormAlt({ key: "startDate", value: formattedStart })
    );
    dispatch(
      updateCampaignEventHubFormAlt({ key: "endDate", value: formattedEnd })
    );

    return {
      start: formattedStart,
      end: formattedEnd,
    };
  };
  const showEvenHub = () => {
    handleInputFocus();
    setShowDropdown(!showDropdown);
  };
  const toggleDurationDropdown = () => {
    setShowDurationDropdown(!showDurationDropdown);
  };
  const handleUrlToggle = (hasUrl: boolean) => {
    setShowUrlInput(hasUrl);
    if (!hasUrl) {
      dispatch(
        updateCampaignEventHubFormAlt({ key: "advert_redirect_url", value: "" })
      );
    }
  };

  const getAvailableDurations = () => {
    const today = new Date();
    const december2nd = new Date(today.getFullYear(), 11, 2);

    if (today > december2nd) {
      return [7, 14, 21, 28];
    }

    const timeDiff = december2nd.getTime() - today.getTime();
    const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
    if (daysDiff < 7) {
      return [7];
    } else if (daysDiff >= 7 && daysDiff < 14) {
      return [7, 14];
    } else if (daysDiff >= 14 && daysDiff < 21) {
      return [7, 14, 21];
    } else {
      return [7, 14, 21, 28];
    }
  };
  const handleDurationChange = (duration: number) => {
    const availableDurations = getAvailableDurations();

    // Only proceed if the selected duration is available
    if (availableDurations.includes(duration)) {
      dispatch(
        updateCampaignEventHubFormAlt({ key: "duration", value: duration })
      );
      setDurationInputValue(
        `${duration} ${cityHubData?.steps?.[3]?.days_label || "days"}`
      );
      setShowDurationDropdown(false);
      updatePriceAndDates(duration);
    }
  };

  const handleUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    dispatch(
      updateCampaignEventHubFormAlt({
        key: "advert_redirect_url",
        value: e.target.value,
      })
    );
  };

  const handleMediaUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      const file = files[0];

      // Check if it's an image file
      if (!file.type.startsWith("image/")) {
        alert(
          cityHubData?.steps?.[4]?.upload_error ||
            "Please upload only image files"
        );
        return;
      }

      // Check file size (5MB limit)
      if (file.size > 5 * 1024 * 1024) {
        alert(
          cityHubData?.errors?.file_too_large_image_text ||
            "Image size must be less than 5MB"
        );
        return;
      }

      // Check image dimensions and aspect ratio
      const img = new Image();
      img.onload = () => {
        const width = img.width;
        const height = img.height;
        // setImageDimensions({ width, height });

        // Determine required aspect ratio based on selectedBooster
        const requiredAspectRatio =
          selectedBooster === "booster" ? 16 / 10 : 6 / 5;
        const currentAspectRatio = width / height;

        // Allow small tolerance for aspect ratio comparison
        const aspectRatioTolerance = 0.01;
        const isValidAspectRatio =
          Math.abs(currentAspectRatio - requiredAspectRatio) <
          aspectRatioTolerance;

        if (!isValidAspectRatio) {
          // Auto-show cropper immediately for invalid aspect ratio
          const imageUrl = URL.createObjectURL(file);
          setImageToCrop(imageUrl);
          setShowCropper(true);

          // Set the media but mark as needing crop
          setSelectedMedia(imageUrl);
          setMediaFile(file);

          return; // Stop normal upload flow
        }

        // If aspect ratio is valid, continue with normal upload
        const imageUrl = URL.createObjectURL(file);
        setSelectedMedia(imageUrl);
        setMediaFile(file);
        // Set image in Redux to trigger display condition
        dispatch(
          updateCampaignEventHubFormAlt({ key: "image", value: file.name })
        );
      };

      img.onerror = () => {
        alert(
          cityHubData?.errors?.invalid_image ||
            "Invalid image file. Please try another image."
        );
      };

      img.src = URL.createObjectURL(file);
    }
  };
  const handleUrlCancel = () => {
    dispatch(
      updateCampaignEventHubFormAlt({ key: "advert_redirect_url", value: "" })
    );
  };

  const handleMediaClear = () => {
    // Revoke the object URL to avoid memory leaks
    if (
      campaignFormEventHub.image &&
      campaignFormEventHub.image.startsWith("blob:")
    ) {
      URL.revokeObjectURL(campaignFormEventHub.image);
    }
    dispatch(updateCampaignEventHubFormAlt({ key: "image", value: "" }));
  };
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (
        durationDropdownRef.current &&
        !durationDropdownRef.current.contains(event.target as Node)
      ) {
        setShowDurationDropdown(false);
      }
    };

    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, []);
  useEffect(() => {
    dispatch(fetchCommuneHubs() as any);
    // Mark component as mounted (client-side only)
    setIsMounted(true);

    // Check if we're returning from payment (cancellation or success)
    const urlParams = new URLSearchParams(window.location.search);
    const paymentCancelled = urlParams.get("payment_cancelled");
    const paymentSuccess = urlParams.get("payment_success");

    // If NOT returning from payment (neither cancelled nor success), clear any saved data
    // This handles page refresh or direct navigation to the page
    if (!paymentCancelled && !paymentSuccess && typeof window !== "undefined") {
      localStorage.removeItem("pending_cityhub_campaign_data");
      try {
        deleteFileFromIndexedDB("pending_cityhub_media_file");
      } catch (error) {
        // Ignore errors when clearing
      }
      // Reset Redux state and local state
      dispatch(resetCampaignForm());
      setSelectedBooster(null);
      setDurationInputValue("");
      setShowUrlInput(false);
      setSelectedMedia("");
      setMediaFile(null);
      setMediaType(null);
      setActivityInputs({
        field1: "",
        field2: "",
        field3: "",
        field4: "",
        field5: "",
      });
      setCurrentPrice("75,00");
      setCurrentDates({ start: "", end: "" });
    }
  }, [dispatch]);

  // Cleanup: Clear saved data when component unmounts (user navigates away)
  useEffect(() => {
    return () => {
      // Clear saved data when navigating away (unless we're processing payment callback)
      if (typeof window !== "undefined") {
        const urlParams = new URLSearchParams(window.location.search);
        const paymentCancelled = urlParams.get("payment_cancelled");
        const paymentSuccess = urlParams.get("payment_success");

        // Only clear if we're not in a payment flow (cancelled or success)
        // This prevents clearing data when user is returning from checkout
        if (!paymentCancelled && !paymentSuccess) {
          localStorage.removeItem("pending_cityhub_campaign_data");
          try {
            deleteFileFromIndexedDB("pending_cityhub_media_file");
          } catch (error) {
            // Ignore errors when clearing
          }
          // Reset Redux state and local state
          dispatch(resetCampaignForm());
        }
      }
    };
  }, []);

  // Handle payment callback after Stripe redirect
  useEffect(() => {
    // Only run on client side after component is mounted
    if (typeof window === "undefined" || !isMounted) {
      return;
    }

    const handlePaymentCallback = async () => {
      // Prevent duplicate execution
      if (paymentCallbackProcessed.current) {
        return;
      }
      const user_id = Cookies.get("user_id");

      const urlParams = new URLSearchParams(window.location.search);
      const paymentSuccess = urlParams.get("payment_success");
      const paymentCancelled = urlParams.get("payment_cancelled");
      const sessionId = urlParams.get("session_id");

      // If no payment-related params, exit early
      if (!paymentSuccess && !paymentCancelled) {
        return;
      }

      // Mark as processed immediately to prevent duplicate calls
      paymentCallbackProcessed.current = true;

      // Clean up URL params immediately to prevent re-execution
      window.history.replaceState({}, document.title, window.location.pathname);

      // Handle payment cancellation
      if (paymentCancelled === "true") {
        // Wait a bit to ensure hydration is complete before restoring
        setTimeout(async () => {
          // Restore form data so user can continue from where they left off
          await restoreFormData();
        }, 100);

        Swal.fire({
          icon: "info",
          title:
            cityHubData?.errors?.payment_cancelled_title || "Payment Cancelled",
          text:
            cityHubData?.errors?.payment_cancelled_text ||
            "Your payment was cancelled. You can try again when ready.",
          confirmButtonText: cityHubData?.processing?.ok || "OK",
        });
        return;
      }

      // Handle payment success
      if (paymentSuccess === "true" && sessionId) {
        setIsProcessing(true);
        setIsProcessingCallback(true);

        try {
          // Get user token
          const token = Cookies.get("token");
          if (!token) {
            throw new Error("User not authenticated");
          }

          // Restore campaign data from localStorage
          const savedDataStr = localStorage.getItem(
            "pending_cityhub_campaign_data"
          );
          if (!savedDataStr) {
            throw new Error(
              "Campaign data not found. Please try creating the campaign again."
            );
          }

          const savedData = JSON.parse(savedDataStr);

          // Restore media file from IndexedDB or base64
          let restoredMediaFile: File | undefined;

          if (savedData.useIndexedDB) {
            // Retrieve large files from IndexedDB
            try {
              const fileFromDB = await getFileFromIndexedDB(
                "pending_cityhub_media_file"
              );
              if (fileFromDB) {
                restoredMediaFile = fileFromDB;
                console.log("Restored file from IndexedDB:", fileFromDB.name);
              } else {
                throw new Error("Media file not found in IndexedDB");
              }
            } catch (error) {
              console.error(
                "Error restoring media file from IndexedDB:",
                error
              );
              throw new Error("Failed to restore media file from storage");
            }
          } else if (
            savedData.mediaFileBase64 &&
            savedData.mediaFileName &&
            savedData.mediaFileType
          ) {
            // Retrieve small images from base64 in localStorage
            try {
              restoredMediaFile = await base64ToFile(
                savedData.mediaFileBase64,
                savedData.mediaFileName,
                savedData.mediaFileType
              );
            } catch (error) {
              console.error("Error restoring media file from base64:", error);
              throw new Error("Failed to restore media file");
            }
          }

          if (!restoredMediaFile) {
            throw new Error("Media file is required");
          }

          // Retrieve session details from Stripe to get discount information
          const sessionDetailsResponse = await fetch(
            `/api/payment/session-details?session_id=${sessionId}`
          );
          if (!sessionDetailsResponse.ok) {
            throw new Error("Failed to retrieve payment details");
          }

          const sessionDetails = await sessionDetailsResponse.json();
          const walletDiscount =
            sessionDetails.walletDiscount || savedData.discountApplied || 0;
          const stripeDiscount = sessionDetails.stripeDiscount || 0;
          const totalDiscount = walletDiscount + stripeDiscount;
          const originalAmount =
            sessionDetails.amount || savedData.originalAmount;
          const finalAmount =
            sessionDetails.finalAmount || savedData.finalAmount;
          const couponCode = sessionDetails.couponCode || null;

          // Calculate dates from duration (more reliable than parsing French format)
          const duration = savedData.campaignFormEventHub.duration || 7;
          const startDate = new Date();
          const endDate = new Date();
          endDate.setDate(startDate.getDate() + duration);

          // Format as ISO dates (YYYY-MM-DD)
          const formatDateISO = (date: Date) => {
            const year = date.getFullYear();
            const month = (date.getMonth() + 1).toString().padStart(2, "0");
            const day = date.getDate().toString().padStart(2, "0");
            return `${year}-${month}-${day}`;
          };

          const startDateISO = formatDateISO(startDate);
          const endDateISO = formatDateISO(endDate);

          // Format activity date
          let activityDateISO = "";
          if (savedData.campaignFormEventHub.activity_dates) {
            try {
              const activityDate = new Date(
                savedData.campaignFormEventHub.activity_dates
              );
              activityDateISO = formatDateISO(activityDate);
            } catch (error) {
              console.error("Error parsing activity date:", error);
              activityDateISO = formatDateISO(new Date());
            }
          } else {
            activityDateISO = formatDateISO(new Date());
          }

          // Prepare campaign data
          const campaignData = {
            user_id: user_id,
            city_hub_page_id: parseInt(
              savedData.campaignFormEventHub.page_id || 0
            ),
            duration: savedData.campaignFormEventHub.duration || 7,
            start_date: startDateISO,
            end_date: endDateISO,
            redirect_url:
              savedData.campaignFormEventHub.advert_redirect_url || "",
            supercharge_advert: savedData.campaignFormEventHub.booster || false,
            user_notes: savedData.campaignFormEventHub.user_notes || "",
            activity_title: savedData.campaignFormEventHub.activity_title || "",
            activity_commune:
              savedData.campaignFormEventHub.activity_commune || "",
            activity_dates: activityDateISO,
            activity_prices:
              savedData.campaignFormEventHub.activity_prices || "",
            activity_description:
              savedData.campaignFormEventHub.activity_description || "",
            stripe_session_id: sessionId,
            payment_amount: originalAmount,
            final_amount: finalAmount,
            discount_amount: totalDiscount,
            wallet_discount: walletDiscount,
            coupon_code: couponCode,
          };

          console.log({ campaignData });

          console.log({ campaignData, restoredMediaFile, token });

          // Send to Nest.js backend
          const result = await sendCityHubCampaignToBackend(
            campaignData,
            restoredMediaFile,
            token
          );

          if (result.success) {
            // Clean up saved data only on success
            localStorage.removeItem("pending_cityhub_campaign_data");

            // Clean up IndexedDB media file
            try {
              await deleteFileFromIndexedDB("pending_cityhub_media_file");
              console.log("Successfully deleted media file from IndexedDB");
            } catch (error) {
              console.error("Error deleting media file from IndexedDB:", error);
              // Try to verify if file still exists
              try {
                const fileExists = await getFileFromIndexedDB(
                  "pending_cityhub_media_file"
                );
                if (fileExists) {
                  console.warn(
                    "Media file still exists in IndexedDB after deletion attempt"
                  );
                  // Retry deletion
                  await deleteFileFromIndexedDB("pending_cityhub_media_file");
                  console.log(
                    "Retry: Successfully deleted media file from IndexedDB"
                  );
                }
              } catch (verifyError) {
                console.error(
                  "Error verifying IndexedDB file deletion:",
                  verifyError
                );
              }
            }

            Swal.fire({
              icon: "success",
              title:
                cityHubData?.errors?.payment_successful_title ||
                "Payment Successful!",
              text:
                cityHubData?.errors?.payment_successful_text ||
                "Your CityHub campaign has been created successfully",
              confirmButtonText: cityHubData?.processing?.ok || "OK",
            }).then(() => {
              router.push("/campaigns/eventhubCampaigns");
            });
          } else {
            // Payment succeeded but campaign creation failed
            // Don't clean up data - user might need to retry
            Swal.fire({
              icon: "warning",
              title:
                cityHubData?.errors?.payment_success_creation_failed_title ||
                "Payment Successful",
              text: `${
                cityHubData?.errors
                  ?.payment_success_creation_failed_text_prefix ||
                "Payment was successful but campaign creation failed: "
              }${result.error}${
                cityHubData?.errors
                  ?.payment_success_creation_failed_text_suffix ||
                ". Please contact support."
              }`,
              confirmButtonText: cityHubData?.processing?.ok || "OK",
            });
          }
        } catch (error: any) {
          console.error("Error creating cityhub campaign:", error);
          // Don't clean up data on error - user might need to retry
          Swal.fire({
            icon: "error",
            title:
              cityHubData?.errors?.campaign_creation_failed_title ||
              "Campaign Creation Failed",
            text:
              error.message ||
              cityHubData?.errors?.campaign_creation_failed_text ||
              "An error occurred while creating your campaign",
            confirmButtonText: cityHubData?.processing?.ok || "OK",
          });
        } finally {
          setIsProcessing(false);
          setIsProcessingCallback(false);
        }
      }
    };

    handlePaymentCallback();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isMounted]);

  // Helper function to convert File to base64
  const fileToBase64 = (file: File): Promise<string> => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = (error) => reject(error);
    });
  };

  // IndexedDB helper functions for large files
  const openDB = (): Promise<IDBDatabase> => {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open("CampaignMediaDB", 1);

      request.onerror = () => reject(request.error);
      request.onsuccess = () => resolve(request.result);
      request.onupgradeneeded = (event) => {
        const db = (event.target as IDBOpenDBRequest).result;
        if (!db.objectStoreNames.contains("media")) {
          db.createObjectStore("media");
        }
      };
    });
  };

  const saveFileToIndexedDB = async (
    key: string,
    file: File
  ): Promise<void> => {
    const db = await openDB();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(["media"], "readwrite");
      const store = transaction.objectStore("media");
      const request = store.put(file, key);

      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  };

  const getFileFromIndexedDB = async (key: string): Promise<File | null> => {
    const db = await openDB();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(["media"], "readonly");
      const store = transaction.objectStore("media");
      const request = store.get(key);

      request.onsuccess = () => resolve(request.result || null);
      request.onerror = () => reject(request.error);
    });
  };

  // Helper function to convert base64 back to File
  const base64ToFile = async (
    base64String: string,
    fileName: string,
    mimeType: string
  ): Promise<File> => {
    const response = await fetch(base64String);
    const blob = await response.blob();
    return new File([blob], fileName, { type: mimeType });
  };

  const deleteFileFromIndexedDB = async (key: string): Promise<void> => {
    const db = await openDB();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(["media"], "readwrite");
      const store = transaction.objectStore("media");
      const request = store.delete(key);

      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  };

  // Function to restore form data from localStorage
  const restoreFormData = async () => {
    // Only restore on client side after mount
    if (typeof window === "undefined" || !isMounted) {
      return;
    }

    try {
      const savedDataStr = localStorage.getItem(
        "pending_cityhub_campaign_data"
      );
      if (!savedDataStr) {
        console.log("No saved campaign data found");
        return;
      }

      const savedData = JSON.parse(savedDataStr);

      // Restore campaignFormEventHub to Redux
      if (savedData.campaignFormEventHub) {
        dispatch(setCampaignForm(savedData.campaignFormEventHub));

        // Restore local state from campaignFormEventHub
        if (savedData.campaignFormEventHub.booster !== undefined) {
          setSelectedBooster(
            savedData.campaignFormEventHub.booster ? "booster" : null
          );
        }
        if (savedData.campaignFormEventHub.duration) {
          setDurationInputValue(
            `${savedData.campaignFormEventHub.duration} ${
              cityHubData?.steps?.[3]?.days_label || "days"
            }`
          );
          updatePriceAndDates(savedData.campaignFormEventHub.duration);
        }
        if (savedData.campaignFormEventHub.advert_redirect_url) {
          setShowUrlInput(true);
        }
        // Restore commune search query
        if (
          savedData.campaignFormEventHub.commune &&
          savedData.campaignFormEventHub.postcode
        ) {
          // Set the search query using handleSearchChange with a synthetic event
          const communeDisplay = `${savedData.campaignFormEventHub.commune}, ${savedData.campaignFormEventHub.postcode}`;
          const syntheticEvent = {
            target: { value: communeDisplay },
          } as React.ChangeEvent<HTMLInputElement>;
          handleSearchChange(syntheticEvent);
        }
        // Restore activity inputs
        if (savedData.campaignFormEventHub.activity_title) {
          setActivityInputs((prev) => ({
            ...prev,
            field1: savedData.campaignFormEventHub.activity_title || "",
          }));
        }
        if (savedData.campaignFormEventHub.activity_commune) {
          setActivityInputs((prev) => ({
            ...prev,
            field2: savedData.campaignFormEventHub.activity_commune || "",
          }));
          // Restore city search query using handleCitySearchChange
          // Use setTimeout to ensure it happens after Redux state is updated
          setTimeout(() => {
            const citySyntheticEvent = {
              target: {
                value: savedData.campaignFormEventHub.activity_commune,
              },
            } as React.ChangeEvent<HTMLInputElement>;
            handleCitySearchChange(citySyntheticEvent);
          }, 50);
        }
        if (savedData.campaignFormEventHub.activity_dates) {
          setActivityInputs((prev) => ({
            ...prev,
            field3: savedData.campaignFormEventHub.activity_dates || "",
          }));
        }
        if (savedData.campaignFormEventHub.activity_prices) {
          setActivityInputs((prev) => ({
            ...prev,
            field4: savedData.campaignFormEventHub.activity_prices || "",
          }));
        }
        if (savedData.campaignFormEventHub.activity_description) {
          setActivityInputs((prev) => ({
            ...prev,
            field5: savedData.campaignFormEventHub.activity_description || "",
          }));
        }
      }

      // Restore media file (similar to SEP campaigns approach)
      if (savedData.useIndexedDB) {
        // Retrieve large files from IndexedDB
        try {
          const fileFromDB = await getFileFromIndexedDB(
            "pending_cityhub_media_file"
          );
          if (fileFromDB) {
            setMediaFile(fileFromDB);
            setMediaType("image");
            const mediaUrl = URL.createObjectURL(fileFromDB);
            setSelectedMedia(mediaUrl);
            // Set image in Redux to trigger display condition
            dispatch(
              updateCampaignEventHubFormAlt({
                key: "image",
                value: fileFromDB.name || "restored-image",
              })
            );
          }
        } catch (error) {
          console.error("Error restoring media file from IndexedDB:", error);
        }
      } else if (
        savedData.mediaFileBase64 &&
        savedData.mediaFileName &&
        savedData.mediaFileType
      ) {
        // Retrieve small images from base64 in localStorage
        try {
          const restoredFile = await base64ToFile(
            savedData.mediaFileBase64,
            savedData.mediaFileName,
            savedData.mediaFileType
          );
          setMediaFile(restoredFile);
          setMediaType("image");
          const mediaUrl = URL.createObjectURL(restoredFile);
          setSelectedMedia(mediaUrl);
          // Set image in Redux to trigger display condition
          dispatch(
            updateCampaignEventHubFormAlt({
              key: "image",
              value: restoredFile.name || "restored-image",
            })
          );
        } catch (error) {
          console.error("Error restoring media file from base64:", error);
        }
      }

      console.log("Form data restored successfully");
    } catch (error) {
      console.error("Error restoring form data:", error);
    }
  };

  // Function to send cityhub campaign to backend
  const sendCityHubCampaignToBackend = async (
    campaignData: {
      city_hub_page_id: number;
      duration: number;
      start_date: string;
      end_date: string;
      redirect_url?: string;
      supercharge_advert?: boolean;
      user_notes?: string;
      activity_title?: string;
      activity_commune?: string;
      activity_dates?: string;
      activity_prices?: string;
      activity_description?: string;
      stripe_session_id: string;
      payment_amount: number;
      final_amount?: number;
      discount_amount?: number;
      wallet_discount?: number;
      coupon_code?: string;
    },
    mediaFile: File,
    token: string
  ): Promise<{ success: boolean; data?: any; error?: string }> => {
    try {
      const formData = new FormData();

      // Add campaign fields
      formData.append(
        "city_hub_page_id",
        campaignData.city_hub_page_id.toString()
      );
      formData.append("duration", campaignData.duration.toString());
      formData.append("start_date", campaignData.start_date);
      formData.append("end_date", campaignData.end_date);

      if (campaignData.redirect_url) {
        formData.append("redirect_url", campaignData.redirect_url);
      }

      if (campaignData.supercharge_advert !== undefined) {
        formData.append(
          "supercharge_advert",
          campaignData.supercharge_advert.toString()
        );
      }

      if (campaignData.user_notes) {
        formData.append("user_notes", campaignData.user_notes);
      }

      // Add activity fields
      if (campaignData.activity_title) {
        formData.append("activity_title", campaignData.activity_title);
      }
      if (campaignData.activity_commune) {
        formData.append("activity_commune", campaignData.activity_commune);
      }
      if (campaignData.activity_dates) {
        formData.append("activity_dates", campaignData.activity_dates);
      }
      if (campaignData.activity_prices) {
        formData.append("activity_prices", campaignData.activity_prices);
      }
      if (campaignData.activity_description) {
        formData.append(
          "activity_description",
          campaignData.activity_description
        );
      }

      // Add Stripe session ID
      formData.append("stripe_session_id", campaignData.stripe_session_id);

      // Add payment amounts
      formData.append("payment_amount", campaignData.payment_amount.toString());

      if (campaignData.final_amount !== undefined) {
        formData.append("final_amount", campaignData.final_amount.toString());
      }

      if (campaignData.discount_amount !== undefined) {
        formData.append(
          "discount_amount",
          campaignData.discount_amount.toString()
        );
      }

      if (campaignData.wallet_discount !== undefined) {
        formData.append(
          "wallet_discount",
          campaignData.wallet_discount.toString()
        );
      }

      if (campaignData.coupon_code) {
        formData.append("coupon_code", campaignData.coupon_code);
      }

      // Add media file
      formData.append("media", mediaFile);

      const apiUrl = process.env.NEXT_PUBLIC_API_URL_New;

      const response = await fetch(`${apiUrl}/cityhub-campaigns/create`, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${token}`,
        },
        body: formData,
      });

      if (!response.ok) {
        const errorData = await response
          .json()
          .catch(() => ({ message: "Unknown error" }));

        // Handle validation errors from backend
        if (errorData.errors && typeof errorData.errors === "object") {
          const errorMessages = Object.values(errorData.errors).join(", ");
          throw new Error(
            errorMessages ||
              errorData.message ||
              `HTTP error! status: ${response.status}`
          );
        }

        throw new Error(
          errorData.message || `HTTP error! status: ${response.status}`
        );
      }

      const data = await response.json();

      // Check if backend returned an error response even with 200 status
      if (data.status && data.status !== 201 && data.status !== 200) {
        throw new Error(data.message || "Failed to create campaign");
      }

      return { success: true, data };
    } catch (error: any) {
      console.error("Error sending cityhub campaign to backend:", error);
      return {
        success: false,
        error: error.message || "Failed to create campaign",
      };
    }
  };

  const updatePriceAndDates = (duration: number) => {
    const price = calculatePrice(duration);
    const dates = calculateDates(duration);
    const priceNumber = parseFloat(price.replace(",", "."));

    dispatch(
      updateCampaignEventHubFormAlt({ key: "price", value: priceNumber })
    );
    dispatch(
      updateCampaignEventHubFormAlt({ key: "startDate", value: dates.start })
    );
    dispatch(
      updateCampaignEventHubFormAlt({ key: "endDate", value: dates.end })
    );

    setCurrentPrice(price);
    setCurrentDates(dates);
  };

  // Add this function inside your component
  const formatActivityDate = (dateString: string) => {
    if (!dateString) return "";

    const date = new Date(dateString);
    const day = date.getDate();
    const month = date.toLocaleString("fr-FR", { month: "long" });
    const year = date.getFullYear();
    const hours = date.getHours().toString().padStart(2, "0");
    const minutes = date.getMinutes().toString().padStart(2, "0");

    return `${day} ${month} ${year}, ${hours}h${minutes}`;
  };

  const handleActivityInputChange = (index: number, value: string) => {
    const fieldKey = `field${index + 1}` as keyof typeof activityInputs;
    setActivityInputs((prev) => ({
      ...prev,
      [fieldKey]: value,
    }));
  };
  useEffect(() => {
    const currentDuration = campaignFormEventHub.duration || 7;
    updatePriceAndDates(currentDuration);
  }, [campaignFormEventHub.booster]);
  const currentDuration = campaignFormEventHub.duration || 7;
  const onPayment = async () => {
    // Prevent multiple clicks while processing
    if (isProcessing) return;

    console.log(campaignFormEventHub, "campaignFormEventHub++");

    // Validation checks
    if (!campaignFormEventHub.commune) {
      Swal.fire({
        icon: "error",
        title: cityHubData?.errors?.missing_commune_title || "Missing Commune",
        text:
          cityHubData?.errors?.missing_commune_text ||
          "Please select a commune from the City Hub Pages",
        confirmButtonText: cityHubData?.processing?.ok || "OK",
      });
      return;
    }

    if (!campaignFormEventHub.duration) {
      Swal.fire({
        icon: "error",
        title:
          cityHubData?.errors?.missing_duration_title || "Missing Duration",
        text:
          cityHubData?.errors?.missing_duration_text ||
          "Please select an advert duration (7, 14, 21, or 28 days)",
        confirmButtonText: cityHubData?.processing?.ok || "OK",
      });
      return;
    }

    if (!campaignFormEventHub.image) {
      Swal.fire({
        icon: "error",
        title: cityHubData?.errors?.missing_media_title || "Missing Media",
        text:
          cityHubData?.errors?.missing_media_text ||
          "Please upload an image for your advert",
        confirmButtonText: cityHubData?.processing?.ok || "OK",
      });
      return;
    }

    if (showUrlInput) {
      if (!campaignFormEventHub.advert_redirect_url) {
        Swal.fire({
          icon: "warning",
          title:
            cityHubData?.errors?.missing_url_title || "Missing Redirect URL",
          text:
            cityHubData?.errors?.missing_url_text ||
            "Please provide an advert redirect URL",
          confirmButtonText: cityHubData?.processing?.ok || "OK",
        });
        return;
      }

      if (!isValidUrl(campaignFormEventHub.advert_redirect_url)) {
        Swal.fire({
          icon: "error",
          title: cityHubData?.errors?.invalid_url_title || "Invalid URL",
          text:
            cityHubData?.errors?.invalid_url_text ||
            "Please provide a valid URL (e.g., https://example.com)",
          confirmButtonText: cityHubData?.processing?.ok || "OK",
        });
        return;
      }
    }

    // Set processing state to true
    setIsProcessing(true);

    try {
      // Get user token and info
      const token = Cookies.get("token");
      const user_id = Cookies.get("user_id");
      const userinfo = getUserInfo();
      const customerEmail = userinfo?.email;

      if (!token) {
        throw new Error("User not authenticated");
      }

      console.log("campaignFormEventHub : ", campaignFormEventHub);

      // Calculate total price
      const totalPrice = campaignFormEventHub.price || 0;
      if (totalPrice <= 0) {
        throw new Error("Invalid total price");
      }

      console.log(
        " campaignFormEventHub.page_id : ",
        campaignFormEventHub.page_id
      );

      // Create checkout session
      const response = await fetch("/api/payment/create-intent-cityhub", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          stripe_customer_id: Cookies.get("stripe_customer_id"),
          amount: totalPrice,
          currency: "eur",
          metadata: {
            user_id: localStorage.getItem("user_id") || user_id || "",
            city_hub_page_id: campaignFormEventHub.page_id?.toString() || "",
            duration: campaignFormEventHub.duration?.toString() || "",
          },
          successUrl: `${window.location.origin}/campaigns/createHubPageAdvert?payment_success=true&session_id={CHECKOUT_SESSION_ID}`,
          cancelUrl: `${window.location.origin}/campaigns/createHubPageAdvert?payment_cancelled=true`,
          token,
          user_id,
          customerEmail,
          duration: campaignFormEventHub.duration,
          communeName: campaignFormEventHub.commune,
        }),
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || "Failed to create checkout session");
      }

      const responseData = await response.json();
      const {
        url,
        discountApplied,
        originalAmount,
        finalAmount,
        walletBalance,
      } = responseData;

      if (url) {
        // Save campaign data before redirecting
        try {
          let mediaFileBase64 = "";
          let mediaFileName = "";
          let mediaFileType = "";
          let useIndexedDB = false;

          // Use mediaFile state if available (more reliable than campaignFormEventHub.image)
          if (mediaFile) {
            mediaFileName = mediaFile.name;
            mediaFileType = mediaFile.type;

            // Use IndexedDB for large files, localStorage for images
            const isLargeFile = mediaFile.size > 4 * 1024 * 1024; // > 4MB

            if (isLargeFile) {
              // Save large files to IndexedDB
              await saveFileToIndexedDB(
                "pending_cityhub_media_file",
                mediaFile
              );
              useIndexedDB = true;
              console.log("Saved large file to IndexedDB:", mediaFileName);
            } else {
              // Keep small images in localStorage as base64
              mediaFileBase64 = await fileToBase64(mediaFile);
            }
          } else if (campaignFormEventHub.image && selectedMedia) {
            // Fallback: Convert image URL to File if it's a blob URL
            if (selectedMedia.startsWith("blob:")) {
              try {
                const response = await fetch(selectedMedia);
                const blob = await response.blob();
                const file = new File(
                  [blob],
                  `cityhub-advert-${Date.now()}.${
                    blob.type.split("/")[1] || "png"
                  }`,
                  { type: blob.type }
                );

                mediaFileName = file.name;
                mediaFileType = file.type;

                // Use IndexedDB for large files, localStorage for images
                const isLargeFile = file.size > 4 * 1024 * 1024; // > 4MB

                if (isLargeFile) {
                  // Save large files to IndexedDB
                  await saveFileToIndexedDB("pending_cityhub_media_file", file);
                  useIndexedDB = true;
                  console.log("Saved large file to IndexedDB:", mediaFileName);
                } else {
                  // Keep small images in localStorage as base64
                  mediaFileBase64 = await fileToBase64(file);
                }
              } catch (error) {
                console.error("Error processing image:", error);
                // Fallback: save the image URL as is
                mediaFileBase64 = selectedMedia;
              }
            }
          }
          console.log("campaignDataToSave", {
            campaignFormEventHub,
            mediaFileBase64: useIndexedDB ? "" : mediaFileBase64,
            mediaFileName,
            mediaFileType,
            useIndexedDB, // Flag to indicate where media is stored
            // Save discount information
            discountApplied: discountApplied || 0,
            originalAmount: originalAmount || totalPrice,
            finalAmount: finalAmount || totalPrice,
            walletBalance: walletBalance || 0,
          });
          const campaignDataToSave = {
            campaignFormEventHub,
            mediaFileBase64: useIndexedDB ? "" : mediaFileBase64,
            mediaFileName,
            mediaFileType,
            useIndexedDB, // Flag to indicate where media is stored
            // Save discount information
            discountApplied: discountApplied || 0,
            originalAmount: originalAmount || totalPrice,
            finalAmount: finalAmount || totalPrice,
            walletBalance: walletBalance || 0,
          };
          console.log("campaignDataToSave", campaignDataToSave);

          localStorage.setItem(
            "pending_cityhub_campaign_data",
            JSON.stringify(campaignDataToSave)
          );
        } catch (error) {
          console.error("Error saving campaign data:", error);
          if (
            error instanceof DOMException &&
            error.name === "QuotaExceededError"
          ) {
            throw new Error(
              "File is too large to store. Please use a smaller file or contact support."
            );
          }
          throw new Error("Failed to save campaign data before payment");
        }

        // Redirect to Stripe Checkout
        window.location.href = url;
      } else {
        throw new Error("Failed to get checkout URL");
      }
    } catch (error: any) {
      console.error("Payment error:", error);
      Swal.fire({
        icon: "error",
        title: cityHubData?.errors?.payment_failed_title || "Payment Failed",
        text:
          error.message ||
          cityHubData?.errors?.payment_failed_text ||
          "An error occurred during payment",
        confirmButtonText: cityHubData?.processing?.ok || "OK",
      });
      setIsProcessing(false);
    }
  };
  const handleCropComplete = (croppedImage: string) => {
    if (!croppedImage) {
      Swal.fire({
        icon: "error",
        title: cityHubData?.errors?.crop_failed_title || "Échec du recadrage.",
        text:
          cityHubData?.errors?.crop_failed_text ||
          "Le recadrage de l'image a échoué. Veuillez réessayer.",
        confirmButtonText: cityHubData?.processing?.ok || "OK",
      });
      return;
    }

    // Convert base64 to blob and create file
    fetch(croppedImage)
      .then((res) => {
        if (!res.ok)
          throw new Error(
            cityHubData?.errors?.failed_fetch_cropped_image ||
              "Échec de la récupération de l'image recadrée."
          );
        return res.blob();
      })
      .then((blob) => {
        const file = new File(
          [blob],
          mediaFile?.name || `cropped-${Date.now()}.jpg`,
          {
            type: "image/jpeg",
          }
        );

        // Create object URL for the cropped image
        const croppedImageUrl = URL.createObjectURL(blob);
        dispatch(
          updateCampaignEventHubFormAlt({
            key: "image",
            value: file.name,
          })
        );
        // Update states with cropped image
        setSelectedMedia(croppedImageUrl);
        setMediaFile(file);
        // setImageDimensions({
        //   width: requiredDimensions.width,
        //   height: requiredDimensions.height,
        // });
        // setIsValidDimension(true);

        Swal.fire({
          icon: "success",
          title:
            cityHubData?.errors?.crop_success_title ||
            "Image recadrée avec succès !",
          text: `${
            cityHubData?.errors?.crop_success_text_prefix ||
            "L'image a été recadrée à "
          }${requiredDimensions.width}x${requiredDimensions.height}${
            cityHubData?.errors?.crop_success_text_suffix || "px"
          }`,
          confirmButtonText: cityHubData?.processing?.ok || "OK",
        });
      })
      .catch((error) => {
        console.error("Error processing cropped image:", error);
        Swal.fire({
          icon: "error",
          title:
            cityHubData?.errors?.crop_processing_failed_title ||
            "Échec du recadrage",
          text:
            cityHubData?.errors?.crop_processing_failed_text ||
            "Le traitement de l'image recadrée a échoué. Veuillez réessayer.",
          confirmButtonText: cityHubData?.processing?.ok || "OK",
        });
      })
      .finally(() => {
        setShowCropper(false);
        setImageToCrop(null);
      });
  };
  const handleRemoveMedia = () => {
    if (selectedMedia) {
      URL.revokeObjectURL(selectedMedia); // Clean up the object URL
    }
    setSelectedMedia("");
    setMediaType(null);
    setMediaFile(null);
    dispatch(
      updateCampaignEventHubFormAlt({
        key: "image",
        value: "",
      })
    );
    // Clear the file input
    const fileInput = document.getElementById(
      "media-upload"
    ) as HTMLInputElement;
    if (fileInput) {
      fileInput.value = "";
    }
  };

  return (
    <>
      {/* Loading Overlay for Payment Processing - Only show during callback processing */}
      {isProcessingCallback && (
        <div className="fixed inset-0 backdrop-blur-md flex items-center justify-center z-[9999]">
          <div className="w-16 h-16 border-4 border-gray-300 border-t-blue-600 rounded-full animate-spin"></div>
        </div>
      )}
      <div className="page-width">
        <div className="steps-cols">
          <div>
            <div
              style={{
                display: "flex",
                alignItems: "center",
                gap: "1rem",
                marginTop: "1rem",
              }}
            >
              <img
                style={{ width: "48px" }}
                src="/cart.png"
                className=""
                alt=""
              />
              <h1 className="primary-heading">{cityHubData?.portal?.title}</h1>
            </div>
            <h2
              style={{ marginLeft: "4rem" }}
              className="secondary-heading event-h"
            >
              {cityHubData?.portal?.section}
            </h2>
            <p
              style={{ fontSize: "1.33rem", marginLeft: "4rem" }}
              className="primary-para event-p"
            >
              {cityHubData?.portal?.description}
            </p>
            <div className="stepper-container-eventHub-design">
              {/* steps */}
              <div>
                {/* step 1 */}

                <div className="mix-right-left-content">
                  {/* Step 1 */}
                  <div className="step-container-eventhub">
                    <div className="step penta-heading">1</div>
                    <div className="line green-line"></div>
                  </div>
                  <div className="w-full">
                    <h2 className="tertiary-heading">
                      {cityHubData?.steps?.[0]?.title}
                    </h2>
                    <p className="primary-para">
                      {cityHubData?.steps?.[0]?.subtitle}
                    </p>
                    <div className="border border-[#c4c4c4] rounded-lg my-5 small-border">
                      <div className=" flex items-center gap-5 py-5 flex-wrap lg:flex-nowrap justify-center ">
                        <div className="border border-[#1b2b3e] h-[113px] w-[85px]"></div>
                        <div className="border border-[#1b2b3e] h-[113px] w-[85px]"></div>
                        <div className="bg-[#0066b4] h-[113px] w-[85px] flex items-center justify-center">
                          <div>
                            <p className="text-center text-[15px] text-white poppins-medium">
                              {cityHubData?.steps?.[0]?.dimensions?.width}
                            </p>
                            <p className="text-center text-[15px] text-white poppins-medium">
                              {cityHubData?.steps?.[0]?.dimensions?.height}
                            </p>
                          </div>
                        </div>
                        <div className="border border-[#1b2b3e] h-[113px] w-[85px]"></div>
                        <div className="border border-[#1b2b3e] h-[113px] w-[85px]"></div>
                      </div>
                      <p
                        style={{ textAlign: "center", color: "#25a0dd" }}
                        className="quaternary-para"
                      >
                        {cityHubData?.steps?.[0]?.price_label || "from"}
                      </p>
                      <p
                        style={{
                          fontSize: "1.63rem",
                          fontWeight: 700,
                          textAlign: "center",
                          color: "#25a0dd",
                        }}
                        className="quaternary-para pb-5"
                      >
                        {cityHubData?.steps?.[0]?.price}
                      </p>
                    </div>
                  </div>
                </div>
                {/* Step 2 */}
                <div className="mix-right-left-content">
                  <div className="step-container-eventhub">
                    <div className="step penta-heading">2</div>
                    <div className={`line red-line-1-completed-booster`}></div>
                  </div>
                  <div className="w-full">
                    <h3 className="tertiary-heading">
                      {cityHubData?.steps?.[1]?.title}
                    </h3>
                    <p className="primary-para primary-para-eventhubcreation mb-3">
                      {cityHubData?.steps?.[1]?.subtitle}
                    </p>
                    <p className="primary-para primary-para-eventhubcreation">
                      {cityHubData?.steps?.[1]?.cta}
                    </p>

                    <div className=" mt-[1rem] flex items-center gap-2 sm:gap-5  sm:mt-8 flex-wrap">
                      <button
                        style={{
                          color: "white",
                          backgroundColor:
                            selectedBooster === "booster"
                              ? "#155d8c"
                              : "#1d8dd1",
                        }}
                        className="rounded-xl px-4 sm:px-6 md:px-8 py-1 sm:py-1 uppercase tertiary-heading text-sm sm:text-base md:text-lg whitespace-nowrap transition-colors duration-200"
                        onClick={() => handleBoosterSelect("booster")}
                      >
                        {cityHubData?.steps?.[1]?.option1}
                      </button>
                      <button
                        style={{
                          color: "white",
                          backgroundColor:
                            selectedBooster === null ? "#155d8c" : "#1d8dd1",
                        }}
                        className="rounded-xl px-4 sm:px-6 md:px-8 py-1 sm:py-1 uppercase tertiary-heading text-sm sm:text-base md:text-lg whitespace-nowrap transition-colors duration-200"
                        onClick={() => handleBoosterSelect("normal")}
                      >
                        {cityHubData?.steps?.[1]?.option2}
                      </button>
                    </div>
                  </div>
                </div>
                {/*step 3  */}
                <div className="mix-right-left-content step3-contentspace-top">
                  <div className="step-container-eventhub">
                    <div className="step penta-heading">3</div>
                    <div
                      className={`line ${
                        searchQuery ? "red-line-1-completed" : "red-line-1"
                      }`}
                    ></div>
                  </div>
                  <div className="w-full">
                    <h3 className="tertiary-heading">
                      {cityHubData?.steps?.[2]?.title}
                    </h3>
                    <p className="primary-para primary-para-eventhubcreation">
                      {cityHubData?.steps?.[2]?.subtitle}
                    </p>
                    <div className="relative" ref={dropdownRef}>
                      <input
                        placeholder={cityHubData?.steps?.[2]?.cta}
                        className="postcode-input "
                        type="text"
                        value={searchQuery}
                        onChange={handleSearchChange}
                        onFocus={handleInputFocus}
                        onClick={handleInputFocus}
                      />
                      <img
                        className={`absolute right-[8px] lg:right-[5px] top-[44px] cursor-pointer transition-transform duration-200 ${
                          showDropdown ? "rotate-90" : ""
                        }`}
                        src="/right-arrow.png"
                        alt=""
                        onClick={showEvenHub}
                      />
                      {showDropdown && (
                        <div
                          style={{
                            position: "absolute",
                            top: "100%",
                            left: 0,
                            right: 0,
                            backgroundColor: "white",
                            border: "1px solid #ccc",
                            borderRadius: "4px",
                            maxHeight: "200px",
                            overflowY: "auto",
                            width: "70%",
                            zIndex: 1000,
                          }}
                        >
                          {filteredCommunes?.length > 0 ? (
                            filteredCommunes.map((commune) => (
                              <div
                                key={commune?.id}
                                onClick={() => handleCommuneSelect(commune)}
                                style={{
                                  padding: "8px 12px",
                                  cursor: "pointer",
                                  borderBottom: "1px solid #eee",
                                }}
                                onMouseEnter={(e) => {
                                  e.currentTarget.style.backgroundColor =
                                    "#f5f5f5";
                                }}
                                onMouseLeave={(e) => {
                                  e.currentTarget.style.backgroundColor =
                                    "transparent";
                                }}
                              >
                                <div>{commune?.commune_name}</div>
                                <div
                                  style={{ fontSize: "0.8em", color: "#666" }}
                                >
                                  {commune?.postal_code}{" "}
                                  {commune?.heading && `• ${commune?.heading}`}
                                </div>
                              </div>
                            ))
                          ) : (
                            <div style={{ padding: "8px 12px", color: "#666" }}>
                              {cityHubData?.steps?.[2]?.no_results ||
                                "No communes found"}
                            </div>
                          )}
                        </div>
                      )}
                    </div>
                  </div>
                </div>
                {/* step5 */}
                <div className="mix-right-left-content step3-contentspace-top">
                  <div className="step-container-eventhub">
                    <div className="step penta-heading">4</div>
                    <div
                      className={`line ${
                        durationInputValue
                          ? "red-line-2-completed"
                          : "red-line-2"
                      }`}
                    ></div>
                  </div>
                  <div className="w-full">
                    <h3 className="tertiary-heading">
                      {cityHubData?.steps?.[3]?.title}
                    </h3>
                    <p className="primary-para">
                      {cityHubData?.steps?.[3]?.subtitle}
                    </p>
                    <div className="relative" ref={durationDropdownRef}>
                      <input
                        placeholder={cityHubData?.steps?.[3]?.options}
                        className="postcode-input cursor-pointer"
                        type="text"
                        value={durationInputValue}
                        readOnly
                        onClick={toggleDurationDropdown} // Add this line
                      />
                      <img
                        className={`absolute right-[8px] lg:right-[5px] top-[44px] cursor-pointer transition-transform duration-200 ${
                          showDurationDropdown ? "rotate-90" : ""
                        } `}
                        src="/right-arrow.png"
                        alt=""
                        onClick={toggleDurationDropdown}
                      />
                      {showDurationDropdown && (
                        <div
                          style={{
                            position: "absolute",
                            top: "100%",
                            left: 0,
                            right: 0,
                            backgroundColor: "white",
                            border: "1px solid #ccc",
                            borderRadius: "4px",
                            maxHeight: "200px",
                            overflowY: "auto",
                            width: "100%",
                            zIndex: 1000,
                            boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                          }}
                        >
                          {getAvailableDurations().map((duration) => (
                            <div
                              key={duration}
                              onClick={() => handleDurationChange(duration)}
                              style={{
                                padding: "12px 16px",
                                cursor: "pointer",
                                borderBottom: "1px solid #eee",
                                fontSize: "1rem",
                                color: "#333",
                              }}
                              onMouseEnter={(e) => {
                                e.currentTarget.style.backgroundColor =
                                  "#f5f5f5";
                              }}
                              onMouseLeave={(e) => {
                                e.currentTarget.style.backgroundColor =
                                  "transparent";
                              }}
                            >
                              {duration}{" "}
                              {cityHubData?.steps?.[3]?.days_label || "days"}
                            </div>
                          ))}
                        </div>
                      )}
                    </div>
                  </div>
                </div>

                <div className="mix-right-left-content step3-contentspace-top">
                  <div className="step-container-eventhub">
                    <div className="step penta-heading">5</div>
                    <div
                      className={`line ${
                        campaignFormEventHub?.image !== ""
                          ? "red-line-3-completed"
                          : "red-line-3"
                      }`}
                    ></div>
                  </div>
                  <div className="w-full">
                    <h3 className="tertiary-heading">
                      {cityHubData?.steps?.[3]?.title}
                    </h3>
                    <p className="primary-para">
                      {cityHubData?.steps?.[3]?.subtitle}
                    </p>

                    <input
                      type="file"
                      accept="image/*"
                      className="hidden"
                      id="media-upload"
                      onChange={handleMediaUpload}
                    />

                    <div className="relative">
                      <div
                        className="postcode-input border-dashed border-2 border-gray-300 cursor-pointer flex items-center justify-center min-h-[200px]"
                        onClick={() =>
                          document.getElementById("media-upload")?.click()
                        }
                        onDragOver={(e) => {
                          e.preventDefault();
                          e.stopPropagation();
                          e.currentTarget.classList.add(
                            "border-blue-500",
                            "bg-blue-50"
                          );
                        }}
                        onDragEnter={(e) => {
                          e.preventDefault();
                          e.currentTarget.classList.add(
                            "border-blue-500",
                            "bg-blue-50"
                          );
                        }}
                        onDragLeave={(e) => {
                          e.preventDefault();
                          if (
                            !e.currentTarget.contains(e.relatedTarget as Node)
                          ) {
                            e.currentTarget.classList.remove(
                              "border-blue-500",
                              "bg-blue-50"
                            );
                          }
                        }}
                        onDrop={(e) => {
                          e.preventDefault();
                          e.stopPropagation();
                          e.currentTarget.classList.remove(
                            "border-blue-500",
                            "bg-blue-50"
                          );

                          const files = e.dataTransfer.files;
                          if (
                            files?.length > 0 &&
                            files[0]?.type.startsWith("image/")
                          ) {
                            const fakeEvent = {
                              target: {
                                files: files,
                              },
                            } as React.ChangeEvent<HTMLInputElement>;

                            handleMediaUpload(fakeEvent);
                          }
                        }}
                      >
                        {campaignFormEventHub?.image ? (
                          <div className="relative w-full h-full flex items-center justify-center">
                            <img
                              src={selectedMedia}
                              alt={
                                cityHubData?.steps?.[4]?.alt_selected ||
                                "Selected media"
                              }
                              className="max-h-[180px] max-w-full object-contain"
                            />
                          </div>
                        ) : (
                          <div className="text-center text-gray-500">
                            <div className="mb-2">
                              <img
                                src="/upload-icon.svg"
                                alt={
                                  cityHubData?.steps?.[4]?.alt_upload ||
                                  "Upload"
                                }
                                className="w-12 h-12 mx-auto opacity-50"
                              />
                            </div>
                            <p>
                              {cityHubData?.steps?.[4]?.upload_instruction1}
                            </p>
                            <p className="text-sm">
                              {cityHubData?.steps?.[4]?.upload_instruction2}
                            </p>
                          </div>
                        )}
                      </div>

                      {/* Action buttons - only show when image is selected */}
                      {campaignFormEventHub?.image && (
                        <div className="flex items-center gap-1 absolute top-[43px] right-[8px] lg:right-[0px]">
                          <img
                            className="cursor-pointer"
                            src="/cross-blue.png"
                            alt={
                              cityHubData?.steps?.[4]?.alt_remove || "Remove"
                            }
                            onClick={handleMediaClear}
                          />
                          {/* <img
                            className="cursor-pointer"
                            src="/check-blue.png"
                            alt={
                              cityHubData?.steps?.[4]?.alt_confirm || "Confirm"
                            }
                            onClick={handleMediaSelect}
                          /> */}
                        </div>
                      )}
                    </div>
                  </div>
                </div>

                {/* Step 6 - Activity Inputs */}
                <div className="mix-right-left-content step3-contentspace-top">
                  <div className="step-container-eventhub">
                    <div className="step penta-heading">6</div>
                    <div
                      className={`line ${
                        campaignFormEventHub?.image == ""
                          ? "red-line-4"
                          : "red-line-4-completed"
                      }`}
                    ></div>
                  </div>
                  <div className="w-full">
                    <h3 className="tertiary-heading">
                      {cityHubData?.steps?.[5]?.title}
                    </h3>
                    <p className="primary-para">
                      {cityHubData?.steps?.[5]?.subtitle}
                    </p>
                    <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-4">
                      {/* Left Column - Activity Inputs */}
                      <div>
                        <div className="activity-inputs-container space-y-3">
                          {/* Field 1 - Activity Title */}
                          <input
                            placeholder={cityHubData?.steps?.[5]?.field1}
                            className="activity-input w-full p-3 border border-[#c4c4c4] rounded-lg font-aileron-black text-sm"
                            type="text"
                            value={activityInputs.field1}
                            onChange={(e) => {
                              handleActivityInputChange(0, e.target.value);
                              dispatch(
                                updateCampaignEventHubFormAlt({
                                  key: "activity_title",
                                  value: e.target.value,
                                })
                              );
                            }}
                          />

                          {/* Field 2 - Commune (City Search) */}
                          <div className="relative" ref={cityDropdownRef}>
                            <input
                              placeholder={cityHubData?.steps?.[5]?.field2}
                              className="activity-input w-full p-3 border border-[#c4c4c4] rounded-lg font-aileron-black text-sm "
                              type="text"
                              value={citySearchQuery}
                              onChange={handleCitySearchChange}
                              onFocus={handleCityInputFocus}
                            />
                            {showCityDropdown && (
                              <div className="absolute top-full left-0 right-0 bg-white border border-gray-300 rounded-lg shadow-lg max-h-60 overflow-y-auto z-50">
                                {filteredCities.length > 0 ? (
                                  filteredCities.map((city) => (
                                    <div
                                      key={city.city_id}
                                      onClick={() => handleCitySelect(city)}
                                      className="p-3 cursor-pointer border-b border-gray-100 hover:bg-gray-50 transition-colors"
                                    >
                                      <div className="font-semibold text-gray-800">
                                        {city.city_name}
                                      </div>
                                      <div className="text-sm text-gray-600">
                                        {city.postal_code} - {city.state_name}
                                      </div>
                                    </div>
                                  ))
                                ) : (
                                  <div className="p-3 text-center text-gray-500">
                                    {citySearchQuery.length < 2
                                      ? cityHubData?.steps?.[5]
                                          ?.city_search_min ||
                                        "Type at least 2 characters"
                                      : cityHubData?.steps?.[5]
                                          ?.city_search_no_results ||
                                        "No cities found"}
                                  </div>
                                )}
                              </div>
                            )}
                          </div>

                          {/* Field 3 - Date & Time */}
                          <input
                            placeholder={cityHubData?.steps?.[5]?.field3}
                            className="activity-input w-full p-3 border border-[#c4c4c4] rounded-lg font-aileron-black text-sm"
                            type="datetime-local"
                            value={activityInputs.field3}
                            onChange={(e) => {
                              handleActivityInputChange(2, e.target.value);
                              dispatch(
                                updateCampaignEventHubFormAlt({
                                  key: "activity_dates",
                                  value: e.target.value,
                                })
                              );
                            }}
                          />

                          {/* Field 4 - Price */}
                          <input
                            placeholder={cityHubData?.steps?.[5]?.field4}
                            className="activity-input w-full p-3 border border-[#c4c4c4] rounded-lg font-aileron-black text-sm "
                            type="text"
                            value={activityInputs.field4}
                            onChange={(e) => {
                              handleActivityInputChange(3, e.target.value);
                              dispatch(
                                updateCampaignEventHubFormAlt({
                                  key: "activity_prices",
                                  value: e.target.value,
                                })
                              );
                            }}
                          />

                          {/* Field 5 - Description */}
                          <input
                            placeholder={cityHubData?.steps?.[5]?.field5}
                            className="activity-input w-full p-3 border border-[#c4c4c4] rounded-lg font-aileron-black text-sm "
                            value={activityInputs.field5}
                            type="text"
                            onChange={(e) => {
                              handleActivityInputChange(4, e.target.value);
                              dispatch(
                                updateCampaignEventHubFormAlt({
                                  key: "activity_description",
                                  value: e.target.value,
                                })
                              );
                            }}
                          />
                        </div>
                      </div>

                      {/* Right Column - Ad Preview */}
                      <div className="w-full">
                        <div className={previewContainerClasses.trim()}>
                          <div className="flex justify-between items-start w-full">
                            <div className="flex flex-col w-full max-w-full">
                              {campaignFormEventHub?.image ? (
                                <div
                                  className="relative w-full overflow-hidden rounded-md mb-2"
                                  style={{
                                    paddingTop:
                                      getAspectPadding(selectedBooster),
                                    maxWidth: "100%",
                                  }}
                                >
                                  <img
                                    src={selectedMedia}
                                    alt={
                                      cityHubData?.steps?.[5]?.alt_image ||
                                      "CityHub image"
                                    }
                                    className="absolute top-0 left-0 w-full h-full object-cover rounded-md"
                                  />
                                </div>
                              ) : (
                                // --- IMAGE PLACEHOLDER WITH DYNAMIC ASPECT RATIO ---
                                <div
                                  className="relative w-full mb-2 bg-[#f4f4f4] rounded-md flex items-center justify-center"
                                  style={{
                                    // FIX: Replace dynamic padding with constant height
                                    width: "100%",
                                    height: "250px",
                                    maxWidth: "100%",
                                  }}
                                >
                                  <p className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-gray-500 text-sm">
                                    {cityHubData?.steps?.[4]
                                      ?.preview_no_image ||
                                      "Aucune image fournie"}
                                  </p>
                                </div>
                              )}

                              <div className="preview-content mt-2 w-full">
                                {activityInputs.field1 && (
                                  <h4 className="text-lg font-semibold text-gray-900 mb-1 break-words">
                                    {activityInputs.field1}
                                  </h4>
                                )}
                                {activityInputs.field5 && (
                                  <p className="text-sm text-gray-700 mb-1 break-words">
                                    {activityInputs.field5}
                                  </p>
                                )}
                                {activityInputs.field3 && (
                                  <p className="text-xs text-gray-600 mb-1">
                                    {formatActivityDate(activityInputs.field3)}
                                  </p>
                                )}
                                {activityInputs.field4 && (
                                  <p className="text-xs text-gray-600 mb-1">
                                    {cityHubData?.steps?.[5]
                                      ?.price_label_preview || "Prix:"}{" "}
                                    {activityInputs.field4}€
                                  </p>
                                )}
                                {citySearchQuery && (
                                  <p className="text-xs text-gray-600 break-words">
                                    {citySearchQuery}
                                  </p>
                                )}
                              </div>
                            </div>
                            {/* <div className="flex-shrink-0 ml-2">
                              <img
                                className="cursor-pointer w-6 h-6"
                                src="/check-blue.png"
                                alt={
                                  cityHubData?.steps?.[5]?.alt_check || "Check"
                                }
                              />
                            </div> */}
                          </div>
                        </div>
                        {/* Removed commented-out note for clean code */}
                      </div>
                    </div>
                  </div>
                </div>

                <div className="mix-right-left-content step3-contentspace-top">
                  {/* Step 7 */}
                  <div className="step-container-eventhub">
                    <div className="step penta-heading">7</div>
                    <div
                      className={`line ${
                        campaignFormEventHub?.advert_redirect_url !== ""
                          ? "red-line-5-with-url-completed"
                          : "red-line-5-with-url"
                      }`}
                    ></div>
                  </div>
                  {/* step 7 */}
                  <div className="">
                    <h3 className="tertiary-heading">
                      {cityHubData?.steps?.[6]?.title}
                    </h3>
                    <p className="primary-para">
                      {cityHubData?.steps?.[6]?.subtitle}
                    </p>
                    <div className="flex items-center gap-5 mt-[1rem] sm:mt-8">
                      <button
                        style={{ color: "white" }}
                        className="bg-[#1d8dd1] rounded-xl px-8 py-1 uppercase tertiary-heading"
                        onClick={() => handleUrlToggle(true)}
                      >
                        {cityHubData?.steps?.[6]?.option1}
                      </button>
                      <button
                        style={{ color: "white" }}
                        className="bg-[#1d8dd1] rounded-xl px-8 py-1 uppercase tertiary-heading"
                        onClick={() => handleUrlToggle(false)}
                      >
                        {cityHubData?.steps?.[6]?.option2}
                      </button>
                    </div>
                    {showUrlInput && (
                      <div className="relative">
                        <input
                          placeholder={
                            cityHubData?.steps?.[6]?.url_placeholder ||
                            "https://eventx.fr/advertpage"
                          }
                          className="postcode-input"
                          type="text"
                          value={
                            campaignFormEventHub?.advert_redirect_url || ""
                          }
                          onChange={handleUrlChange}
                        />

                        <div className=" flex items-center gap-1 absolute top-[43px] right-[8px] lg:right-[0px]">
                          <img
                            className="cursor-pointer"
                            src="/cross-blue.png"
                            onClick={handleUrlCancel}
                          />
                          <img
                            className="cursor-pointer"
                            src="/check-blue.png"
                          />
                        </div>
                      </div>
                    )}
                  </div>
                </div>
                <div className="mix-right-left-content step3-contentspace-top">
                  {/* step  8 */}
                  <div className="step-container-eventhub">
                    <div className="step penta-heading">8</div>
                  </div>
                  <div className="step-5">
                    <h3 className="tertiary-heading">
                      {cityHubData?.steps?.[7]?.title}
                    </h3>
                    <p className="primary-para choose-p">
                      {cityHubData?.steps?.[7]?.subtitle}
                    </p>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div>
            {/* summary */}
            <h3 className="sum-h penta-heading">
              {cityHubData?.summary?.title || "Summary"}
            </h3>
            <div className="sum-container">
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "space-between",
                  marginBottom: "1.5rem",
                  marginTop: "0.5rem",
                }}
              >
                {/* <h4 className="penta-heading2 slot-p">SLOT 1</h4> */}
                {/* <img style={{ width: "20px" }} src="/top-arrow.png" /> */}
              </div>
              {/*  */}
              {slot?.map((item, i) => (
                <div key={i} className="slot-1-content">
                  <>
                    <p className="secondary-para">{item?.title}</p>
                    <p className="secondary-para">{item?.content}</p>
                  </>
                </div>
              ))}

              <div className="slot-1-content">
                <>
                  <p className="secondary-para">
                    {cityHubData?.summary?.duration || "Duration"}
                  </p>
                  <p
                    style={{ color: "#299B13", fontSize: "1.25rem" }}
                    className="secondary-para"
                  >
                    {currentDuration} {cityHubData?.summary?.days || "days"}
                  </p>
                </>
              </div>
              <div className="advert">
                <div className="slot-1-content">
                  <>
                    <p className="secondary-para">
                      {cityHubData?.summary?.advert_starts || "Advert Starts"}
                    </p>
                    <p className="secondary-para">{currentDates.start}</p>
                  </>
                </div>
                <div className="slot-1-content">
                  <>
                    <p className="secondary-para">
                      {cityHubData?.summary?.advert_ends || "Advert Ends"}
                    </p>
                    <p className="secondary-para">{currentDates.end}</p>
                  </>
                </div>
              </div>
              <div style={{ marginTop: "1rem" }} className="slot-1-content">
                <>
                  <p
                    style={{ color: "#299B13", fontSize: "1.5rem" }}
                    className="secondary-para"
                  >
                    {cityHubData?.summary?.total_ttc || "Total TTC"}
                  </p>
                  <p
                    style={{ color: "#299B13", fontSize: "1.6rem" }}
                    className="secondary-para"
                  >
                    {currentPrice}€
                  </p>
                </>
              </div>
              <p style={{ color: "#6A6C5E" }} className="secondary-para">
                {cityHubData?.summary?.coupon_text ||
                  "Have a Coupon? Add at Checkout"}
              </p>
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "space-between",
                  marginBottom: "1.5rem",
                  marginTop: "2.5rem",
                }}
              >
                {/* <h4 className="penta-heading2 slot-p">SLOT 2</h4> */}
                {/* <img style={{ width: "20px" }} src="/bottom-arrow.png" /> */}
              </div>

              {/*  */}
              <div
                style={{
                  display: "flex",
                  justifyContent: "center",
                  cursor:
                    isProcessing || isProcessingCallback
                      ? "not-allowed"
                      : "pointer",
                }}
                onClick={onPayment}
              >
                <button
                  className={`paymentBtn penta-heading ${
                    isProcessing || isProcessingCallback
                      ? "paymentBtn:disabled"
                      : ""
                  }`}
                  disabled={isProcessing || isProcessingCallback}
                >
                  {isProcessing || isProcessingCallback ? (
                    <>
                      <div className="loading-spinner"></div>
                      {isProcessingCallback
                        ? cityHubData?.processing?.creating_campaign ||
                          "Creating Campaign..."
                        : cityHubData?.processing?.processing ||
                          "Processing..."}
                    </>
                  ) : (
                    <>
                      <img
                        src="/cart-white.png"
                        className="w-[30px] md:w-[30px]"
                        alt={cityHubData?.summary?.alt_cart || "Cart"}
                      />
                      {cityHubData?.summary?.payment_button ||
                        "Go to the Payment Page"}
                    </>
                  )}
                </button>
              </div>
            </div>
            {/* open map */}
            {/* <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: "1rem",
          marginTop: "2rem",
        }}
      >
        <p
          style={{ color: "#0066B4", textAlign: "center" }}
          className="tertiary-heading"
        >
          OPEN <br /> MAP
        </p>
        <img src="/open-map.png" className="w-[34px] md:w-[50px]" />
      </div> */}
          </div>
        </div>
        {showCropper && imageToCrop && (
          <ImageCropperEventHub
            imageSrc={imageToCrop}
            selectedBooster={selectedBooster}
            onCropComplete={handleCropComplete}
            onCancel={() => {
              setShowCropper(false);
              setImageToCrop(null);
              handleRemoveMedia();
            }}
            translations={cityHubData?.cropper}
          />
        )}
      </div>
    </>
  );
}
