"use client";

import React, { useCallback, useEffect, useMemo, useState } from "react";

import styles from "@/components/administrator/UserEditor/usereditor.module.css";
import Input from "@/components/administrator/form/Input/input";
import Button from "@/components/ui/Button/button";
import Loader from "@/components/web/Loader/loader";
import Dropdown from "@/components/administrator/form/Dropdown/dropdown";
import { useRouter } from "next/navigation";
import { useUser } from "@/hooks/useUser";
import { checkPasswordStrength, filterEmptyValue } from "@/app/library/library";
import { useDispatch } from "react-redux";
import { setNotification } from "@/utils/store/features/ui/notification.slice";

/**
 *
 * @type {React.FC <{
 *    data: object;
 * }>}
 * @returns
 */
const UserEditor = (props) => {
  const router = useRouter();
  const dispatch = useDispatch();
  const [data, setData] = useState(props.data);
  const [loading, setLoading] = useState({
    save: false,
    delete: false,
  });
  const [password, setPassword] = useState({
    new: "",
    confirm: "",
  });

  const { deleteUser, updateUser } = useUser();

  const isChange = useMemo(() => {
    const _data = filterEmptyValue(data);
    const _data2 = filterEmptyValue(props.data);
    return JSON.stringify(_data) !== JSON.stringify(_data2);
  }, [props.data, data]);
  const role = useMemo(() => {
    const roleList = [
      { role: "admin", label: "Administrator" },
      { role: "editor", label: "Editor" },
    ];
    const current = roleList.find((v) => v.role === data.role);
    return { data: roleList, current };
  }, [data]);
  const passwordMatch = useMemo(() => {
    if (Object.values(password).every((v) => !v)) return false;
    return password.new === password.confirm;
  }, [password]);
  const passwordStrange = useMemo(() => {
    const stength = checkPasswordStrength(password.new);
    return {
      status: ["Weak", "Medium"].includes(stength),
      message: `Password strength: ${stength}, Please use a strong password`,
    };
  }, [password]);

  const handleDelete = useCallback(() => {
    setLoading((prev) => ({ ...prev, delete: true }));
    deleteUser(
      data._id,
      () => {
        router.push("/dashboard/users");
        setLoading((prev) => ({ ...prev, delete: false }));
      },
      () => {
        setLoading((prev) => ({ ...prev, delete: false }));
      }
    );
  }, [data, router, deleteUser]);

  const handleSave = useCallback(() => {
    if (!passwordMatch && Object.values(password).some((v) => v)) {
      return dispatch(
        setNotification({
          status: true,
          message: "Password does not match",
          type: "error",
          timeout: 3000,
        })
      );
    }

    const filteredData = Object.fromEntries(
      Object.entries(data).filter(([_, value]) => value)
    );

    updateUser(filteredData, (result) => {
      setData(result);
      setLoading((prev) => ({ ...prev, save: false }));
    });
  }, [data, updateUser, passwordMatch, dispatch, password]);

  useEffect(() => {
    const handleKeyDown = (e) => {
      const keyDown = [
        {
          on: e.key === "s" && e.ctrlKey,
          call: async () => {
            e.preventDefault();
            handleSave();
          },
        },
        {
          on: e.key === "Delete" && e.shiftKey,
          call: async () => {
            e.preventDefault();
            handleDelete();
          },
        },
      ];

      return keyDown.find((key) => key.on)?.call();
    };

    document.addEventListener("keydown", handleKeyDown);
    return () => {
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [handleSave, handleDelete]);

  return (
    <>
      <h1 className={styles.post_title}>{data.name || "Unnamed"}</h1>
      <div className={styles.container}>
        <div className={styles.editor_header}>
          <div className={styles.editor_status}>
            <p>
              ID : <span>{data._id}</span>
            </p>
            <p>
              Status : <span>{isChange ? "Changed" : "Unchanged"}</span>
            </p>
          </div>
          <div className={styles.editor_status}>
            <Button
              className={styles.button}
              disabled={!isChange || loading.save}
              onClick={() => handleSave()}>
              {loading.save && (
                <>
                  <Loader
                    size={20}
                    color={"#fff"}
                  />
                </>
              )}
              Save
            </Button>
            <Button
              className={styles.button}
              disabled={loading.delete}
              onClick={() => handleDelete()}>
              {loading.delete && (
                <>
                  <Loader
                    size={20}
                    color={"#fff"}
                  />
                </>
              )}
              Delete
            </Button>
          </div>
        </div>
        <div className={styles.editor_content}>
          <div className={`${styles.editor_body}`}>
            <div className={styles.editor_post}>
              <Input
                label="Name"
                className={styles.input}
                value={data.name || ""}
                labelclassname={styles.label}
                onChange={(e) =>
                  setData((prev) => ({
                    ...prev,
                    name: e.target.value,
                  }))
                }
              />
              <Input
                label="Username"
                className={styles.input}
                value={data.username || ""}
                labelclassname={styles.label}
                onChange={(e) =>
                  setData((prev) => ({
                    ...prev,
                    username: e.target.value,
                  }))
                }
              />
              <Dropdown
                className={styles.input}
                data={role.data}
                display="label"
                label="Role"
                value={role.current}
                onClick={(data) => {
                  setData((prev) => ({
                    ...prev,
                    role: data.role,
                  }));
                }}
              />
              <Input
                label="Password"
                type="password"
                error={passwordStrange}
                className={styles.input}
                labelclassname={styles.label}
                onChange={(e) => {
                  setData((prev) => ({ ...prev, password: e.target.value }));
                  setPassword((prev) => ({ ...prev, new: e.target.value }));
                }}
              />
              <Input
                label="Confirm Password"
                type="password"
                disabled={password.new === "" || passwordStrange.status}
                className={styles.input}
                error={{
                  status: !passwordMatch && password.confirm !== "",
                  message: "Password does not match",
                }}
                labelclassname={styles.label}
                onChange={(e) =>
                  setPassword((prev) => ({
                    ...prev,
                    confirm: e.target.value,
                  }))
                }
              />
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default UserEditor;
