"use client";
import { groupBy } from "@/utils/lib/helpers";
import { useMutation, useQuery } from "@tanstack/react-query";
import axios from "axios";
import { Alert, Checkbox, Label, Spinner } from "flowbite-react";
import { FC, useEffect, useRef, useState } from "react";
import { HiInformationCircle } from "react-icons/hi";
import { toast } from "react-toastify";
import ActionButton from "../action-button";
import RolesList from "./roles";
import { FormProvider, useForm } from "react-hook-form";

type RolePermission = {
  role_id?: string | null;
  resellerPermissions?: [];
  user_type?: string;
};

const PermissionList: FC<RolePermission> = ({
  role_id,
  resellerPermissions = [],
  user_type = "reseller",
}) => {
  const [usePermission, setusePermission] = useState(resellerPermissions);

  const permissionForm = useForm<any>({
    mode: "onChange",
    defaultValues: {},
  });
  const checkboxes = useRef<any>([]);
  const [formState, setFormState] = useState({
    role_id: "",
    permission: [],
  });
  useEffect(() => {
    setFormState((prev: any) => {
      return {
        ...prev,
        role_id: role_id,
      };
    });
  }, [role_id]);
  const getPermissions = async () => {
    const { data } = await axios.get(`/api/permissions`);
    console.log(data);
    return data?.data;
  };

  const {
    data: permissions,
    isLoading,
    isError: isPermissionsError,
    error: permissionError = {} as any,
  } = useQuery({
    queryKey: ["permissions"],
    queryFn: () => getPermissions(),
    retry: 0,
  });

  const {
    mutate: updatePermission,
  } = useMutation({
    mutationFn: async (params: any) => {
      const { action } = params;
      const { data } = await axios.post(
        `/api/role-permission?action=${action}`,
        formState
      );
      setusePermission(data?.data);
      return data?.data;
    },
    onSuccess: () => {
      toast.success(`Permission update successfully!`);
    },
    onError: (error: any) => {
      if (error?.response?.data?.error?.message) {
        toast.error(error?.response?.data?.error?.message);
      } else {
        toast.error(`Unable to update permission`);
      }
    },
  });

  const updatePermissionGroup = (
    group_name: string,
    permissions: [],
    isChecked: boolean,
    callback: Function
  ) => {
    for (let i = 0; i < permissions?.length; i++) {
      checkboxes.current[group_name + i].checked = isChecked;
    }
    const selectedPermissions = permissions?.map((item: any) => item.name);
    return callback(selectedPermissions);
  };

  const handleChange = (e: any) => {
    setFormState((prev) => {
      return {
        ...prev,
        [e.target.name]: e.target.value,
      };
    });
  };

  if (isLoading) {
    return (
      <div className="text-center">
        <Spinner
          aria-label="Center-aligned spinner example"
          className="mt-20"
          size="xl"
        />
      </div>
    );
  }
  if (isPermissionsError) {
    return (
      <Alert color="failure" icon={HiInformationCircle}>
        <span className="mr-2 font-medium">Info alert!</span>
        {permissionError?.response?.data?.error?.message}
      </Alert>
    );
  }
  const permission_group = groupBy(
    permissions,
    (permission: any) => permission.name.split(".")[0]
  );
  const groupChecked = (permissions: []): boolean => {
    let groups = permissions.map((item: any) => item.name);
    return groups?.every((permission) =>
      usePermission?.includes(permission as never)
    );
  };
  return (
    <>
      <div className="role-permissions p-5">
        {role_id && (
          <div className="flex justify-end my-4 mr-4">
            <ActionButton type="back" href={`/${user_type}s`} />
          </div>
        )}

        <FormProvider {...permissionForm}>
          <form>
            {!role_id && (
              <RolesList
                setusePermission={setusePermission}
                setFormState={setFormState}
              />
            )}

            <div
              className="grid grid-cols-1 gap-3 p-5 relative md:grid-cols-3 lg:grid-cols-3"
              id="checkbox"
            >
              {Object.keys(permission_group)?.map(
                (permission_group_name: any, group_index: number) => (
                  <div
                    key={group_index}
                    className={`mb-3  ${permission_group_name} border dark:border-gray-700 p-3 relative`}
                  >
                    <div className="absolute -top-3 -left-1 bg-gray-50 cursor-pointer dark:bg-gray-900">
                      <Checkbox
                        checked={groupChecked(
                          permission_group[permission_group_name]
                        )}
                        id={`permission-group-${group_index}`}
                        onChange={(event: any) =>
                          updatePermissionGroup(
                            permission_group_name,
                            permission_group[permission_group_name],
                            event.target?.checked,
                            (permissions: any) => {
                              setFormState((prev: any) => ({
                                ...prev,
                                permission: permissions,
                              }));
                              let params = {
                                action: event.target.checked ? "add" : "remove",
                              };
                              updatePermission(params);
                            }
                          )
                        }
                      />
                      <Label
                        className="ml-2 capitalize dark:text-gray-400 cursor-pointer"
                        htmlFor={`permission-group-${group_index}`}
                      >
                        {permission_group_name} - Group
                      </Label>
                    </div>
                    <div className="px-3">
                      {permission_group[permission_group_name]?.map(
                        (permission: Permission, index: number) => (
                          <div key={index}>
                            <Checkbox
                              checked={usePermission?.includes(
                                permission?.name as never
                              )}
                              onClick={(event: any) =>
                                updatePermission({
                                  action: event.target.checked ? "add" : "remove",
                                })
                              }
                              id={`permission-${group_index}-${index}`}
                              className={permission_group_name}
                              name="permission"
                              value={permission?.name}
                              onChange={handleChange}
                              ref={(element) => {
                                checkboxes.current[
                                  permission_group_name + index
                                ] = element;
                              }}
                            />
                            <Label
                              htmlFor={`permission-${group_index}-${index}`}
                              className="ml-3 capitalize dark:text-gray-400"
                            >
                              {permission?.name?.split(".")?.join(" ")}
                            </Label>
                          </div>
                        )
                      )}
                    </div>
                  </div>
                )
              )}
            </div>
          </form>
        </FormProvider>
      </div>
    </>
  );
};

export default PermissionList;
