import apiFetch from "@/lib/apiFetch";
import {
  ActionIcon,
  Button,
  Divider,
  Flex,
  Group,
  Input,
  Modal,
  Select,
  Stack,
  Table,
  Text,
  Title,
  Tooltip,
} from "@mantine/core";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { IconEdit, IconPlus, IconTrash } from "@tabler/icons-react";
import type { JsonValue } from "generated/prisma/runtime/library";
import { useState } from "react";
import useSWR from "swr";
import notification from "./notificationGlobal";

export default function UserSetting({
  permissions,
}: {
  permissions: JsonValue[];
}) {
  const [btnDisable, setBtnDisable] = useState(true);
  const [btnLoading, setBtnLoading] = useState(false);
  const [opened, { open, close }] = useDisclosure(false);
  const [openedDelete, { open: openDelete, close: closeDelete }] =
    useDisclosure(false);
  const [dataDelete, setDataDelete] = useState("");
  const {
    data: dataRole,
    mutate: mutateRole,
    isLoading: isLoadingRole,
  } = useSWR("user-role", () => apiFetch.api.user.role.get());
  const [openedTambah, { open: openTambah, close: closeTambah }] =
    useDisclosure(false);
  const { data, mutate, isLoading } = useSWR("user-list", () =>
    apiFetch.api.user.list.get(),
  );
  const list = data?.data || [];
  const listRole = dataRole?.data || [];
  const [dataEdit, setDataEdit] = useState({
    id: "",
    name: "",
    phone: "",
    email: "",
    roleId: "",
  });
  const [dataTambah, setDataTambah] = useState({
    name: "",
    email: "",
    roleId: "",
    password: "",
    phone: "",
  });
  const [error, setError] = useState({
    name: false,
    email: false,
    roleId: false,
    password: false,
    phone: false,
  });

  useShallowEffect(() => {
    mutate();
  }, []);

  async function handleCreate() {
    try {
      setBtnLoading(true);
      const res = await apiFetch.api.user.create.post(dataTambah);
      if (res.status === 200) {
        mutate();
        closeTambah();
        setDataTambah({
          name: "",
          email: "",
          roleId: "",
          password: "",
          phone: "",
        });
        notification({
          title: "Success",
          message: "Your user have been saved",
          type: "success",
        });
      } else {
        notification({
          title: "Error",
          message: "Failed to create user ",
          type: "error",
        });
      }
    } catch (error) {
      console.error(error);
      notification({
        title: "Error",
        message: "Failed to create user",
        type: "error",
      });
    } finally {
      setBtnLoading(false);
    }
  }

  async function handleEdit() {
    try {
      setBtnLoading(true);
      const res = await apiFetch.api.user.update.post(dataEdit);
      if (res.status === 200) {
        mutate();
        close();
        notification({
          title: "Success",
          message: "Your data have been saved",
          type: "success",
        });
      } else {
        notification({
          title: "Error",
          message: "Failed to edit user",
          type: "error",
        });
      }
    } catch (error) {
      console.error(error);
      notification({
        title: "Error",
        message: "Failed to edit user2",
        type: "error",
      });
    } finally {
      setBtnLoading(false);
    }
  }

  async function handleDelete() {
    try {
      setBtnLoading(true);
      const res = await apiFetch.api.user.delete.post({ id: dataDelete });
      if (res.status === 200) {
        mutate();
        closeDelete();
        notification({
          title: "Success",
          message: "Your user have been deleted",
          type: "success",
        });
      } else {
        notification({
          title: "Error",
          message: "Failed to delete user",
          type: "error",
        });
      }
    } catch (error) {
      console.error(error);
      notification({
        title: "Error",
        message: "Failed to delete user",
        type: "error",
      });
    } finally {
      setBtnLoading(false);
    }
  }

  function chooseEdit({
    data,
  }: {
    data: {
      id: string;
      name: string;
      phone: string;
      email: string;
      roleId: string;
    };
  }) {
    setDataEdit(data);
    open();
  }

  function onValidation({
    kat,
    value,
    aksi,
  }: {
    kat: "name" | "email" | "roleId" | "password" | "phone";
    value: string | null;
    aksi: "edit" | "tambah";
  }) {
    if (value == null || value.length < 1) {
      setBtnDisable(true);
      setError({ ...error, [kat]: true });
    } else {
      setBtnDisable(false);
      setError({ ...error, [kat]: false });
    }

    if (aksi === "edit") {
      setDataEdit({ ...dataEdit, [kat]: value });
    } else {
      setDataTambah({ ...dataTambah, [kat]: value });
    }
  }

  useShallowEffect(() => {
    if (dataEdit.name.length > 0) {
      setBtnDisable(false);
    }
  }, [dataEdit.id]);

  return (
    <>
      {/* Modal Edit */}
      <Modal
        opened={opened}
        onClose={close}
        title={"Edit"}
        centered
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Stack gap="ld">
          <Input.Wrapper label="Nama">
            <Input
              value={dataEdit.name}
              error={error.name ? "Field is required" : ""}
              onChange={(e) =>
                onValidation({
                  kat: "name",
                  value: e.target.value,
                  aksi: "edit",
                })
              }
            />
          </Input.Wrapper>
          <Select
            label="Role"
            placeholder="Pilih Role"
            data={listRole.map((r: any) => ({
              value: r.id,
              label: r.name,
            }))}
            value={dataEdit.roleId || null}
            error={error.roleId ? "Field is required" : ""}
            onChange={(_value, option) => {
              onValidation({
                kat: "roleId",
                value: option?.value,
                aksi: "edit",
              });
            }}
          />
          <Input.Wrapper label="Phone" description="">
            <Input
              value={dataEdit.phone}
              onChange={(e) =>
                onValidation({
                  kat: "phone",
                  value: e.target.value,
                  aksi: "edit",
                })
              }
            />
          </Input.Wrapper>
          <Input.Wrapper
            label="Email"
            description=""
            error={error.email ? "Field is required" : ""}
          >
            <Input
              value={dataEdit.email}
              onChange={(e) =>
                onValidation({
                  kat: "email",
                  value: e.target.value,
                  aksi: "edit",
                })
              }
            />
          </Input.Wrapper>
          <Group justify="center" grow>
            <Button variant="light" onClick={close}>
              Batal
            </Button>
            <Button
              variant="filled"
              onClick={handleEdit}
              disabled={btnDisable}
              loading={btnLoading}
            >
              Simpan
            </Button>
          </Group>
        </Stack>
      </Modal>

      {/* Modal Tambah */}
      <Modal
        opened={openedTambah}
        onClose={closeTambah}
        title={"Tambah"}
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Stack gap="ld">
          <Input.Wrapper
            label="Nama"
            description=""
            error={error.name ? "Field is required" : ""}
          >
            <Input
              value={dataTambah.name}
              onChange={(e) =>
                onValidation({
                  kat: "name",
                  value: e.target.value,
                  aksi: "tambah",
                })
              }
            />
          </Input.Wrapper>
          <Select
            label="Role"
            placeholder="Pilih Role"
            data={listRole.map((r: any) => ({
              value: r.id,
              label: r.name,
            }))}
            value={dataTambah.roleId || null}
            error={error.roleId ? "Field is required" : ""}
            onChange={(_value, option) => {
              onValidation({
                kat: "roleId",
                value: option?.value,
                aksi: "tambah",
              });
            }}
          />
          <Input.Wrapper label="Phone" description="">
            <Input
              value={dataTambah.phone}
              onChange={(e) =>
                onValidation({
                  kat: "phone",
                  value: e.target.value,
                  aksi: "tambah",
                })
              }
            />
          </Input.Wrapper>
          <Input.Wrapper
            label="Email"
            description=""
            error={error.email ? "Field is required" : ""}
          >
            <Input
              value={dataTambah.email}
              onChange={(e) =>
                onValidation({
                  kat: "email",
                  value: e.target.value,
                  aksi: "tambah",
                })
              }
            />
          </Input.Wrapper>
          <Input.Wrapper
            label="Password"
            description=""
            error={error.password ? "Field is required" : ""}
          >
            <Input
              value={dataTambah.password}
              onChange={(e) =>
                onValidation({
                  kat: "password",
                  value: e.target.value,
                  aksi: "tambah",
                })
              }
            />
          </Input.Wrapper>

          <Group justify="center" grow>
            <Button variant="light" onClick={closeTambah}>
              Batal
            </Button>
            <Button
              variant="filled"
              onClick={handleCreate}
              disabled={
                btnDisable ||
                dataTambah.name.length < 1 ||
                dataTambah.email.length < 1 ||
                dataTambah.password.length < 1 ||
                dataTambah.roleId.length < 1 ||
                dataTambah.phone.length < 1
              }
              loading={btnLoading}
            >
              Simpan
            </Button>
          </Group>
        </Stack>
      </Modal>

      {/* Modal Delete */}
      <Modal
        opened={openedDelete}
        onClose={closeDelete}
        title={"Delete"}
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Stack gap="md">
          <Text size="md" color="gray.6">
            Apakah anda yakin ingin menghapus user ini?
          </Text>
          <Group justify="center" grow>
            <Button variant="light" onClick={closeDelete}>
              Batal
            </Button>
            <Button
              variant="filled"
              color="red"
              onClick={handleDelete}
              loading={btnLoading}
            >
              Hapus
            </Button>
          </Group>
        </Stack>
      </Modal>

      <Stack gap={"md"}>
        <Flex align="center" justify="space-between">
          <Title order={4} c="gray.2">
            Daftar User
          </Title>
          {permissions.includes("setting.user.tambah") && (
            <Tooltip label="Tambah User">
              <Button
                variant="light"
                leftSection={<IconPlus size={20} />}
                onClick={openTambah}
              >
                Tambah
              </Button>
            </Tooltip>
          )}
        </Flex>
        <Divider my={0} />
        <Stack gap={"md"}>
          <Table highlightOnHover>
            <Table.Thead>
              <Table.Tr>
                <Table.Th>Nama</Table.Th>
                <Table.Th>Telepon</Table.Th>
                <Table.Th>Email</Table.Th>
                <Table.Th>Role</Table.Th>
                <Table.Th>Aksi</Table.Th>
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>
              {list && Array.isArray(list) && list.length > 0 ? (
                list?.map((v: any) => (
                  <Table.Tr key={v.id}>
                    <Table.Td>{v.name}</Table.Td>
                    <Table.Td>{v.phone}</Table.Td>
                    <Table.Td>{v.email}</Table.Td>
                    <Table.Td>{v.nameRole}</Table.Td>
                    <Table.Td>
                      <Group>
                        <Tooltip
                          label={
                            permissions.includes("setting.user.edit")
                              ? "Edit User"
                              : "Edit User - Anda tidak memiliki akses"
                          }
                        >
                          <ActionIcon
                            variant="light"
                            size="sm"
                            style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
                            onClick={() => chooseEdit({ data: v })}
                            disabled={
                              !permissions.includes("setting.user.edit") ||
                              v.roleId == "developer"
                            }
                          >
                            <IconEdit size={20} />
                          </ActionIcon>
                        </Tooltip>
                        <Tooltip
                          label={
                            permissions.includes("setting.user.delete")
                              ? "Delete User"
                              : "Delete User - Anda tidak memiliki akses"
                          }
                        >
                          <ActionIcon
                            variant="light"
                            size="sm"
                            color="red"
                            style={{ boxShadow: "0 0 8px rgba(0,255,200,0.2)" }}
                            onClick={() => {
                              setDataDelete(v.id);
                              openDelete();
                            }}
                            disabled={
                              !permissions.includes("setting.user.delete") ||
                              v.roleId == "developer"
                            }
                          >
                            <IconTrash size={20} />
                          </ActionIcon>
                        </Tooltip>
                      </Group>
                    </Table.Td>
                  </Table.Tr>
                ))
              ) : (
                <Table.Tr>
                  <Table.Td colSpan={5} align="center">
                    Data User Tidak Ditemukan
                  </Table.Td>
                </Table.Tr>
              )}
            </Table.Tbody>
          </Table>
        </Stack>
      </Stack>
    </>
  );
}
