import type { MetaFunction } from "@remix-run/node";
import { X, Loader } from "lucide-react";
import HeaderWithSupport from "../components/HeaderWithSupport";
import { useSearchParams } from "react-router-dom";
import { safeGoBack } from "~/utils/helpers";
import { convertHeicFiles } from "~/utils/convert-heic";
import { useRef, useState, useEffect } from "react";
import { Button } from "../components/ui/button";
import { ImageUploadDrawer } from "~/components/store/ImageUploadDrawer";
import { ImageEditor } from "~/components/store/ImageEditor";
import { ImageUploadSection } from "~/components/store/ImageUploadSection";
import { ProductDetailsForm } from "~/components/store/ProductDetailsForm";
import { ProductVariantsSection } from "~/components/store/ProductVariantsSection";
import { SizeChartSection } from "~/components/store/SizeChartSection";
import { PricingForm } from "~/components/store/PricingForm";
import {
  useCreateFullProduct,
  useProductCategories,
  useProductDetails,
  useUpdateProduct,
} from "~/requestHandler/use-product-hooks";
import { useImageUpload } from "~/requestHandler/use-media-hooks";
import { toast } from "~/hooks/use-toast";
import AppSelectBox from "~/components/AppSelectBox";
import { FormField } from "~/components/ui/FormField";
import {
  useGetInstagramPostDetails,
  useGenerateProductFromPost,
} from "~/requestHandler/use-instagram-hooks";
import {
  FullProductCreate,
  ProductVariant as ApiProductVariant,
  ProductAttributeItem,
  MediaUploadImageUsageEnum,
  SizeChart,
} from "../../src/api/types";
import { Dialog, DialogContent, DialogOverlay } from "../components/ui/dialog";
import { useNavigate, useParams } from "@remix-run/react";
import { useStoreOwnership } from "../hooks/useStoreOwnership";

export const meta: MetaFunction = () => {
  return [
    { title: "افزودن محصول - ویترون" },
    {
      name: "description",
      content:
        "افزودن محصول جدید به فروشگاه شما در ویترون. آپلود تصاویر، تعیین قیمت، ویژگی‌ها و تنظیمات محصول.",
    },
    {
      name: "keywords",
      content: "افزودن محصول، جدید محصول، فروشگاه، قیمت گذاری، ویترون",
    },
    { name: "robots", content: "noindex, follow" },
    { property: "og:title", content: "افزودن محصول - ویترون" },
    {
      property: "og:description",
      content:
        "افزودن محصول جدید به فروشگاه شما در ویترون. آپلود تصاویر، تعیین قیمت، ویژگی‌ها و تنظیمات محصول.",
    },
    { property: "og:type", content: "website" },
    { name: "twitter:card", content: "summary" },
    { name: "twitter:title", content: "افزودن محصول - ویترون" },
    {
      name: "twitter:description",
      content:
        "افزودن محصول جدید به فروشگاه شما در ویترون. آپلود تصاویر، تعیین قیمت، ویژگی‌ها و تنظیمات محصول.",
    },
  ];
};

// Local interface for the component's variant structure
interface ProductVariant {
  color: string;
  size: string;
  quantity: number;
}

