import React from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import MkdSDK from "@/utils/MkdSDK";
import { getNonNullValue } from "@/utils/utils";
import { PaginationBar } from "@/components/PaginationBar";
import { AuthContext, tokenExpireError } from "@/context/Auth";
import { GlobalContext } from "@/context/Global";
import { MkdGridCards } from "@/components/MkdGridView";
import { MkdInput } from "@/components/MkdInput";

let sdk = new MkdSDK();

const getType = (type) => {
  switch (type) {
    case "varchar":
      return "text";
    case "text":
      return "textarea";
    case "mediumtext":
      return "textarea";
    case "longtext":
      return "textarea";
    case "tinyint":
      return "number";
    case "int":
      return "number";
    case "bigint":
      return "number";
    case "float":
      return "number";
    case "double":
      return "number";
    case "image":
      return "image";
    case "file":
      return "file";
    case "date":
      return "date";
    case "datetime":
      return "datetime";
    default:
      return "text";
  }
};

const MkdGridView = ({
  columns = [],
  actions = { view: true, edit: true, delete: true },
  actionId = "id",
  tableRole = "admin",
  table = "user",
  tableSchema = [],
  hasFilter = true,
  schemaFields = [],
}) => {
  const { dispatch } = React.useContext(AuthContext);
  const [currentTableData, setCurrentTableData] = React.useState([]);
  const [pageSize, setPageSize] = React.useState(10);
  const [pageCount, setPageCount] = React.useState(0);
  const [currentPage, setPage] = React.useState(0);
  const [canPreviousPage, setCanPreviousPage] = React.useState(false);
  const [canNextPage, setCanNextPage] = React.useState(false);
  const [showDeleteModal, setShowDeleteModal] = React.useState(false);
  const [deleteLoading, setDeleteLoading] = React.useState(false);
  const [loading, setLoading] = React.useState(false);

  const schema = yup.object({});

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  });

  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(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
      );
    })();
  }

  async function getData(pageNum, limitNum, currentTableData) {
    try {
      setLoading(true);
      sdk.setTable(table);
      const result = await sdk.callRestAPI(
        {
          payload: {
            ...currentTableData,
          },
          page: pageNum,
          limit: limitNum,
        },
        "PAGINATE"
      );
      if (result) {
        setLoading(false);
      }
      const { list, limit, num_pages, page } = result;

      setCurrentTableData(list);
      setPageSize(limit);
      setPageCount(num_pages);
      setPage(page);
      setCanPreviousPage(page > 1);
      setCanNextPage(page + 1 <= num_pages);
      setLoading(false);
    } catch (error) {
      setLoading(false);
      tokenExpireError(dispatch, error.message);
    }
  }

  const deleteItem = async (id) => {
    try {
      setDeleteLoading(true);
      sdk.setTable(table);
      const result = await sdk.callRestAPI({ id }, "DELETE");
      if (!result?.error) {
        setCurrentTableData((list) =>
          list.filter((x) => Number(x.user_id) !== Number(id))
        );
        setDeleteLoading(false);
        setShowDeleteModal(false);
      }
    } catch (err) {
      setDeleteLoading(false);
      setShowDeleteModal(false);
      tokenExpireError(dispatch, err?.message);
      throw new Error(err);
    }
  };

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

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

  const onSubmit = (_data) => {
    let filter = {};
    for (const field of schemaFields) {
      const [key] = field.split(":");
      filter[key] = getNonNullValue(_data[key]);
    }
    getData(1, pageSize, filter);
  };

  React.useEffect(() => {

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

  return (
    <div className="w-full">
      {hasFilter ? (
        <form
          className="mb-10 rounded bg-white p-5 shadow"
          onSubmit={handleSubmit(onSubmit)}
        >
          <h4 className="text-2xl font-medium capitalize">{table} Search</h4>
          <div className="filter-form-holder mt-10 flex w-full flex-wrap gap-5">
            {tableSchema && tableSchema.length
              ? tableSchema
                .map((item, key) => {
                  if (item.is_filter) {
                    if (Object.keys(item.mapping).length) {
                      return (
                        <div key={key + 1} className="w-[25%_!important] ">
                          <MkdInput
                            className={``}
                            errors={errors}
                            label={item.name}
                            name={item.name}
                            placeholder={item.name}
                            type={`mapping`}
                            mapping={item.mapping}
                            options={[...Object.keys(item.mapping)]}
                            register={register}
                            page={``}
                          />
                        </div>
                      );
                    } else {
                      return (
                        <div key={key + 1} className="w-[25%_!important] ">
                          <MkdInput
                            className={``}
                            errors={errors}
                            label={item.name}
                            name={item.name}
                            placeholder={item.name}
                            type={getType(item.type)}
                            register={register}
                            page={``}
                          />
                        </div>
                      );
                    }
                  }
                })
                .filter(Boolean)
              : null}
          </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>
      ) : null}

      <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 capitalize">{table} Profile</h4>
          <div className="flex">
          </div>
        </div>
        <MkdGridCards
          table={table}
          columns={columns}
          actions={actions}
          loading={loading}
          actionId={actionId}
          tableRole={tableRole}
          deleteLoading={deleteLoading}
          showDeleteModal={showDeleteModal}
          currentTableData={currentTableData}
          onSort={onSort}
          getData={getData}
          deleteItem={deleteItem}
          setShowDeleteModal={setShowDeleteModal}
          setCurrentTableData={setCurrentTableData}
        />
      </div>
      <PaginationBar
        currentPage={currentPage}
        pageCount={pageCount}
        pageSize={pageSize}
        canPreviousPage={canPreviousPage}
        canNextPage={canNextPage}
        updatePageSize={updatePageSize}
        previousPage={previousPage}
        nextPage={nextPage}
      />
    </div>
  );
};

export default MkdGridView;
