"use client";

import React, { useEffect, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

import CustomInput from "@/components/ui/FormInput/CustomInput";
import { CustomDropZone, CustomToggle } from "@/components/ui/FormInput/Inputs";
import MultiSelect from "@/components/ui/FormInput/MultiSelectNew";
import { Button } from "@/components/ui/button";
import {
  addProductCollection,
  editProductCollection,
} from "@/Services/ProductCollections/ApiProductCollections";
import { getProducts } from "@/Services/Products/ApiProducts";
import DividerWithText from "@/components/ui/FormInput/DividerWithText";
import { getCategories } from "@/Services/Categories/ApiCategory";
import { Switch } from "@/components/ui/switch";
import AddMeta from "../Meta/AddMeta";
import { getMetas } from "@/Services/Meta/ApiMeta";
import { useModal } from "@/context/ModalProvider";
// import { buildCategoryLabels } from "../Products/AddProducts";

const schema = yup.object().shape({
  name: yup.string().required("Collection name is required"),
  url: yup.string().required("URL is required"),
  // url_target: yup.string().oneOf(["card", "button", "both"]).default("button"),
  url_target: yup.string().nullable(),
  page: yup.string().nullable(),
  description: yup.string().nullable(),
  // offers_percentage: yup.number().nullable(),
  offers_percentage: yup
    .number()
    .nullable()
    .transform((value, originalValue) => (originalValue === "" ? null : value)),
  ref_table: yup
    .string()
    .oneOf(["products", "categories"])
    .required("Ref table is required"),
  refids: yup
    .array()
    .min(1, "Collection is required")
    .required("collection is required"),
  image: yup.object({
    image: yup
      .array()
      .of(yup.mixed().required("Image is required"))
      .min(1, "Image is required")
      .required("Image is required"),
  }),
  show_button: yup.boolean().default(false),
  show_description: yup.boolean().default(false),
  show_offers: yup.boolean().default(false),
  status: yup.boolean().default(true),
});

const AddProductCollections = ({ type = "add", editData, onClose }) => {
  const queryClient = useQueryClient();
  const { openModal, closeModal } = useModal();

  const {
    control,
    handleSubmit,
    reset,
    setValue,
    watch,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
    defaultValues: {
      status: true,
      url_target: "button",
      show_button: false,
      show_description: false,
      show_offers: false,
      ref_table: type === "edit" ? editData.ref_table : "products",
    },
  });

  const nameWatch = watch("name");
  const refTableWatch = watch("ref_table");
  useEffect(() => {
    setValue("refids", []);
  }, [refTableWatch]);

  useEffect(() => {
    if (editData && editData?.url) {
      setValue("url", editData.url);
    }
  }, [editData]);

  useEffect(() => {
    if (nameWatch !== editData?.name) {
      const formattedName = nameWatch
        ?.trim()
        .replace(/[^a-zA-Z0-9 ]/g, "")
        .replace(/\s+/g, "-")
        .toLowerCase();

      setValue("url", formattedName);
    }
  }, [nameWatch, editData]);

  const [imageFile, setImageFile] = useState({
    image: editData?.image ? [editData.image] : [],
  });

  useEffect(() => {
    setValue("image", imageFile);
  }, [imageFile, setValue]);

  useEffect(() => {
    if (type === "edit" && editData) {
      Object.keys(editData).forEach((key) => {
        if (key === "visibility" && typeof editData.visibility === "object") {
          const visibility = editData?.visibility;
          Object?.keys(visibility)?.forEach((vKey) => {
            setValue(vKey, visibility[vKey] ? true : false);
          });
        } else {
          setValue(key, editData[key]);
        }
      });

      if (editData.image) {
        setImageFile({ image: [editData.image] });
      }
    }
  }, [type, editData, setValue]);

  const { data: products = [] } = useQuery({
    queryKey: ["products"],
    queryFn: getProducts,
  });
  const { data: categories = [] } = useQuery({
    queryKey: ["categories"],
    queryFn: () => getCategories(0, 10, false, true),
  });
  // const flattenCategory = buildCategoryLabels(categories?.rows || []);

  const addMutation = useMutation({
    mutationFn: addProductCollection,
    onSuccess: () => {
      queryClient.invalidateQueries("product_collections");
      reset();
      setImageFile({ image: [] });
      onClose?.();
    },
  });

  const editMutation = useMutation({
    mutationFn: (data) => editProductCollection(data, editData.id),
    onSuccess: () => {
      queryClient.invalidateQueries("product_collections");
      reset();
      setImageFile({ image: [] });
      onClose?.();
    },
  });

  const submitHandler = async (data) => {
    const formData = new FormData();
    formData.append("folder", "product_collections");

    Object.entries(data).forEach(([key, value]) => {
      if (key === "image") {
        if (value?.image?.[0]) {
          formData.append("image", value.image[0]);
        } else {
          formData.append("image", JSON.stringify({ image: [] }));
        }
      } else if (["refids"].includes(key)) {
        formData.append(key, JSON.stringify(value));
      } else {
        formData.append(key, value);
      }
    });

    const wantsMeta = window.confirm(
      "Do you want to add meta tags for this collection?"
    );
    if (wantsMeta) {
      let metaEditData = type === "edit" ? { ...editData } : {};

      if (type === "edit") {
        try {
          const meta = await getMetas(0, 1, {
            reference_type: "collection",
            reference_id: editData.url || data.url,
          });

          if (meta?.rows?.[0]) {
            metaEditData = {
              ...metaEditData,
              metas: meta.rows[0].metas,
            };
          }
        } catch (err) {
          console.error("Failed to fetch meta for collection:", err);
        }
      }

      openModal(
        <AddMeta
          parent
          editData={metaEditData}
          onClose={closeModal}
          type={type}
          onSubmit={(metaFormData) => {
            for (let [key, value] of metaFormData.entries()) {
              formData.append(key, value);
            }

            if (type === "add") {
              addMutation.mutate(formData);
            } else {
              formData.append("id", editData.id);
              editMutation.mutate(formData);
            }

            closeModal();
          }}
        />
      );
    } else {
      if (type === "add") {
        addMutation.mutate(formData);
      } else {
        formData.append("id", editData.id);
        editMutation.mutate(formData);
      }
    }
  };

  return (
    <div className="bg-white pt-0 w-full border border-gray-200 rounded-md ">
      <div className="flex justify-between items-center border-b p-4 bg-brand-dark/5">
        <h2 className="text-xl font-semibold text-brand-dark">
          {type === "add" ? "Add" : "Edit"} Collection
        </h2>
        <Controller
          control={control}
          name="status"
          render={({ field }) => (
            <div className="flex items-center space-x-2">
              <label className="text-sm">Active</label>
              <Switch checked={field.value} onCheckedChange={field.onChange} />
            </div>
          )}
        />
      </div>

      <form onSubmit={handleSubmit(submitHandler)} className="p-6 space-y-6">
        <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
          <Controller
            name="name"
            control={control}
            render={({ field }) => (
              <CustomInput
                {...field}
                label="Collection Name"
                placeholder="Enter collection name"
                errors={errors}
                required
              />
            )}
          />

          <Controller
            name="url_target"
            control={control}
            render={({ field }) => (
              <MultiSelect
                {...field}
                label="URL Target"
                options={[
                  { label: "Card", value: "card" },
                  { label: "Button", value: "button" },
                  { label: "Both", value: "both" },
                ]}
                errors={errors}
                required
                labelComponent={
                  <CustomToggle
                    className="justify-between"
                    options={[{ name: "show_button", label: "Show Button" }]}
                    control={control}
                    errors={errors}
                    showLabel={false}
                    showTooltip
                  />
                }
              />
            )}
          />

          <CustomDropZone
            name="image"
            label="Collection Image"
            number_of_images={1}
            errors={errors.image}
            fileType={"image"}
            image_size={1024 * 1024 * 2}
            uploadedFiles={imageFile}
            setUploadedFiles={setImageFile}
            showIcon={false}
            required
          />

          <Controller
            name="description"
            control={control}
            render={({ field }) => (
              <CustomInput
                {...field}
                label="Description"
                type="text"
                placeholder="Enter a brief description"
                errors={errors}
                labelComponent={
                  <CustomToggle
                    options={[
                      {
                        name: "show_description",
                        label: "Show Description",
                      },
                    ]}
                    control={control}
                    errors={errors}
                    showTooltip
                    showLabel={false}
                  />
                }
              />
            )}
          />
          <Controller
            name="offers_percentage"
            control={control}
            render={({ field }) => (
              <CustomInput
                {...field}
                label="Offers %"
                min={0}
                max={100}
                type="number"
                placeholder="Eg: 10"
                errors={errors}
                labelComponent={
                  <CustomToggle
                    options={[{ name: "show_offers", label: "Show Offers" }]}
                    control={control}
                    errors={errors}
                    showTooltip
                    showLabel={false}
                  />
                }
              />
            )}
          />

          <DividerWithText
            text="Collections Details"
            className="col-span-full"
            showLines
            textClassName="text-brand-dark"
            position="start"
            lineColor="border-brand-dark"
          />
          <Controller
            name="ref_table"
            control={control}
            defaultValue="products"
            render={({ field }) => (
              <MultiSelect
                {...field}
                label="Link Products/Categories"
                options={[
                  { label: "Products", value: "products" },
                  { label: "Categories", value: "categories" },
                ]}
                isMulti={false}
                errors={errors}
                required
              />
            )}
          />
        </div>

        <Controller
          name="refids"
          control={control}
          render={({ field }) => {
            const options =
              refTableWatch === "products"
                ? products?.rows?.map((p) => ({
                    label: p.name,
                    // value: p.id.toString(),
                    value: p.id,
                  }))
                : categories?.rows?.map((c) => ({
                    label: c.category_name,
                    value: c.id,
                  }));

            return (
              <MultiSelect
                {...field}
                label={`Select ${refTableWatch === "products" ? "Products" : "Categories"}`}
                options={options}
                isMulti
                isSearchable
                selectable
                showClearAll
                errors={errors}
                required
              />
            );
          }}
        />

        <div className="flex justify-end gap-2 pt-4">
          <Button onClick={() => reset()} type="reset" className="bg-red-700">
            Reset
          </Button>
          <Button type="submit" variant="dark">
            Save
          </Button>
        </div>
      </form>
    </div>
  );
};

export default AddProductCollections;
