import { yupResolver } from "@hookform/resolvers/yup";
import FormMultiSelect from "Components/FormMultiSelect";
import React, { useRef } from "react";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { ClipLoader } from "react-spinners";
import { retrieveAllMixTypesAPI } from "Src/services/mixTypeServices";
import { retrieveAllUserAPI } from "Src/services/userService";
import * as yup from "yup";
import { AuthContext, tokenExpireError } from "../authContext";
import AddButton from "../components/AddButton";
import PaginationBar from "../components/PaginationBar";
import { GlobalContext } from "../globalContext";
import { getNonNullValue, removeKeysWhenValueIsNull } from "../utils/utils";
import CustomSelect2 from "Components/CustomSelect2";

const COLORS = [
  {
    id: 1,
    color: "#6CC551",
    name: "Green",
  },
  {
    id: 2,
    color: "#197BBD",
    name: "Blue",
  },
  {
    id: 3,
    color: "#F3A738",
    name: "Gold",
  },
  {
    id: 4,
    color: "#C0C0C0",
    name: "Gray",
  },
  {
    id: 5,
    color: "#8A2BE2",
    name: "Purple",
  },
  {
    id: 6,
    color: "#FF91AF",
    name: "Pink",
  },
  {
    id: 7,
    color: "#00FFFF",
    name: "Cyan",
  },
  {
    id: 8,
    color: "#B31B1B",
    name: "Red",
  },
  {
    id: 9,
    color: "#FF7F50",
    name: "Coral",
  },
];

const columns = [
  {
    header: "Name",
    accessor: "name",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },
  {
    header: "Producer",
    accessor: "member_name",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },
  {
    header: "Voiceover",
    accessor: "is_voiceover",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: true,
    mappings: {
      0: "No",
      1: "Yes",
    },
  },
  {
    header: "Voiceover Count",
    accessor: "voiceover",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },
  {
    header: "Song",
    accessor: "is_song",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: true,
    mappings: {
      0: "No",
      1: "Yes",
    },
  },
  {
    header: "Song Count",
    accessor: "song",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },
  {
    header: "Tracking",
    accessor: "is_tracking",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: true,
    mappings: {
      0: "No",
      1: "Yes",
    },
  },
  {
    header: "Tracking Count",
    accessor: "tracking",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },
  {
    header: "Color",
    accessor: "color",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },
  {
    header: "Price",
    accessor: "price",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },
];

