import React, { useState } from "react";
import { AuthContext, tokenExpireError } from "@/context/Auth";
import MkdSDK from "@/utils/MkdSDK";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { GlobalContext } from "@/context/Global";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import { getNonNullValue } from "@/utils/utils";
import { PaginationBar } from "@/components/PaginationBar";
import { MkdButton } from "@/components/MkdButton";
import { ExportButton } from "@/components/ExportButton";
import { BiFilterAlt, BiSearch } from "react-icons/bi";
import { AiOutlineClose, AiOutlinePlus } from "react-icons/ai";
import { RiDeleteBin5Line } from "react-icons/ri";
import { ModalSidebar } from "@/components/ModalSidebar";
import AddSettingPage from "../Add/AddAdminSettingTablePage";
import SkeletonLoader from "@/components/Skeleton/Skeleton";

let sdk = new MkdSDK();

const columns = [
  {
    header: "Action",
    accessor: "",
  },

  {
    header: "Setting Key",
    accessor: "setting_key",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },

  {
    header: "Setting Value",
    accessor: "setting_value",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },

  {
    header: "Create At",
    accessor: "create_at",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },

  {
    header: "Update At",
    accessor: "update_at",
    isSorted: false,
    isSortedDesc: false,
    mappingExist: false,
    mappings: {},
  },
];

