import { yupResolver } from "@hookform/resolvers/yup";
import { retrieveAllUserAPI } from "Src/services/userService";
import React from "react";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { ClipLoader } from "react-spinners";
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 } from "../utils/utils";
import CustomSelect from "Components/CustomSelect";
import CustomSelect2 from "Components/CustomSelect2";

const columns = [
  {
    header: "ID",
    accessor: "id",
  },
  {
    header: "First Name",
    accessor: "first_name",
  },
  {
    header: "Last Name",
    accessor: "last_name",
  },
  {
    header: "Company Name",
    accessor: "company_name",
  },
  {
    header: "Email",
    accessor: "email",
  },
  {
    header: "Role",
    accessor: "role",
  },
  {
    header: "Status",
    accessor: "status",
    mapping: ["Inactive", "Active", "Suspend"],
  },
];

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

  const [data, 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 [loading, setLoading] = React.useState(false);
  const navigate = useNavigate();

  const schema = yup.object({
    id: yup.string(),
    first_name: yup.string(),
    last_name: yup.string(),
    email: yup.string(),
    status: yup.string(),
    role: yup.string(),
  });

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

  const selectRole = ["admin", "member"];
  const selectStatus = [
    { key: "", value: "All" },
    { key: "0", value: "Inactive" },
    { key: "1", value: "Active" },
    { key: "2", value: "Suspend" },
  ];
  const roles = [
    { key: "", value: "member" },
    { key: "1", value: "manager" },
    { key: "2", value: "admin" },
    { key: "3", value: "client" },
  ];

  function updatePageSize(limit) {
    (async function () {
      setPageSize(limit);
      await getData(1, 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, filter) {
    setLoading(true);
    try {
      const result = await retrieveAllUserAPI(pageNum, limitNum, filter);

      if (!result.error) {
        setLoading(false);
        const { list, total, limit, num_pages, page } = result;
        console.log(result);
        setCurrentTableData(list);
        setPageSize(limit);
        setPageCount(num_pages);
        setPage(page);
        setDataTotal(total);
        setCanPreviousPage(page > 1);
        setCanNextPage(page + 1 <= num_pages);
      } else {
        setLoading(false);
        tokenExpireError(dispatch, result.message);
      }
    } catch (error) {
      setLoading(false);

      tokenExpireError(dispatch, error.message);
    }
  }

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

  const onSubmit = (data) => {
    const first_name = getNonNullValue(data.first_name);
    const last_name = getNonNullValue(data.last_name);
    const email = getNonNullValue(data.email);
    const status = getNonNullValue(data.status);
    const id = getNonNullValue(data.id);
    const company_name = getNonNullValue(data.company_name);
    const role = getNonNullValue(data.role);

    getData(1, pageSize, {
      first_name,
      last_name,
      email,
      status,
      id,
      company_name,
      role,
    });
  };

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

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

  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 dark:border-strokedark dark: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">
            Users
          </h4>
          <AddButton link="/admin/add-user" />
        </div>

        {/* Search/Filter Section */}
        <div className="mb-4 border-b border-strokedark px-4 py-4 sm:px-6 2xl:px-9 dark:border-strokedark">
          <div>
            <form onSubmit={handleSubmit(onSubmit)}>
              {/* First Row of Filters */}
              <div className="flex flex-wrap items-center gap-3">
                <div>
                  <label className="mb-1 block text-sm font-medium text-white">
                    ID
                  </label>
                  <input
                    type="text"
                    placeholder="ID"
                    {...register("id")}
                    className="m h-[36px] w-64 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 dark:focus:border-primary"
                  />
                </div>

                <div>
                  <label className="mb-1 block text-sm font-medium text-white">
                    First Name
                  </label>
                  <input
                    type="text"
                    placeholder="First Name"
                    {...register("first_name")}
                    className="m h-[36px] w-64 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 dark:focus:border-primary"
                  />
                </div>

                <div>
                  <label className="mb-1 block text-sm font-medium text-white">
                    Last Name
                  </label>
                  <input
                    type="text"
                    placeholder="Last Name"
                    {...register("last_name")}
                    className="m h-[36px] w-64 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 dark:focus:border-primary"
                  />
                </div>
              </div>

              {/* Second Row of Filters */}
              <div className="mt-3 flex flex-wrap items-center gap-3">
                <div>
                  <label className="mb-1 block text-sm font-medium text-white">
                    Email
                  </label>
                  <input
                    type="email"
                    placeholder="Email"
                    {...register("email")}
                    className="m h-[36px] w-64 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 dark:focus:border-primary"
                  />
                </div>

                <div>
                  <label className="mb-1 block text-sm font-medium text-white">
                    Status
                  </label>
                  <CustomSelect2
                    className="h-[36px] !w-64"
                    label="Select Status"
                    options={selectStatus.map((option) => ({
                      value: option.key,
                      label: option.value,
                    }))}
                    register={register}
                    name="status"
                  />
                </div>

                <div>
                  <label className="mb-1 block text-sm font-medium text-white">
                    Role
                  </label>
                  <CustomSelect2
                    className="h-[36px] !w-64"
                    label="Select Role"
                    options={roles.map((option) => ({
                      value: option.value,
                      label: option.value,
                    }))}
                    register={register}
                    name="role"
                  />
                </div>
              </div>

              {/* Action Buttons */}
              <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>
        </div>

        {/* Table Section */}
        <div>
          <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={`whitespace-nowrap px-3 py-3 text-left text-xs font-medium uppercase tracking-wider text-bodydark1 ${
                        i === 0 ? "xl:pl-6 2xl:pl-9" : ""
                      }`}
                    >
                      {column.header}
                      {column.isSorted && (
                        <span>{column.isSortedDesc ? " ▼" : " ▲"}</span>
                      )}
                    </th>
                  ))}
                </tr>
              </thead>

              {!loading && data.length > 0 ? (
                <tbody className="cursor-pointer text-white">
                  {data.map((row, i) => (
                    <tr
                      key={i}
                      onClick={() => {
                        navigate(`/admin/edit-user/${row.id}`, {
                          state: row,
                        });
                      }}
                      className="border-b border-strokedark hover:bg-primary/5"
                    >
                      {columns.map((cell, index) => (
                        <td
                          key={index}
                          className={`whitespace-nowrap px-3 py-4 ${
                            index === 0
                              ? "text-bodydark1 xl:pl-6 2xl:pl-9"
                              : "text-bodydark"
                          }`}
                        >
                          {cell.mapping
                            ? cell.mapping[row[cell.accessor]]
                            : row[cell.accessor]}
                        </td>
                      ))}
                    </tr>
                  ))}
                </tbody>
              ) : loading ? (
                <tbody>
                  <tr>
                    <td colSpan={columns.length} className="text-center">
                      <span className="trans relative top-[30px] m-4 animate-pulse whitespace-nowrap p-4 pb-8 text-xl font-semibold text-white ease-out">
                        <ClipLoader color="#fff" size={20} className="mr-3" />{" "}
                        Loading Users...
                      </span>
                    </td>
                  </tr>
                </tbody>
              ) : (
                <tbody>
                  <tr>
                    <td colSpan={columns.length} className="text-center">
                      <span className="relative top-[10px] m-4 p-4 font-semibold text-white">
                        No data found
                      </span>
                    </td>
                  </tr>
                </tbody>
              )}
            </table>
          </div>
        </div>

        {/* Pagination */}
        {data.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}
            />
          </div>
        )}
      </div>
    </div>
  );
};

export default AdminUserListPage;