export default function AddProduct() {
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const { storeId } = useParams();

  // Get URL parameters
  const postId = searchParams.get("id");
  const isAI = searchParams.get("ai") === "true";
  const editProductId = searchParams.get("edit");

  // Check store ownership - this will redirect if user doesn't own the store
  const { isLoading: isOwnershipLoading } = useStoreOwnership(storeId);

  // Step management
  const [currentStep, setCurrentStep] = useState(1);

  // Step 1 - Product Info
  const [productTitle, setProductTitle] = useState("");
  const [productDescription, setProductDescription] = useState("");
  const [selectedCategory, setSelectedCategory] = useState("");
  // Step 2 - Pricing
  const [productPrice, setProductPrice] = useState("");
  const [finalPrice, setFinalPrice] = useState("");

  // Loading states
  const [isSubmittingProduct, setIsSubmittingProduct] = useState(false);
  const [imageUploadProgress, setImageUploadProgress] = useState({
    current: 0,
    total: 0,
    isUploading: false,
  });

  // API hooks
  const createProductMutation = useCreateFullProduct();
  const updateProductMutation = useUpdateProduct();
  const imageUploadMutation = useImageUpload();

  // Product details for editing
  const { data: existingProduct } = useProductDetails(editProductId || "");

  // Instagram post hooks - only fetch if we have postId and AI is false
  const { data: instagramPostData, isLoading: isLoadingPostData } =
    useGetInstagramPostDetails(postId || "", {
      enabled: !!postId && !isAI,
    });

  // Generate product hook - for AI generation
  const {
    data: aiGeneratedData,
    isLoading: isAiGenerating,
    error: aiGenerationError,
  } = useGenerateProductFromPost(postId || "", {
    enabled: !!postId && isAI,
  });

  // Fetch categories
  const { data: categoriesData, isLoading: categoriesLoading } =
    useProductCategories();

  // Categories now live in a two-level tree (parent > sub). The seller first
  // picks the parent bucket, then a sub-bucket underneath. Selected sub is
  // the value we send to the backend; the parent is UI state only.
  const parentOptions = (categoriesData || [])
    .filter((c) => !c.parentId)
    .map((cat) => ({ value: cat.id || "", label: cat.name }));

  const [selectedParent, setSelectedParent] = useState("");

  const subOptions = (categoriesData || [])
    .filter((c) => c.parentId && c.parentId === selectedParent)
    .map((cat) => ({ value: cat.id || "", label: cat.name }));

  // Legacy flat list used by helpers/copy that just want to look up a name.
  const categoryOptions = (categoriesData || []).map((cat) => ({
    value: cat.id || "",
    label: cat.name,
  }));

  // Track if form has been initialized and previous AI state
  const [formInitialized, setFormInitialized] = useState(false);
  const [previousIsAI, setPreviousIsAI] = useState<boolean | null>(null);

  // Determine if we're in edit mode
  const isEditMode = !!editProductId;

  // Effect to fill form with existing product data for editing
  useEffect(() => {
    if (existingProduct && isEditMode && !formInitialized) {
      setProductTitle(existingProduct.title || "");
      setProductDescription(existingProduct.description || "");
      setSelectedCategory(existingProduct.category || "");
      // Derive the parent bucket from the sub's parentId so the two-step
      // picker shows the correct main category when the seller opens edit.
      if (existingProduct.category && categoriesData) {
        const sub = categoriesData.find((c) => c.id === existingProduct.category);
        if (sub?.parentId) setSelectedParent(sub.parentId);
      }
      setSizeChart(existingProduct.sizeChart || null);
      setProductPrice(
        existingProduct.basePrice
          ? parseInt(existingProduct.basePrice).toString()
          : ""
      );

      // Set final price if available from first variant
      if (existingProduct.variants && existingProduct.variants.length > 0) {
        const firstVariant = existingProduct.variants[0];
        const discountPrice = firstVariant.discountPrice
          ? parseInt(firstVariant.discountPrice).toString()
          : "";
        const regularPrice = firstVariant.price
          ? parseInt(firstVariant.price).toString()
          : "";
        setFinalPrice(discountPrice || regularPrice);
      }

      // Set images from existing product
      if (existingProduct.imageUrls && existingProduct.imageUrls.length > 0) {
        const existingImages = existingProduct.imageUrls.map((url, index) => ({
          file: new File([], `existing-image-${index + 1}.jpg`, {
            type: "image/jpeg",
          }),
          url: url,
          isEdited: false,
          originalUrl: url,
          uploadedUrl: undefined,
        }));
        setSelectedImages(existingImages);
      }

      // Set variants from existing product
      if (existingProduct.variants && existingProduct.variants.length > 0) {
        const existingVariants = existingProduct.variants
          .filter((variant) => variant.stock && variant.stock > 0) // Only include variants with stock
          .map((variant) => ({
            color:
              variant.resolvedAttributes?.COLOR ||
              variant.attributes?.COLOR ||
              "unselected",
            size:
              variant.resolvedAttributes?.SIZE ||
              variant.attributes?.SIZE ||
              "unselected",
            quantity: variant.stock || 0,
          }));

        // If no variants with stock, create a default variant
        if (existingVariants.length === 0) {
          existingVariants.push({
            color: "unselected",
            size: "unselected",
            quantity: 1,
          });
        }

        setProductVariants(existingVariants);
      } else {
        // If no variants exist, create a default variant
        setProductVariants([
          {
            color: "unselected",
            size: "unselected",
            quantity: 1,
          },
        ]);
      }

      setFormInitialized(true);
    }
  }, [existingProduct, isEditMode, formInitialized]);

  // Effect to fill form when AI generation is complete
  useEffect(() => {
    if (aiGeneratedData && isAI && !formInitialized && !isEditMode) {
      setProductTitle(aiGeneratedData.product.title || "");
      setProductDescription(aiGeneratedData.product.description || "");
      setSelectedImages(
        aiGeneratedData.product.imageUrls.map((url) => ({
          file: new File([], url),
          url: url,
          isEdited: false,
          originalUrl: url,
          uploadedUrl: undefined,
        }))
      );

      // Set pricing
      if (aiGeneratedData.product.basePrice) {
        setProductPrice(
          parseInt(aiGeneratedData.product.basePrice.toString()).toString()
        );
      }

      // Set final price from first variant if available
      if (
        aiGeneratedData.product.variants &&
        aiGeneratedData.product.variants.length > 0
      ) {
        const firstVariant = aiGeneratedData.product.variants[0];
        const variantPrice = firstVariant.price
          ? parseInt(firstVariant.price.toString()).toString()
          : "";
        const basePrice = aiGeneratedData.product.basePrice
          ? parseInt(aiGeneratedData.product.basePrice.toString()).toString()
          : "";
        setFinalPrice(variantPrice || basePrice);
      }

      // Set category - we need to find the category ID from the category name
      if (aiGeneratedData.product.category && categoriesData) {
        // Don't set category if it's UNSELECTED or similar values
        const categoryName = aiGeneratedData.product.category;
        if (
          categoryName.toLowerCase() !== "unselected" &&
          categoryName.toLowerCase() !== "none"
        ) {
          const categoryMatch = categoriesData.find(
            (cat) => cat.name === categoryName
          );
          if (categoryMatch && categoryMatch.id) {
            setSelectedCategory(categoryMatch.id);
          }
        }
      }

      // Set variants - convert from API format to component format
      if (
        aiGeneratedData.product.variants &&
        aiGeneratedData.product.variants.length > 0
      ) {
        const convertedVariants = aiGeneratedData.product.variants.map(
          (variant) => ({
            color:
              variant.attributes?.COLOR?.toLowerCase() === "unselected"
                ? "unselected"
                : variant.attributes?.COLOR || "unselected",
            size:
              variant.attributes?.SIZE?.toLowerCase() === "unselected"
                ? "unselected"
                : variant.attributes?.SIZE || "unselected",
            quantity: variant.stock || 0,
          })
        );
        setProductVariants(convertedVariants);
      } else {
        // Default variant if none provided
        setProductVariants([
          {
            color: "unselected",
            size: "unselected",
            quantity: 1,
          },
        ]);
      }

      setFormInitialized(true);
    }
  }, [aiGeneratedData, isAI, formInitialized, isEditMode, categoriesData]);

  // Effect to set category when categoriesData loads after AI generation
  useEffect(() => {
    if (
      aiGeneratedData &&
      isAI &&
      formInitialized &&
      !isEditMode &&
      categoriesData &&
      !selectedCategory &&
      aiGeneratedData.product.category
    ) {
      const categoryName = aiGeneratedData.product.category;
      // Don't set category if it's UNSELECTED or similar values
      if (
        categoryName.toLowerCase() !== "unselected" &&
        categoryName.toLowerCase() !== "none"
      ) {
        const categoryMatch = categoriesData.find(
          (cat) => cat.name === categoryName
        );
        if (categoryMatch && categoryMatch.id) {
          setSelectedCategory(categoryMatch.id);
        }
      }
    }
  }, [
    categoriesData,
    aiGeneratedData,
    isAI,
    formInitialized,
    isEditMode,
    selectedCategory,
  ]);

  // Effect to handle initial data loading from Instagram post (only for manual mode)
  useEffect(() => {
    if (instagramPostData && !isAI && !formInitialized && !isEditMode) {
      // If AI is false and we have post data, populate initial values
      setProductTitle(instagramPostData.caption?.split("\n")[0] || "");
      setProductDescription(instagramPostData.caption || "");

      // Convert Instagram URLs to File-like objects
      if (
        instagramPostData.localMedia &&
        instagramPostData.localMedia.length > 0
      ) {
        const imageFiles = instagramPostData.localMedia.map(
          (url: string, index: number) => {
            // Create a dummy File object for Instagram URLs
            const dummyFile = new File([], `instagram-image-${index + 1}.jpg`, {
              type: "image/jpeg",
            });

            return {
              file: dummyFile,
              url: url,
              isEdited: false,
              originalUrl: url,
              uploadedUrl: undefined,
            };
          }
        );

        setSelectedImages(imageFiles);
      }
      setFormInitialized(true);
    }
  }, [instagramPostData, isAI, formInitialized, isEditMode]);

  // Reset form only when actually switching between AI and manual modes
  useEffect(() => {
    // Only reset if we're switching from one mode to another (not on initial load)
    if (previousIsAI !== null && previousIsAI !== isAI && postId) {
      setFormInitialized(false);
      setProductTitle("");
      setProductDescription("");
      setSelectedImages([]);
      setSelectedCategory("");
      setProductVariants([]);
      setProductPrice("");
      setFinalPrice("");
    }
    setPreviousIsAI(isAI);
  }, [isAI, postId, previousIsAI]);

  const [isDrawerOpen, setIsDrawerOpen] = useState(false);
  const [isImageEditorOpen, setIsImageEditorOpen] = useState(false);
  const [currentEditingIndex, setCurrentEditingIndex] = useState<number | null>(
    null
  );
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [selectedImages, setSelectedImages] = useState<
    Array<{
      file: File;
      url: string;
      isEdited: boolean;
      originalUrl?: string;
      uploadedUrl?: string;
    }>
  >([]);
  const [productVariants, setProductVariants] = useState<ProductVariant[]>([]);
  const [sizeChart, setSizeChart] = useState<SizeChart | null>(null);

  // Distinct sizes this product offers (drives the size-chart rows & requirement).
  const productSizes = [
    ...new Set(
      productVariants
        .map((v) => v.size)
        .filter((s) => s && s !== "unselected" && s.trim() !== "")
    ),
  ];
  const hasSizes = productSizes.length > 0;
  const selectedCategoryName =
    categoryOptions.find((o) => o.value === selectedCategory)?.label || "";

  // Complete = has columns and every offered size has a row with ≥1 filled value.
  const isSizeChartComplete = () => {
    if (!hasSizes) return true; // only required when the product has sizes
    if (!sizeChart || sizeChart.columns.length === 0) return false;
    return productSizes.every((s) => {
      const row = sizeChart.rows.find((r) => r.label.trim() === s.trim());
      return !!row && row.values.some((v) => v && v.trim() !== "");
    });
  };

  // Function to update variant quantity
  const updateVariantQuantity = (index: number, newQuantity: number) => {
    setProductVariants((prev) =>
      prev.map((variant, i) =>
        i === index ? { ...variant, quantity: newQuantity } : variant
      )
    );
  };

  // Validation functions
  const allVariantsHaveRealSize = () =>
    productVariants.length > 0 &&
    productVariants.every(
      (v) => v.size && v.size !== "unselected" && v.size.trim() !== ""
    );

  const isStep1Valid = () => {
    return (
      selectedImages.length > 0 &&
      productTitle.trim() !== "" &&
      productDescription.trim() !== "" &&
      selectedCategory !== "" &&
      allVariantsHaveRealSize() &&
      isSizeChartComplete()
    );
  };

  const isStep2Valid = () => {
    return productPrice.trim() !== "";
  };

  // Helper function to determine which images need to be uploaded
  const getImagesToUpload = () => {
    return selectedImages.filter((img) => img.isEdited || !img.originalUrl);
  };

  // Helper function to get final image URLs.
  //
  // Uploads in parallel (bounded concurrency) with one automatic retry per
  // image, so a single flaky request over a slow Iran connection can't drop
  // the seller out of the whole submission. Every successful upload is
  // persisted to `selectedImages[i].uploadedUrl` immediately, so if the
  // seller retries the submit later, only the still-failing images re-upload.
  // Returns only the successful URLs; if any failed, the seller gets a
  // toast naming the count so they know to re-pick and try again.
  const getFinalImageUrls = async (): Promise<string[]> => {
    const totalImages = selectedImages.length;
    setImageUploadProgress({
      current: 0,
      total: totalImages,
      isUploading: true,
    });

    let completed = 0;
    const bumpProgress = () => {
      completed += 1;
      setImageUploadProgress({
        current: completed,
        total: totalImages,
        isUploading: true,
      });
    };

    const CONCURRENCY = 3;
    const isValidUrl = (u: unknown): u is string =>
      typeof u === "string" && /^https?:\/\//i.test(u);

    const uploadOne = async (index: number): Promise<string | null> => {
      const image = selectedImages[index];

      // Already-uploaded or unedited-existing paths bypass the network.
      if (image.uploadedUrl && isValidUrl(image.uploadedUrl)) {
        bumpProgress();
        return image.uploadedUrl;
      }
      if (!image.isEdited && image.originalUrl && isValidUrl(image.originalUrl)) {
        bumpProgress();
        return image.originalUrl;
      }

      // Needs an upload — try twice.
      for (let attempt = 0; attempt < 2; attempt++) {
        try {
          const result = await imageUploadMutation.mutateAsync({
            file: image.file,
            usageType: MediaUploadImageUsageEnum.Product,
          });
          const uploadedUrl = result.originalUrl;
          if (isValidUrl(uploadedUrl)) {
            // Persist success so a subsequent retry-submit doesn't re-upload.
            setSelectedImages((prev) =>
              prev.map((img, i) => (i === index ? { ...img, uploadedUrl } : img))
            );
            bumpProgress();
            return uploadedUrl;
          }
        } catch {
          // Fall through to next attempt.
        }
      }
      bumpProgress();
      return null;
    };

    const queue = selectedImages.map((_, i) => i);
    const worker = async () => {
      while (queue.length > 0) {
        const idx = queue.shift();
        if (idx == null) break;
        results[idx] = await uploadOne(idx);
      }
    };
    const results: (string | null)[] = new Array(totalImages).fill(null);
    await Promise.all(
      Array.from({ length: Math.min(CONCURRENCY, totalImages) }, () => worker())
    );

    setImageUploadProgress({ current: 0, total: 0, isUploading: false });

    const succeeded = results.filter(isValidUrl);
    const failedCount = results.length - succeeded.length;
    if (failedCount > 0) {
      toast({
        title: `${failedCount} تصویر آپلود نشد`,
        description:
          "با تصاویر باقی‌مانده ادامه دادیم. برای آپلود تصاویر ناموفق، بعد از ذخیره‌سازی محصول، آن‌ها را دوباره اضافه کنید.",
        variant: "destructive",
      });
    }
    return succeeded;
  };

  // Helper function to prepare product attributes
  const prepareProductAttributes = (
    variants: ProductVariant[]
  ): ProductAttributeItem[] => {
    const attributes: ProductAttributeItem[] = [];

    // Add colors (excluding unselected)
    const colors = [
      ...new Set(
        variants.map((v) => v.color).filter((c) => c !== "unselected")
      ),
    ];
    if (colors.length > 0) {
      colors.forEach((color) => {
        attributes.push({
          attribute: "COLOR",
          value: color, // Use raw color value instead of persian translation
        });
      });
    }

    // Add sizes (excluding unselected)
    const sizes = [
      ...new Set(variants.map((v) => v.size).filter((s) => s !== "unselected")),
    ];
    if (sizes.length > 0) {
      sizes.forEach((size) => {
        attributes.push({
          attribute: "SIZE",
          value: size,
        });
      });
    }

    return attributes;
  };

  // Helper function to prepare product variants
  const prepareProductVariants = (
    variants: ProductVariant[]
  ): ApiProductVariant[] => {
    return variants.map((variant) => {
      // Create variant name based on color and size
      let variantName = "";
      if (variant.color === "unselected" && variant.size === "unselected") {
        variantName = "Default";
      } else if (variant.color === "unselected") {
        variantName = variant.size;
      } else if (variant.size === "unselected") {
        variantName = variant.color;
      } else {
        variantName = `${variant.color}-${variant.size}`;
      }

      // Prepare attributes object
      const attributes: Record<string, string> = {};
      if (variant.color !== "unselected") {
        attributes.COLOR = variant.color;
      }
      if (variant.size !== "unselected" && variant.size !== "") {
        attributes.SIZE = variant.size;
      }

      // Only ship a `discountPrice` when the seller has actually configured a
      // discount (finalPrice strictly below productPrice). Passing an equal
      // value used to leak through the PricingForm's "no discount" radio and
      // land as a phantom promo in the DB — the storefront still hid it, but
      // saving the product a second time could bring it back if the field
      // drifted. Send null so the backend clears any stale value on update.
      const priceNum = Number(productPrice || 0);
      const finalNum = Number(finalPrice || 0);
      const hasRealDiscount =
        Number.isFinite(priceNum) &&
        Number.isFinite(finalNum) &&
        finalNum > 0 &&
        finalNum < priceNum;

      return {
        variantName: variantName,
        stock: variant.quantity,
        price: productPrice || "0",
        discountPrice: hasRealDiscount ? finalPrice : null,
        attributes: attributes,
      };
    });
  };

  // Main product submission handler
  const handleProductSubmission = async () => {
    try {
      setIsSubmittingProduct(true);

      // Get final image URLs (only upload edited/new images)
      const imageUrls = await getFinalImageUrls();

      // getFinalImageUrls already filters to valid http(s) URLs and toasts
      // when some failed. Refuse to submit with no images at all — otherwise
      // the seller sees a cryptic backend validation error.
      if (imageUrls.length === 0) {
        toast({
          title: "هیچ تصویری آپلود نشد",
          description:
            "لطفاً اتصال اینترنت را بررسی کنید و دوباره تلاش کنید. با تصاویر کوچک‌تر یا کمتر شروع کنید.",
          variant: "destructive",
        });
        return;
      }

      const sizeChartPayload =
        sizeChart && sizeChart.columns.length > 0 && sizeChart.rows.length > 0
          ? sizeChart
          : null;

      const validImageUrls = imageUrls;

      if (isEditMode && editProductId) {
        // Update existing product
        const updateData = {
          title: productTitle,
          description: productDescription,
          basePrice: productPrice || "",
          imageUrls: validImageUrls,
          category: selectedCategory,
          attributes: prepareProductAttributes(productVariants),
          variants: prepareProductVariants(productVariants),
          sizeChart: sizeChartPayload,
        };
        await updateProductMutation.mutateAsync({
          productId: editProductId,
          productData: updateData,
        });
        navigate(`/store/${storeId}/product/${editProductId}`);
      } else {
        // Create new product
        const productData: FullProductCreate = {
          title: productTitle,
          description: productDescription,
          basePrice: productPrice || "",
          imageUrls: validImageUrls,
          category: selectedCategory,
          attributes: prepareProductAttributes(productVariants),
          variants: prepareProductVariants(productVariants),
          instagramPostId: postId ? parseInt(postId) : undefined,
          sizeChart: sizeChartPayload,
        };

        const product = await createProductMutation.mutateAsync(productData);
        navigate(`/store/${product.seller?.username}`);
      }
    } catch (error) {
      console.error(
        `Failed to ${isEditMode ? "update" : "create"} product:`,
        error
      );
    } finally {
      setIsSubmittingProduct(false);
    }
  };

  const handleContinue = () => {
    if (currentStep === 1 && isStep1Valid()) {
      setCurrentStep(2);
    } else if (currentStep === 2 && isStep2Valid()) {
      handleProductSubmission();
    }
  };

  const handleBack = () => {
    if (currentStep === 2) {
      setCurrentStep(1);
    } else {
      safeGoBack(navigate);
    }
  };

  // Handle drawer actions
  const handleUploadClick = () => {
    setIsDrawerOpen(true);
  };

  const handleCameraSelect = () => {
    setIsDrawerOpen(false);
    if (fileInputRef.current) {
      fileInputRef.current.setAttribute("capture", "environment");
      fileInputRef.current.click();
    }
  };

  const handleGallerySelect = () => {
    setIsDrawerOpen(false);
    if (fileInputRef.current) {
      fileInputRef.current.removeAttribute("capture");
      fileInputRef.current.click();
    }
  };

  const handleRemoveImage = (indexToRemove: number) => {
    setSelectedImages((prev) => {
      const imageToRemove = prev[indexToRemove];
      const newImages = prev.filter((_, index) => index !== indexToRemove);
      if (imageToRemove) {
        setTimeout(() => {
          URL.revokeObjectURL(imageToRemove.url);
        }, 1000);
      }
      return newImages;
    });
  };

  const handleScaleImage = (index: number) => {
    setCurrentEditingIndex(index);
    setIsImageEditorOpen(true);
  };

  const handleImageEditorSave = (editedImageBlob: Blob) => {
    if (currentEditingIndex === null) return;

    // Clean up old URL
    const oldImage = selectedImages[currentEditingIndex];
    if (oldImage) {
      URL.revokeObjectURL(oldImage.url);
    }

    // Create new file and URL
    const newFile = new File(
      [editedImageBlob],
      oldImage?.file.name || "edited-image.jpg",
      {
        type: editedImageBlob.type,
      }
    );
    const newUrl = URL.createObjectURL(editedImageBlob);

    // Update the image in state
    setSelectedImages((prev) =>
      prev.map((image, index) =>
        index === currentEditingIndex
          ? {
              file: newFile,
              url: newUrl,
              isEdited: true,
              originalUrl: oldImage?.originalUrl || oldImage?.url,
              uploadedUrl: undefined, // Clear uploaded URL since image is edited
            }
          : image
      )
    );

    setCurrentEditingIndex(null);
  };

  // Handle image selection
  const handleImageSelect = async (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const files = event.target.files;
    if (files && files.length > 0) {
      // iPhone photos are HEIC, which most browsers can't preview/crop.
      // Convert to JPEG up front so preview, the crop editor, and upload work.
      const converted = await convertHeicFiles(Array.from(files));

      const newImages = converted.map((file) => ({
        file,
        url: URL.createObjectURL(file),
        isEdited: false,
        uploadedUrl: undefined,
      }));

      setSelectedImages((prev) => [...prev, ...newImages]);

      // Reset the input value so the same files can be selected again if needed
      if (fileInputRef.current) {
        fileInputRef.current.value = "";
      }
    }
  };

  // Handle pricing changes
  const handlePriceChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setProductPrice(e.target.value.replace(/[^0-9]/g, ""));
  };

  const onFinalPriceChange = (finalPrice: string) => {
    setFinalPrice(finalPrice);
  };

  // Show loading while checking ownership
  if (isOwnershipLoading) {
    return (
      <div className="flex items-center justify-center">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-0 w-full lg:max-w-[760px] lg:mx-auto lg:pt-6">
      <HeaderWithSupport
        title={
          isEditMode
            ? "ویرایش محصول"
            : postId && isAI
              ? "ایجاد محصول با هوش مصنوعی"
              : postId && !isAI
                ? "ایجاد محصول از پست اینستاگرام"
                : "افزودن محصول جدید"
        }
        onBack={handleBack}
      />

      {/* Show form only if not in AI generation mode or AI generation is complete */}
      {(!postId || !isAI || !isAiGenerating) && (
        <>
          {currentStep === 1 && (
            <>
              {/* Image Upload Section */}
              <ImageUploadSection
                selectedImages={selectedImages}
                onUploadClick={handleUploadClick}
                onRemoveImage={handleRemoveImage}
                onScaleImage={handleScaleImage}
                onImageSelect={handleImageSelect}
                fileInputRef={fileInputRef}
              />

              {/* Product Details Form */}
              <ProductDetailsForm
                productTitle={productTitle}
                productDescription={productDescription}
                onTitleChange={(e) => setProductTitle(e.target.value)}
                onDescriptionChange={(e) =>
                  setProductDescription(e.target.value)
                }
              />

              {/* Category Selection — two-step: parent then sub */}
              <div className="px-4 mt-4 space-y-3">
                <FormField label="دسته‌بندی اصلی" required>
                  <AppSelectBox
                    items={parentOptions}
                    value={selectedParent}
                    setValue={(v: string) => {
                      setSelectedParent(v);
                      // Reset the sub whenever the parent changes so we never
                      // send a sub that no longer belongs to the picked parent.
                      setSelectedCategory("");
                    }}
                    placeholder="ابتدا یک دسته اصلی انتخاب کنید"
                    loading={categoriesLoading}
                    haveSearchbar={true}
                    width="w-full"
                  />
                </FormField>
                <FormField label="زیر‌دسته" required>
                  <AppSelectBox
                    items={subOptions}
                    value={selectedCategory}
                    setValue={setSelectedCategory}
                    placeholder={
                      selectedParent
                        ? "یک زیر‌دسته انتخاب کنید"
                        : "ابتدا دسته اصلی را انتخاب کنید"
                    }
                    loading={categoriesLoading}
                    haveSearchbar={true}
                    width="w-full"
                  />
                </FormField>
              </div>

              {/* Product Variants Section */}
              <ProductVariantsSection
                setProductVariants={setProductVariants}
                productVariants={productVariants}
                onUpdateVariantQuantity={updateVariantQuantity}
              />

              {/* Size Chart (راهنمای سایز) */}
              <div className="px-4 mt-4">
                <SizeChartSection
                  value={sizeChart}
                  onChange={setSizeChart}
                  categoryName={selectedCategoryName}
                  productSizes={productSizes}
                  required={hasSizes}
                  showError={hasSizes && !isSizeChartComplete()}
                />
              </div>
            </>
          )}

          {currentStep === 2 && (
            <PricingForm
              productPrice={productPrice}
              finalPrice={finalPrice}
              onPriceChange={handlePriceChange}
              onFinalPriceChange={onFinalPriceChange}
            />
          )}

          {/* Action Buttons */}
          <div className="flex flex-col gap-3 px-4 pb-20 mt-2">
            <Button
              className="w-full"
              size="xl"
              variant="dark"
              onClick={handleContinue}
              disabled={
                isSubmittingProduct ||
                imageUploadProgress.isUploading ||
                (currentStep === 1 ? !isStep1Valid() : !isStep2Valid())
              }
            >
              {currentStep === 1
                ? "ادامه"
                : isEditMode
                  ? "به‌روزرسانی محصول"
                  : "ثبت محصول"}
            </Button>

            {/* Validation Messages */}
            {currentStep === 1 && !isStep1Valid() && (
              <div className="text-xs text-red-500 text-center space-y-1">
                {selectedImages.length === 0 && (
                  <div>•حداقل یک تصویر اضافه کنید</div>
                )}
                {!productTitle.trim() && <div>•عنوان محصول را وارد کنید</div>}
                {!productDescription.trim() && (
                  <div>•توضیحات محصول را وارد کنید</div>
                )}
                {!selectedCategory && (
                  <div>•دسته‌بندی محصول را انتخاب کنید</div>
                )}
                {productVariants.length === 0 && (
                  <div>•حداقل یک ویژگی اضافه کنید</div>
                )}
                {hasSizes && !isSizeChartComplete() && (
                  <div>•راهنمای سایز را برای همه سایزها کامل کنید</div>
                )}
              </div>
            )}

            {currentStep === 2 && !isStep2Valid() && (
              <div className="text-xs text-red-500 text-center">
                • لطفاً قیمت محصول را وارد کنید
              </div>
            )}
          </div>
        </>
      )}

      {/* Show a message when AI is generating */}
      {postId && isAI && isAiGenerating && (
        <div className="flex flex-col items-center justify-center p-8 mt-20">
          <Loader className="animate-spin mb-4" size={48} />
          <h2 className="text-lg font-bold mb-2">
            در حال ایجاد محصول با هوش مصنوعی
          </h2>
          <p className="text-BLACK2 text-center">
            لطفا صبر کنید تا محصول شما از روی پست اینستاگرام ایجاد شود...
          </p>
        </div>
      )}

      {postId && isAI && aiGenerationError && (
        <div className="flex flex-col items-center justify-center p-8 mt-20">
          <div className="text-red-500 mb-4">
            <X size={48} />
          </div>
          <h2 className="text-lg font-bold mb-2 text-red-600">
            خطا در ایجاد محصول
          </h2>
          <p className="text-BLACK2 text-center mb-4">
            متأسفانه نتوانستیم محصول را از روی پست اینستاگرام شما ایجاد کنیم
          </p>
          <Button
            onClick={() => safeGoBack(navigate)}
            variant="outline"
            className="mb-2"
          >
            بازگشت
          </Button>
        </div>
      )}

      {/* Image Editor */}
      <ImageEditor
        isOpen={isImageEditorOpen}
        onClose={() => setIsImageEditorOpen(false)}
        imageUrl={
          currentEditingIndex !== null
            ? selectedImages[currentEditingIndex]?.url || ""
            : ""
        }
        onSave={handleImageEditorSave}
      />

      {/* Image Upload Drawer */}
      <ImageUploadDrawer
        isOpen={isDrawerOpen}
        onOpenChange={setIsDrawerOpen}
        onCameraSelect={handleCameraSelect}
        onGallerySelect={handleGallerySelect}
      />

      {/* Loading Modals */}
      <LoadingModal
        open={imageUploadProgress.isUploading}
        setOpen={() => {}}
        title={`در حال آپلود ${imageUploadProgress.current}/${imageUploadProgress.total} عکس...`}
      />

      <LoadingModal
        open={isSubmittingProduct}
        setOpen={() => {}}
        title={
          isEditMode ? "در حال به‌روزرسانی محصول..." : "در حال ایجاد محصول..."
        }
      />

      <LoadingModal
        open={isLoadingPostData}
        setOpen={() => {}}
        title="در حال بارگذاری اطلاعات پست..."
      />
    </div>
  );
}

interface LoadingModalProps {
  open: boolean;
  setOpen: (open: boolean) => void;
  title?: string;
  description?: string;
}

export const LoadingModal = ({
  open,
  setOpen,
  title = "در حال بارگذاری...",
  description,
}: LoadingModalProps) => {
  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogOverlay className="bg-BLACK/50" />
      <DialogContent className="p-6 bg-WHITE rounded-[15px] w-[calc(100%-40px)] max-w-sm">
        <div className="flex flex-col items-center justify-center gap-4 py-4">
          <Loader className="animate-spin" />
          <p className="text-B14 font-bold text-center">لطفا منتظر بمانید...</p>
          <p className="text-R12 text-center">{title}</p>
          {description && <p className="text-R12 text-center">{description}</p>}
        </div>
      </DialogContent>
    </Dialog>
  );
};