const SettingListPage = () => {
  const { dispatch } = React.useContext(AuthContext);
  const { dispatch: globalDispatch } = React.useContext(GlobalContext);

  const [query, setQuery] = React.useState("");
  const [currentTableData, setCurrentTableData] = 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 [showAddSidebar, setShowAddSidebar] = React.useState(false);
  const [openFilter, setOpenFilter] = React.useState(false);
  const [showFilterOptions, setShowFilterOptions] = React.useState(false);
  const [selectedOptions, setSelectedOptions] = React.useState([]);
  const [filterConditions, setFilterConditions] = React.useState([]);
  const [searchValue, setSearchValue] = React.useState("");
  const [optionValue, setOptionValue] = React.useState("eq");
  const navigate = useNavigate();
  const [loading, setLoading] = useState(true);

  const schema = yup.object({
    setting_key: yup.string(),
    setting_value: yup.string(),
    create_at: yup.string(),
    update_at: yup.string(),
  });
  const {
    register,
    handleSubmit,
    setError,
    reset,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  });

  function onSort(columnIndex) {
    console.log(columns[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(0, pageSize);
    })();
  }

  function updatePageSize(limit) {
    (async function () {
      setPageSize(limit);
      await getData(0, limit);
    })();
  }

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

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

  const addFilterCondition = (option, selectedValue, inputValue) => {
    const input =
      selectedValue === "eq" && isNaN(inputValue)
        ? `"${inputValue}"`
        : inputValue;
    const condition = `${option},${selectedValue},${input}`;
    setFilterConditions((prevConditions) => {
      const newConditions = prevConditions.filter(
        (condition) => !condition.includes(option)
      );
      return [...newConditions, condition];
    });
    setSearchValue(inputValue);
  };

  async function getData(pageNum, limitNum, currentTableData) {
    try {
      setLoading(true);
      sdk.setTable("setting");
      let sortField = columns.filter((col) => col.isSorted);
      const result = await sdk.callRestAPI(
        {
          payload: { ...currentTableData },
          page: pageNum,
          limit: limitNum,
          sortId: sortField.length ? sortField[0].accessor : "",
          direction: sortField.length
            ? sortField[0].isSortedDesc
              ? "DESC"
              : "ASC"
            : "",
        },
        "PAGINATE"
      );

      const { list, total, limit, num_pages, page } = result;

      setCurrentTableData(list);
      setPageSize(limit);
      setPageCount(num_pages);
      setPage(page);
      setDataTotal(total);
      setCanPreviousPage(page > 1);
      setCanNextPage(page + 1 <= num_pages);
      setLoading(false);
    } catch (error) {
      setLoading(false);

      console.log("ERROR", error);
      tokenExpireError(dispatch, error.message);
    }
  }

  const deleteItem = async (id) => {
    try {
      sdk.setTable("setting");
      const result = await sdk.callRestAPI({ id }, "DELETE");
      setCurrentTableData((list) =>
        list.filter((x) => Number(x.id) !== Number(id))
      );
    } catch (err) {
      throw new Error(err);
    }
  };

  const exportTable = async (id) => {
    try {
      sdk.setTable("notes");
      const result = await sdk.exportCSV();
    } catch (err) {
      throw new Error(err);
    }
  };

  const resetForm = async () => {
    reset();
    await getData(0, pageSize);
  };

  const onSubmit = (_data) => {
    let setting_key = getNonNullValue(_data.setting_key);
    let setting_value = getNonNullValue(_data.setting_value);
    let create_at = getNonNullValue(_data.create_at);
    let update_at = getNonNullValue(_data.update_at);
    let filter = {
      id,

      setting_key: setting_key,
      setting_value: setting_value,
      create_at: create_at,
      update_at: update_at,
    };
    getData(1, pageSize, filter);
  };

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

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

  return (
    <div className="px-8">
      {loading ? (
        <SkeletonLoader />
      ) : (
        <>
          {" "}
          {/* <form
            className="mb-10 rounded bg-white p-5 shadow"
            onSubmit={handleSubmit(onSubmit)}
          >
            <h4 className="text-2xl font-medium">Setting Search</h4>
            <div className="filter-form-holder mt-10 flex flex-wrap">
              <div className="mb-4 w-full pl-2 pr-2 md:w-1/2 ">
                <label
                  className="mb-2 block text-sm font-bold text-gray-700"
                  htmlFor="setting_key"
                >
                  Setting Key
                </label>
                <input
                  placeholder="Setting Key"
                  {...register("setting_key")}
                  className={`focus:shadow-outline w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow focus:outline-none ${errors.setting_key?.message ? "border-red-500" : ""
                    }`}
                />
                <p className="text-xs italic text-red-500">
                  {errors.setting_key?.message}
                </p>
              </div>

              <div className="mb-4 w-full pl-2 pr-2 md:w-1/2 ">
                <label
                  className="mb-2 block text-sm font-bold text-gray-700"
                  htmlFor="setting_value"
                >
                  Setting Value
                </label>
                <textarea
                  placeholder="Setting Value"
                  {...register("setting_value")}
                  className={`focus:shadow-outline w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow focus:outline-none ${errors.setting_value?.message ? "border-red-500" : ""
                    }`}
                  row={15}
                ></textarea>
                <p className="text-xs italic text-red-500">
                  {errors.setting_value?.message}
                </p>
              </div>

              <div className="mb-4 w-full pl-2 pr-2 md:w-1/2 ">
                <label
                  className="mb-2 block text-sm font-bold text-gray-700"
                  htmlFor="create_at"
                >
                  Create At
                </label>
                <input
                  type="date"
                  placeholder="Create At"
                  {...register("create_at")}
                  className={`focus:shadow-outline w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow focus:outline-none ${errors.create_at?.message ? "border-red-500" : ""
                    }`}
                />
                <p className="text-xs italic text-red-500">
                  {errors.create_at?.message}
                </p>
              </div>

              <div className="mb-4 w-full pl-2 pr-2 md:w-1/2 ">
                <label
                  className="mb-2 block text-sm font-bold text-gray-700"
                  htmlFor="update_at"
                >
                  Update At
                </label>
                <input
                  type="datetime-local"
                  placeholder="Update At"
                  {...register("update_at")}
                  className={`focus:shadow-outline w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow focus:outline-none ${errors.update_at?.message ? "border-red-500" : ""
                    }`}
                />
                <p className="text-xs italic text-red-500">
                  {errors.update_at?.message}
                </p>
              </div>
            </div>
            <button
              type="submit"
              className=" focus:shadow-outline ml-2 inline rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-700 focus:outline-none"
            >
              Search
            </button>

            <button
              onClick={() => {
                resetForm();
              }}
              type="button"
              className=" focus:shadow-outline ml-2 inline rounded bg-red-500 px-4 py-2 font-bold text-white hover:bg-red-700 focus:outline-none"
            >
              Clear
            </button>
          </form> */}
          <div className="flex items-center justify-between py-3">
            <form
              className="relative rounded bg-white"
              onSubmit={handleSubmit(onSubmit)}
            >
              <div className="flex items-center gap-4 text-gray-700">
                <div
                  className="flex cursor-pointer items-center justify-between gap-3 rounded-md border border-gray-200 px-3 py-1"
                  onClick={() => setOpenFilter(!openFilter)}
                >
                  <BiFilterAlt />
                  <span>Filters</span>
                  {selectedOptions.length > 0 && (
                    <span className="flex h-6 w-6 items-center justify-center rounded-full bg-gray-800 text-start  text-white">
                      {selectedOptions.length > 0
                        ? selectedOptions.length
                        : null}
                    </span>
                  )}
                </div>
                <div className=" flex cursor-pointer items-center justify-between gap-3 rounded-md border border-gray-200 px-2 py-1 focus-within:border-gray-400">
                  <BiSearch className="text-xl text-gray-200" />
                  <input
                    type="text"
                    placeholder="search..."
                    className="border-none p-0 placeholder:text-left  focus:outline-none"
                    style={{ boxShadow: "0 0 transparent" }}
                    onInput={(e) =>
                      addFilterCondition("name", "cs", e.target?.value)
                    }
                  />
                  <AiOutlineClose className="text-lg text-gray-200" />
                </div>
              </div>
              {openFilter && (
                <div className="top-fill filter-form-holder absolute left-0  z-20 mt-4 min-w-[70%] rounded-md border border-gray-200 bg-white p-5 shadow-xl">
                  {selectedOptions?.map((option, index) => (
                    <div
                      key={index}
                      className="mb-2 flex w-full items-center justify-between gap-3 text-gray-600"
                    >
                      <div className=" mb-3  w-1/3 rounded-md border border-gray-300 px-3 py-2 leading-tight text-gray-700 outline-none">
                        {option}
                      </div>
                      <select
                        className="w-[30%] appearance-none border-none outline-0"
                        onChange={(e) => {
                          setOptionValue(e.target.value);
                        }}
                      >
                        <option value="eq" selected>
                          equals
                        </option>
                        <option value="cs">contains</option>
                        <option value="sw">start with</option>
                        <option value="ew">ends with</option>
                        <option value="lt">lower than</option>
                        <option value="le">lower or equal</option>
                        <option value="ge">greater or equal</option>
                        <option value="gt">greater than</option>
                        <option value="bt">between</option>
                        <option value="in">in</option>
                        <option value="is">is null</option>
                      </select>

                      <input
                        type="text"
                        placeholder="Enter value..."
                        className=" mb-3 w-1/3 rounded-md border px-3 py-2 leading-tight text-gray-700 outline-none"
                        onChange={(e) =>
                          addFilterCondition(
                            option,
                            optionValue,
                            e.target.value
                          )
                        }
                      />

                      <RiDeleteBin5Line
                        className=" cursor-pointer text-2xl"
                        onClick={() => {
                          setSelectedOptions((prevOptions) =>
                            prevOptions.filter((op) => op !== option)
                          );
                          setFilterConditions((prevConditions) => {
                            return prevConditions.filter(
                              (condition) => !condition.includes(option)
                            );
                          });
                        }}
                      />
                    </div>
                  ))}

                  <div className="search-buttons relative flex items-center justify-between font-semibold">
                    <div
                      // type="submit"
                      className="mr-2 flex w-auto cursor-pointer items-center gap-2 rounded bg-gray-100 px-4 py-2.5 font-medium leading-tight text-gray-600 transition duration-150 ease-in-out "
                      onClick={() => {
                        setShowFilterOptions(!showFilterOptions);
                      }}
                    >
                      <AiOutlinePlus />
                      Add filter
                    </div>

                    {showFilterOptions && (
                      <div className="absolute top-11 z-10 bg-white px-5 py-3 text-gray-600 shadow-md">
                        <ul className="flex flex-col gap-2 text-gray-500">
                          {columns.slice(0, -1).map((column) => (
                            <li
                              key={column.header}
                              className={`${
                                selectedOptions.includes(column.header)
                                  ? "cursor-not-allowed text-gray-400"
                                  : "cursor-pointer"
                              }`}
                              onClick={() => {
                                if (!selectedOptions.includes(column.header)) {
                                  setSelectedOptions((prev) => [
                                    ...prev,
                                    column.header,
                                  ]);
                                }
                                setShowFilterOptions(false);
                              }}
                            >
                              {column.header}
                            </li>
                          ))}
                        </ul>
                      </div>
                    )}
                    {selectedOptions.length > 0 && (
                      <div
                        // type="reset"
                        onClick={() => {
                          setSelectedOptions([]);
                          setFilterConditions([]);
                        }}
                        className="inline-block cursor-pointer  rounded px-6  py-2.5 font-medium leading-tight text-gray-600  transition duration-150 ease-in-out"
                      >
                        Clear all filter
                      </div>
                    )}
                  </div>
                </div>
              )}
            </form>
            <div className="flex">
              <MkdButton onClick={() => setShowAddSidebar(true)} />
              <ExportButton onClick={exportTable} className="mx-1" />
            </div>
          </div>
          <div className="overflow-x-auto  rounded bg-white p-5 shadow">
            {/* <div className="mb-3 flex w-full justify-between text-center  ">
              <h4 className="text-2xl font-medium">Setting</h4>
              <div className="flex">
                <MkdButton onClick={() => setShowAddSidebar(true)} />
                <ExportButton onClick={exportTable} className="mx-1" />
              </div>
            </div> */}
            <div className="overflow-x-auto border-b border-gray-200 shadow ">
              <table className="min-w-full divide-y divide-gray-200">
                <thead className="bg-gray-50">
                  <tr>
                    {columns.map((column, i) => (
                      <th
                        key={i}
                        scope="col"
                        className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500"
                        onClick={() => onSort(i)}
                      >
                        {column.header}
                        <span>
                          {column.isSorted
                            ? column.isSortedDesc
                              ? " ▼"
                              : " ▲"
                            : ""}
                        </span>
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody className="divide-y divide-gray-200 bg-white">
                  {currentTableData.map((row, i) => {
                    return (
                      <tr key={i}>
                        {columns.map((cell, index) => {
                          if (cell.accessor.indexOf("image") > -1) {
                            return (
                              <td
                                key={index}
                                className="whitespace-nowrap px-6 py-4"
                              >
                                <img
                                  src={row[cell.accessor]}
                                  className="h-[100px] w-[150px]"
                                />
                              </td>
                            );
                          }
                          if (
                            cell.accessor.indexOf("pdf") > -1 ||
                            cell.accessor.indexOf("doc") > -1 ||
                            cell.accessor.indexOf("file") > -1 ||
                            cell.accessor.indexOf("video") > -1
                          ) {
                            return (
                              <td
                                key={index}
                                className="whitespace-nowrap px-6 py-4"
                              >
                                <a
                                  className="text-blue-500"
                                  target="_blank"
                                  href={row[cell.accessor]}
                                >
                                  {" "}
                                  View
                                </a>
                              </td>
                            );
                          }
                          if (cell.accessor == "") {
                            return (
                              <td
                                key={index}
                                className="whitespace-nowrap px-6 py-4"
                              >
                                <button
                                  className="text-xs"
                                  onClick={() => {
                                    navigate("/admin/edit-setting/" + row.id, {
                                      state: row,
                                    });
                                  }}
                                >
                                  {" "}
                                  Edit
                                </button>
                                <button
                                  className="px-1 text-xs text-blue-500"
                                  onClick={() => {
                                    navigate("/admin/view-setting/" + row.id, {
                                      state: row,
                                    });
                                  }}
                                >
                                  {" "}
                                  View
                                </button>
                                <button
                                  className="px-1 text-xs text-red-500"
                                  onClick={() => deleteItem(row.id)}
                                >
                                  {" "}
                                  Delete
                                </button>
                              </td>
                            );
                          }
                          if (cell.mappingExist) {
                            return (
                              <td
                                key={index}
                                className="whitespace-nowrap px-6 py-4"
                              >
                                {cell.mappings[row[cell.accessor]]}
                              </td>
                            );
                          }
                          return (
                            <td
                              key={index}
                              className="whitespace-nowrap px-6 py-4"
                            >
                              {row[cell.accessor]}
                            </td>
                          );
                        })}
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>
          <PaginationBar
            currentPage={currentPage}
            pageCount={pageCount}
            pageSize={pageSize}
            canPreviousPage={canPreviousPage}
            canNextPage={canNextPage}
            updatePageSize={updatePageSize}
            previousPage={previousPage}
            nextPage={nextPage}
          />{" "}
        </>
      )}
      <ModalSidebar
        isModalActive={showAddSidebar}
        closeModalFn={() => setShowAddSidebar(false)}
      >
        <AddSettingPage setSidebar={setShowAddSidebar} />
      </ModalSidebar>
    </div>
  );
};

export default SettingListPage;
