import Button from "@/components/Button";
import { extractErrorMessage } from "@/config/func";
import type { ErrorType } from "@/helpers/types";
import { useQueryClient } from "@tanstack/react-query";
import { useFormik } from "formik";
import { TickCircle } from "iconsax-react";
import { type FC, useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import * as Yup from "yup";
import { useMultipleUpload } from "../uploader/hooks/useUploaderData";
import BasicInfoSection from "./components/BasicInfoSection";
import CreateProductSidebar from "./components/CreateProductSidebar";
import { PaymentType, PricingType, PurchaseUnit } from "./enum/Enum";
import { useGetCategories, useGetProductDetails, useUpdateProduct } from "./hooks/useProductData";
import type { CreateProductType } from "./types/Types";
import { buildProductPayload } from "./utils/productPayload";

const UpdateProduct: FC = () => {
  const { id } = useParams<{ id: string }>();
  const queryClient = useQueryClient();
  const { data: productData, isLoading } = useGetProductDetails(id || "");
  const { data: categoriesData } = useGetCategories();
  const [isActive, setIsActive] = useState<boolean>(true);
  const [isSpecial, setIsSpecial] = useState<boolean>(false);
  const [imageFiles, setImageFiles] = useState<File[]>([]);
  const [existingImages, setExistingImages] = useState<string[]>([]);
  const { mutate: updateProduct, isPending } = useUpdateProduct();
  const { mutate: multipleUpload, isPending: isUploading } = useMultipleUpload();
  const navigate = useNavigate();
  const categories = categoriesData?.data ?? [];

  const product = productData?.data;
  const isSubmitting = isPending || isUploading;

  const formik = useFormik<CreateProductType>({
    initialValues: {
      categoryId: "",
      title: "",
      attribute: "",
      variants: [],
      desc: "",
      price: 0,
      isActive: true,
      images: [],
      discount: 0,
      isSpecialOffer: false,
      order: 0,
      stock: undefined,
      maxPurchaseQuantity: undefined,
      minPurchaseQuantity: undefined,
      purchasePitch: undefined,
      pricingType: PricingType.FIXED,
      paymentType: PaymentType.INSTANT,
      purchaseUnit: PurchaseUnit.NUMBER,
      needAdminAcceptance: false,
    },
    validationSchema: Yup.object().shape({
      title: Yup.string().required("نام کالا الزامی است"),
      categoryId: Yup.string().required("دسته‌بندی الزامی است"),
      price: Yup.number().required("قیمت الزامی است").min(0, "قیمت باید مثبت باشد"),
      discount: Yup.number().min(0, "تخفیف باید مثبت باشد"),
      attribute: Yup.string(),
      pricingType: Yup.string().required(),
      paymentType: Yup.string().required(),
      minPurchaseQuantity: Yup.number().when("pricingType", {
        is: PricingType.VARIABLE,
        then: (schema) => schema.required("حداقل مقدار الزامی است").positive("حداقل مقدار باید مثبت باشد"),
      }),
      maxPurchaseQuantity: Yup.number().required("حداکثر مقدار الزامی است").positive("حداکثر مقدار باید مثبت باشد"),
      purchasePitch: Yup.number().when("pricingType", {
        is: PricingType.VARIABLE,
        then: (schema) => schema.min(0, "گام تغییر باید مثبت باشد"),
      }),
      variants: Yup.array().of(
        Yup.object().shape({
          id: Yup.string(),
          value: Yup.string(),
          price: Yup.number().min(0),
        }),
      ),
    }),
    onSubmit: (values) => {
      if (!id) {
        toast.error("شناسه کالا یافت نشد");
        return;
      }

      const submitProduct = (newImageUrls: string[] = []) => {
        const allImages = [...values.images, ...newImageUrls];
        const productData = buildProductPayload({
          values,
          isActive,
          isSpecialOffer: isSpecial,
          images: allImages,
        });

        updateProduct(
          { id, params: productData },
          {
            onSuccess: () => {
              queryClient.invalidateQueries({ queryKey: ["product", id] });
              queryClient.invalidateQueries({ queryKey: ["products"] });
              toast.success("کالا با موفقیت به‌روزرسانی شد");
              navigate(-1);
            },
            onError: (error: ErrorType) => {
              toast.error(extractErrorMessage(error));
            },
          },
        );
      };

      if (imageFiles.length > 0) {
        multipleUpload(imageFiles, {
          onSuccess: (response) => {
            const imageUrls = response?.data?.map((item) => item.url) || [];
            submitProduct(imageUrls);
          },
          onError: (error: ErrorType) => {
            toast.error(extractErrorMessage(error, "خطا در آپلود تصاویر"));
          },
        });
      } else {
        submitProduct();
      }
    },
  });

  useEffect(() => {
    if (product) {
      const variants = product.variants || [];
      const priceFromVariant = variants.length > 0 ? variants[0].price : product.price;
      formik.setValues({
        categoryId: product.category?.id || "",
        title: product.title || "",
        attribute: product.attribute || "",
        variants,
        desc: product.desc || "",
        price: priceFromVariant ?? product.price ?? 0,
        isActive: product.isActive || false,
        images: product.images || [],
        discount: product.discount || 0,
        isSpecialOffer: product.isSpecialOffer || false,
        order: product.order ?? 0,
        stock: product.variants?.[0]?.stock,
        maxPurchaseQuantity: product.maxPurchaseQuantity,
        minPurchaseQuantity: product.minPurchaseQuantity,
        purchasePitch: product.purchasePitch,
        pricingType: product.pricingType ?? PricingType.FIXED,
        paymentType: product.paymentType ?? (product.needAdminAcceptance ? PaymentType.AFTER_PREPARATION : PaymentType.INSTANT),
        purchaseUnit: product.purchaseUnit ?? PurchaseUnit.NUMBER,
        needAdminAcceptance: product.needAdminAcceptance ?? false,
      });
      setIsActive(product.isActive || false);
      setIsSpecial(product.isSpecialOffer || false);
      setExistingImages(product.images || []);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [product]);

  useEffect(() => {
    formik.setFieldValue("images", existingImages);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [existingImages]);

  if (isLoading) {
    return (
      <div className="w-full mt-4 flex justify-center items-center">
        <div>در حال بارگذاری...</div>
      </div>
    );
  }

  if (!product) {
    return (
      <div className="w-full mt-4 flex justify-center items-center">
        <div>کالا یافت نشد</div>
      </div>
    );
  }

  return (
    <div className="w-full mt-4">
      <div className="flex flex-col sm:flex-row w-full justify-between items-start sm:items-center gap-4">
        <div className="text-lg font-light">ویرایش کالا</div>
        <div>
          <Button className="px-5 w-full sm:w-auto" onClick={() => formik.handleSubmit()} isloading={isSubmitting}>
            <div className="flex gap-2 items-center">
              <TickCircle className="size-5" color="white" />
              <div>ذخیره تغییرات</div>
            </div>
          </Button>
        </div>
      </div>

      <div className="flex flex-col lg:flex-row gap-6 mt-6">
        <div className="flex-1">
          <div className="bg-white py-6 sm:py-8 xl:px-10 px-4 rounded-3xl">
            <BasicInfoSection
              formik={formik}
              categories={categories}
              initialHasVariants={(product?.variants?.length ?? 0) > 1 || (product?.variants?.length === 1 && (product.variants[0].value ?? "") !== "")}
            />
          </div>
        </div>

        <div className="w-full lg:w-auto">
          <CreateProductSidebar
            isActive={isActive}
            isSpecial={isSpecial}
            onChangeActive={setIsActive}
            onChangeSpecial={setIsSpecial}
            onChangeImages={setImageFiles}
            existingImages={existingImages}
            onChangeExistingImages={setExistingImages}
          />
        </div>
      </div>
    </div>
  );
};

export default UpdateProduct;