const AdminListMixTypePage = () => {
  const { dispatch, state: authState } = React.useContext(AuthContext);
  const { dispatch: globalDispatch } = React.useContext(GlobalContext);

  const [currentTableData, setCurrentTableData] = React.useState([]);
  const [searchResult, setSearchResult] = React.useState([]);
  // const [pageSize, setPageSize] = React.useState(10);
  const [pageCount, setPageCount] = React.useState(0);
  const [dataTotal, setDataTotal] = React.useState(0);
  const [currentPage, setPage] = React.useState(0);
  const [canPreviousPage, setCanPreviousPage] = React.useState(false);
  const [canNextPage, setCanNextPage] = React.useState(false);
  const [loading, setLoading] = React.useState(true);

  // Check if pageSize exists in local storage
  const pageSizeFromLocalStorage = localStorage.getItem("mixTypePageSize");

  // Use a state variable to manage the pageSize
  const [pageSize, setPageSize] = React.useState(
    pageSizeFromLocalStorage ? Number(pageSizeFromLocalStorage) : 10 // Default pageSize
  );

  const [producersForSelect, setProducersForSelect] = React.useState([]);
  const [selectedProducers, setSelectedProducers] = React.useState([]);
  const [producersInitialized, setProducersInitialized] = React.useState(false);

  const navigate = useNavigate();

  const schema = yup.object({
    name: yup.string(),
    is_voiceover: yup.string(),
    is_song: yup.string(),
    price: yup.string(),
    voiceover: yup.string(),
    song: yup.string(),
  });
  const {
    register,
    handleSubmit,
    setError,
    reset,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  });

  const getAllProducers = async () => {
    try {
      const result = await retrieveAllUserAPI(1, 10000, { role: "member" });

      if (!result.error) {
        if (result.list.length > 0) {
          let list = result.list;

          list = list.map((row) => {
            row.user_name = row.first_name + " " + row.last_name;
            return { value: row.id, label: row.user_name };
          });

          let forSelect = [];
          if (list.length > 0) {
            list.map((row, i) => {
              forSelect.push({
                value: row.value,
                label: row?.label,
              });
            });
          }

          setProducersForSelect(forSelect);
        }
      }
    } catch (error) {
      tokenExpireError(dispatch, error.message);
    }
  };

  function onSort(columnIndex) {
    if (columns[columnIndex].isSorted) {
      columns[columnIndex].isSortedDesc = !columns[columnIndex].isSortedDesc;
    } else {
      columns.map((i) => (i.isSorted = false));
      columns.map((i) => (i.isSortedDesc = false));
      columns[columnIndex].isSorted = true;
    }

    (async function () {
      await getData(1, pageSize);
    })();
  }

  function updatePageSize(limit) {
    (async function () {
      setPageSize(limit);
      await getData(1, limit);
    })();
    localStorage.setItem("mixTypePageSize", limit);
  }

  function callDataAgain(page) {
    (async function () {
      // await getData(currentPage - 1 > 0 ? currentPage - 1 : 0, pageSize);
      await getData(
        page,
        pageSizeFromLocalStorage ? Number(pageSizeFromLocalStorage) : pageSize
      );
    })();
  }

  function previousPage() {
    (async function () {
      // await getData(currentPage - 1 > 0 ? currentPage - 1 : 0, pageSize);
      await getData(
        currentPage - 1,
        pageSizeFromLocalStorage ? Number(pageSizeFromLocalStorage) : pageSize
      );
    })();
  }

  function nextPage() {
    (async function () {
      // await getData(
      //   currentPage + 1 <= pageCount ? currentPage + 1 : 0,
      //   pageSize
      // );
      await getData(
        currentPage + 1,
        pageSizeFromLocalStorage ? Number(pageSizeFromLocalStorage) : pageSize
      );
    })();
  }

  async function getData(
    pageNum,
    limitNum,
    filter,
    selectedProd = selectedProducers
  ) {
    try {
      const result = await retrieveAllMixTypesAPI(
        pageNum,
        limitNum,
        removeKeysWhenValueIsNull({
          ...filter,
          user_id:
            selectedProd.length <= 0
              ? null
              : selectedProd.map((elem) => elem.value),
        })
      );
      const { list, total, limit, num_pages, page } = result;
      setCurrentTableData(list);
      setSearchResult(list);
      setPageSize(limit);
      setPageCount(num_pages);
      setPage(page);
      setDataTotal(total);
      setCanPreviousPage(page > 1);
      setCanNextPage(page + 1 <= num_pages);
      setLoading(false);
    } catch (error) {
      setLoading(false);
      tokenExpireError(dispatch, error.message);
    }
  }

  const handleSelectedProducers = async (names) => {
    if (names.length === 0) {
      setSelectedProducers([]);
      // localStorage.setItem('projectProducers', JSON.stringify(''));
      // setCachedProjectProducers([]);
    } else {
      setSelectedProducers(names);
      // localStorage.setItem('projectProducers', JSON.stringify(names));
      // setCachedProjectProducers(names);
    }

    // kks

    if (names?.length < selectedProducers.length) {
      await getData(1, pageSize, {}, []);
    }
  };

  const resetForm = async () => {
    reset();
    setSelectedProducers([]);
    await getData(1, pageSize, {}, []);
    localStorage.setItem("mixTypePageSize", 10);
    setPageSize(10);
  };

  const onSubmit = (_data) => {
    let name = getNonNullValue(_data.name);
    let is_voiceover = getNonNullValue(_data.is_voiceover);
    let is_song = getNonNullValue(_data.is_song);
    let is_tracking = getNonNullValue(_data.is_tracking);
    let color = getNonNullValue(_data.color);
    let price = getNonNullValue(_data.price);
    let filter = {
      name: name,
      is_voiceover: is_voiceover,
      is_song: is_song,
      is_tracking: is_tracking,
      color: color,
      price: price,
    };
    getData(1, pageSize, removeKeysWhenValueIsNull(filter));
  };

  const handleSearch = (e) => {
    // e.preventDefault();
    const keyword = e.target.value;
    if (keyword !== "") {
      const filterSearch = currentTableData.filter((item) => {
        return item.name.toLowerCase().includes(keyword.toLowerCase());
      });
      setSearchResult(filterSearch);
    } else {
      setSearchResult(currentTableData);
    }
  };

  React.useEffect(() => {
    globalDispatch({
      type: "SETPATH",
      payload: {
        path: "mix-types",
      },
    });

    const initProducers = async () => {
      try {
        await getAllProducers();
        setProducersInitialized(true);
      } catch (error) {
        tokenExpireError(dispatch, error.message);
      }
    };

    initProducers();
  }, []);

  React.useEffect(() => {
    if (producersInitialized) {
      const loadData = async () => {
        try {
          setLoading(true);
          const size = pageSizeFromLocalStorage
            ? Number(pageSizeFromLocalStorage)
            : pageSize;
          await getData(1, size);
        } catch (error) {
          tokenExpireError(dispatch, error.message);
        } finally {
          setLoading(false);
        }
      };

      loadData();
    }
  }, [producersInitialized]);

  const selectProducersRef = useRef(null);

  return (
    <div
      className="max-w-screen h-full p-4 md:p-4 lg:p-6 xl:p-8"
      id="mainContainer"
    >
      <div className="shadow-default rounded border border-strokedark bg-boxdark">
        {/* Header Section */}
        <div className="flex items-center justify-between border-b border-strokedark px-4 md:px-6 2xl:px-9">
          <h4 className="my-3 text-2xl font-semibold text-white dark:text-white">
            Mix Types
          </h4>
          <AddButton link={`/${authState.role}/add-mix-type`} />
        </div>

        {/* Search/Filter Section */}
        <div className="mb-4 border-b border-strokedark px-4 py-4 sm:px-6 2xl:px-9">
          <form onSubmit={handleSubmit(onSubmit)}>
            <div className="flex flex-wrap items-center gap-3">
              {/* Producer Filter */}
              <div className="w-64">
                <label
                  htmlFor="producers"
                  className="mb-2 block text-sm text-white"
                >
                  Producers
                </label>
                <FormMultiSelect
                  id="producers"
                  selectRef={selectProducersRef}
                  values={selectedProducers}
                  onValuesChange={handleSelectedProducers}
                  options={producersForSelect}
                  placeholder="Producers"
                />
              </div>

              {/* Name Filter */}
              <div className="w-64">
                <label htmlFor="name" className="mb-2 block text-sm text-white">
                  Name
                </label>
                <input
                  id="name"
                  type="text"
                  placeholder="Name"
                  {...register("name")}
                  className="h-[36px] w-full rounded border-[1.5px] border-form-strokedark bg-form-input px-3 py-2 text-sm outline-none transition placeholder:font-normal placeholder:text-bodydark focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter dark:border-form-strokedark dark:bg-form-input"
                />
              </div>

              {/* Voiceover Filter */}
              <div className="w-64">
                <label
                  htmlFor="is_voiceover"
                  className="mb-2 block text-sm text-white"
                >
                  Voiceover
                </label>
                <CustomSelect2
                  id="is_voiceover"
                  name="is_voiceover"
                  register={register}
                  label="Select Voiceover"
                  className="h-[36px] w-full rounded border-[1.5px] border-form-strokedark bg-form-input px-3 py-2 text-sm outline-none transition focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter dark:border-form-strokedark dark:bg-form-input"
                >
                  <option value="">Select Voiceover</option>
                  <option value="1">Yes</option>
                  <option value="0">No</option>
                </CustomSelect2>
              </div>

              {/* Song Filter */}
              <div className="w-64">
                <label
                  htmlFor="is_song"
                  className="mb-2 block text-sm text-white"
                >
                  Song
                </label>
                <CustomSelect2
                  id="is_song"
                  name="is_song"
                  register={register}
                  label="Select Song"
                  className="h-[36px] w-full rounded border-[1.5px] border-form-strokedark bg-form-input px-3 py-2 text-sm outline-none transition focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter dark:border-form-strokedark dark:bg-form-input"
                >
                  <option value="">Select Song</option>
                  <option value="1">Yes</option>
                  <option value="0">No</option>
                </CustomSelect2>
              </div>

              {/* Tracking Filter */}
              <div className="w-64">
                <label
                  htmlFor="is_tracking"
                  className="mb-2 block text-sm text-white"
                >
                  Tracking
                </label>
                <CustomSelect2
                  id="is_tracking"
                  name="is_tracking"
                  register={register}
                  label="Select Tracking"
                  className="h-[36px] w-full rounded border-[1.5px] border-form-strokedark bg-form-input px-3 py-2 text-sm outline-none transition focus:border-primary active:border-primary disabled:cursor-default disabled:bg-whiter dark:border-form-strokedark dark:bg-form-input"
                >
                  <option value="">Select Tracking</option>
                  <option value="1">Yes</option>
                  <option value="0">No</option>
                </CustomSelect2>
              </div>
            </div>

            <div className="mt-3 flex items-center gap-2">
              <button
                type="submit"
                className="inline-flex h-[36px] items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-white hover:bg-opacity-90"
              >
                Search
              </button>
              <button
                onClick={resetForm}
                type="button"
                className="inline-flex h-[36px] items-center justify-center rounded-md border border-strokedark bg-danger px-4 py-2 text-sm font-medium text-white hover:bg-opacity-90"
              >
                Reset
              </button>
            </div>
          </form>
        </div>

        {/* Table Section */}
        <div className="custom-overflow min-h-[150px] overflow-x-auto">
          <table className="w-full table-auto">
            <thead className="bg-meta-4">
              <tr>
                {columns.map((column, i) => (
                  <th
                    key={i}
                    className={`px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-white ${
                      i === 0 ? "xl:pl-6 2xl:pl-9" : ""
                    }`}
                  >
                    {column.header}
                    {column.isSorted && (
                      <span>{column.isSortedDesc ? " ▼" : " ▲"}</span>
                    )}
                  </th>
                ))}
              </tr>
            </thead>

            {loading && (
              <tbody>
                <tr>
                  <td colSpan={columns.length} className="text-center">
                    <div className="flex h-[100px] animate-pulse items-center justify-center text-white">
                      <ClipLoader color="#fff" size={20} className="mr-3" />
                      <span className="font-semibold">
                        Loading Mix Types...
                      </span>
                    </div>
                  </td>
                </tr>
              </tbody>
            )}

            {!loading && searchResult.length > 0 && (
              <tbody className="cursor-pointer text-white">
                {searchResult.map((row, i) => (
                  <tr
                    key={i}
                    className="border-b border-strokedark hover:bg-primary/5"
                  >
                    {columns.map((cell, index) => (
                      <td
                        key={index}
                        className={`whitespace-nowrap px-4 py-4 ${
                          index === 0 ? "xl:pl-6 2xl:pl-9" : ""
                        }`}
                      >
                        {cell.accessor === "color" ? (
                          <div className="flex items-center gap-3">
                            <div
                              className="h-6 w-6 rounded-full"
                              style={{
                                backgroundColor: COLORS.find(
                                  (color) => color.name === row[cell.accessor]
                                )?.color,
                              }}
                            ></div>
                            {COLORS.find(
                              (color) => color.name === row[cell.accessor]
                            )?.name || row[cell.accessor]}
                          </div>
                        ) : cell.mappingExist ? (
                          cell.mappings[row[cell.accessor]]
                        ) : (
                          row[cell.accessor]
                        )}
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            )}

            {!loading && searchResult.length === 0 && (
              <tbody>
                <tr>
                  <td colSpan={columns.length} className="text-center">
                    <div className="py-4">No data found</div>
                  </td>
                </tr>
              </tbody>
            )}
          </table>
        </div>

        {/* Pagination */}
        {searchResult.length > 0 && !loading && (
          <div className="w-full px-4 py-10 md:px-6 2xl:px-9">
            <PaginationBar
              currentPage={currentPage}
              pageCount={pageCount}
              pageSize={pageSize}
              canPreviousPage={canPreviousPage}
              canNextPage={canNextPage}
              updatePageSize={updatePageSize}
              previousPage={previousPage}
              nextPage={nextPage}
              dataTotal={dataTotal}
              callDataAgain={callDataAgain}
              setCurrentPage={setPage}
            />
          </div>
        )}
      </div>
    </div>
  );
};

export default AdminListMixTypePage;
