import clsx from "clsx";
import { IconType } from "react-icons";
import { MdSpaceDashboard } from "react-icons/md";
import {
  BsFileEarmarkText,
  BsClockHistory,
  BsGraphUp,
  BsChevronBarRight,
  BsChevronBarLeft,
  BsShieldFill,
  BsCloudFill,
  BsCurrencyDollar,
  BsClipboardData,
  BsPeople,
} from "react-icons/bs";
import { GoWorkflow } from "react-icons/go";
import { CiDumbbell } from "react-icons/ci";
import { RiLogoutBoxFill } from "react-icons/ri";
import Link from "next/link";
import { useRouter } from "next/router";
import axios from "axios";
import FocusLayer from "@/components/FocusLayer";
import { preventNavigation } from "@/utils/navigation.disabled";
import usePreferencesStore from "@/stores/preferencesStore";
import { User } from "@/interfaces/user";
import useTicketsListener from "@/hooks/useTicketsListener";
import { getTypesOfUser } from "@/utils/permissions";
import usePermissions from "@/hooks/usePermissions";
import { EntityWithRoles } from "@/interfaces/entity";
import {
  useAllowedEntities,
  useAllowedEntitiesSomePermissions,
} from "@/hooks/useEntityPermissions";
import { useMemo } from "react";
import { PermissionType } from "../interfaces/permissions";

interface Props {
  path: string;
  navDisabled?: boolean;
  focusMode?: boolean;
  onFocusLayerMouseEnter?: () => void;
  className?: string;
  user: User;
  entities?: EntityWithRoles[];
}

interface NavProps {
  Icon: IconType;
  label: string;
  path: string;
  keyPath: string;
  disabled?: boolean;
  isMinimized?: boolean;
  badge?: number;
}

const Nav = ({
  Icon,
  label,
  path,
  keyPath,
  disabled = false,
  isMinimized = false,
  badge,
}: NavProps) => {
  return (
    <Link
      href={!disabled ? keyPath : ""}
      className={clsx(
        "flex items-center gap-4 rounded-full p-4 text-gray-500 hover:text-white",
        "transition-all duration-300 ease-in-out relative",
        disabled
          ? "hover:bg-mti-gray-dim cursor-not-allowed"
          : "hover:bg-mti-purple-light cursor-pointer",
        path.startsWith(keyPath) && "bg-mti-purple-light text-white",
        isMinimized ? "w-fit" : "w-full min-w-[200px] px-8 2xl:min-w-[220px]"
      )}
    >
      <Icon size={24} />
      {!isMinimized && <span className="text-lg font-semibold">{label}</span>}
      {!!badge && badge > 0 && (
        <div
          className={clsx(
            "bg-mti-purple-light h-5 w-5 text-xs rounded-full flex items-center justify-center text-white",
            "transition ease-in-out duration-300",
            isMinimized && "absolute right-0 top-0"
          )}
        >
          {badge}
        </div>
      )}
    </Link>
  );
};

export default function Sidebar({
  path,
  entities = [],
  navDisabled = false,
  focusMode = false,
  user,
  onFocusLayerMouseEnter,
  className,
}: Props) {
  const router = useRouter();

  const isAdmin = useMemo(
    () => ["developer", "admin"].includes(user?.type),
    [user?.type]
  );

  const [isMinimized, toggleMinimize] = usePreferencesStore((state) => [
    state.isSidebarMinimized,
    state.toggleSidebarMinimized,
  ]);

  const { permissions } = usePermissions(user.id);

  const entitiesAllowStatistics = useAllowedEntities(
    user,
    entities,
    "view_statistics"
  );

  const entitiesAllowPaymentRecord = useAllowedEntities(
    user,
    entities,
    "view_payment_record"
  );
  const entitiesAllowGeneration = useAllowedEntitiesSomePermissions(
    user,
    entities,
    [
      "generate_reading",
      "generate_listening",
      "generate_writing",
      "generate_speaking",
      "generate_level",
    ]
  );

  const sidebarPermissions = useMemo<{ [key: string]: boolean }>(() => {
    if (user.type === "developer") {
      return {
        viewExams: true,
        viewStats: true,
        viewRecords: true,
        viewTickets: true,
        viewClassrooms: true,
        viewSettings: true,
        viewPaymentRecords: true,
        viewGeneration: true,
        viewApprovalWorkflows: true,
      };
    }
    const sidebarPermissions: { [key: string]: boolean } = {
      viewExams: false,
      viewStats: false,
      viewRecords: false,
      viewTickets: false,
      viewClassrooms: false,
      viewSettings: false,
      viewPaymentRecords: false,
      viewGeneration: false,
      viewApprovalWorkflows: false,
    };

    if (!user || !user?.type) return sidebarPermissions;

    const neededPermissions = permissions.reduce((acc, curr) => {
      if (
        ["viewExams", "viewRecords", "viewTickets"].includes(curr as string)
      ) {
        acc.push(curr);
      }
      return acc;
    }, [] as PermissionType[]);

    if (
      ["student", "teacher", "developer"].includes(user.type) &&
      neededPermissions.includes("viewExams")
    ) {
      sidebarPermissions["viewExams"] = true;
    }
    if (
      getTypesOfUser(["agent"]).includes(user.type) &&
      (entitiesAllowStatistics.length > 0 ||
        neededPermissions.includes("viewStats"))
    ) {
      sidebarPermissions["viewStats"] = true;
    }
    if (
      [
        "admin",
        "developer",
        "teacher",
        "corporate",
        "mastercorporate",
      ].includes(user.type) &&
      (entitiesAllowGeneration.length > 0 || isAdmin)
    ) {
      sidebarPermissions["viewGeneration"] = true;
      sidebarPermissions["viewApprovalWorkflows"] = true;
    }
    if (
      getTypesOfUser(["agent"]).includes(user.type) &&
      neededPermissions.includes("viewRecords")
    ) {
      sidebarPermissions["viewRecords"] = true;
    }
    if (
      ["admin", "developer", "agent"].includes(user.type) &&
      neededPermissions.includes("viewTickets")
    ) {
      sidebarPermissions["viewTickets"] = true;
    }
    if (
      [
        "admin",
        "mastercorporate",
        "developer",
        "corporate",
        "teacher",
        "student",
      ].includes(user.type)
    ) {
      sidebarPermissions["viewClassrooms"] = true;
    }
    if (getTypesOfUser(["student", "agent"]).includes(user.type)) {
      sidebarPermissions["viewSettings"] = true;
    }
    if (
      ["admin", "developer", "agent", "corporate", "mastercorporate"].includes(
        user.type
      ) &&
      entitiesAllowPaymentRecord.length > 0
    ) {
      sidebarPermissions["viewPaymentRecords"] = true;
    }
    return sidebarPermissions;
  }, [
    entitiesAllowGeneration.length,
    entitiesAllowPaymentRecord.length,
    entitiesAllowStatistics.length,
    isAdmin,
    permissions,
    user,
  ]);

  const { totalAssignedTickets } = useTicketsListener(
    user.id,
    sidebarPermissions["viewTickets"]
  );

  const logout = async () => {
    axios.post("/api/logout").finally(() => {
      setTimeout(() => router.reload(), 500);
    });
  };

  const disableNavigation = preventNavigation(navDisabled, focusMode);

  return (
    <section
      className={clsx(
        "relative flex h-full flex-col justify-between bg-transparent px-4 py-4 pb-8",
        isMinimized ? "w-fit" : "-xl:w-20 w-1/6",
        className
      )}
    >
      <div className="-xl:hidden flex-col gap-3 xl:flex">
        <Nav
          disabled={disableNavigation}
          Icon={MdSpaceDashboard}
          label="Dashboard"
          path={path}
          keyPath="/dashboard"
          isMinimized={isMinimized}
        />
        {sidebarPermissions["viewExams"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsFileEarmarkText}
            label="Practice"
            path={path}
            keyPath="/exam"
            isMinimized={isMinimized}
          />
        )}
        {sidebarPermissions["viewStats"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsGraphUp}
            label="Stats"
            path={path}
            keyPath="/stats"
            isMinimized={isMinimized}
          />
        )}
        {sidebarPermissions["viewClassrooms"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsPeople}
            label="Classrooms"
            path={path}
            keyPath="/classrooms"
            isMinimized={isMinimized}
          />
        )}
        {sidebarPermissions["viewRecords"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsClockHistory}
            label="Record"
            path={path}
            keyPath="/record"
            isMinimized={isMinimized}
          />
        )}
        {sidebarPermissions["viewRecords"] && (
          <Nav
            disabled={disableNavigation}
            Icon={CiDumbbell}
            label="Training"
            path={path}
            keyPath="/training"
            isMinimized={isMinimized}
          />
        )}
        {sidebarPermissions["viewPaymentRecords"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsCurrencyDollar}
            label="Payment Record"
            path={path}
            keyPath="/payment-record"
            isMinimized={isMinimized}
          />
        )}
        {sidebarPermissions["viewSettings"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsShieldFill}
            label="Settings"
            path={path}
            keyPath="/settings"
            isMinimized={isMinimized}
          />
        )}
        {sidebarPermissions["viewTickets"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsClipboardData}
            label="Tickets"
            path={path}
            keyPath="/tickets"
            isMinimized={isMinimized}
            badge={totalAssignedTickets}
          />
        )}
        {sidebarPermissions["viewGeneration"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsCloudFill}
            label="Generation"
            path={path}
            keyPath="/generation"
            isMinimized={isMinimized}
          />
        )}
        {sidebarPermissions["viewApprovalWorkflows"] && (
          <Nav
            disabled={disableNavigation}
            Icon={GoWorkflow}
            label="Approval Workflows"
            path={path}
            keyPath="/approval-workflows"
            isMinimized={isMinimized}
          />
        )}
      </div>
      <div className="-xl:flex flex-col gap-3 xl:hidden">
        <Nav
          disabled={disableNavigation}
          Icon={MdSpaceDashboard}
          label="Dashboard"
          path={path}
          keyPath="/"
          isMinimized
        />
        <Nav
          disabled={disableNavigation}
          Icon={BsFileEarmarkText}
          label="Exams"
          path={path}
          keyPath="/exam"
          isMinimized
        />
        {sidebarPermissions["viewStats"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsGraphUp}
            label="Stats"
            path={path}
            keyPath="/stats"
            isMinimized
          />
        )}
        {sidebarPermissions["viewRecords"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsClockHistory}
            label="Record"
            path={path}
            keyPath="/record"
            isMinimized
          />
        )}
        {sidebarPermissions["viewRecords"] && (
          <Nav
            disabled={disableNavigation}
            Icon={CiDumbbell}
            label="Training"
            path={path}
            keyPath="/training"
            isMinimized
          />
        )}
        {sidebarPermissions["viewPaymentRecords"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsCurrencyDollar}
            label="Payment Record"
            path={path}
            keyPath="/payment-record"
            isMinimized
          />
        )}
        {sidebarPermissions["viewSettings"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsShieldFill}
            label="Settings"
            path={path}
            keyPath="/settings"
            isMinimized
          />
        )}
        {sidebarPermissions["viewGeneration"] && (
          <Nav
            disabled={disableNavigation}
            Icon={BsCloudFill}
            label="Generation"
            path={path}
            keyPath="/generation"
            isMinimized
          />
        )}
        {sidebarPermissions["viewApprovalWorkflows"] && (
          <Nav
            disabled={disableNavigation}
            Icon={GoWorkflow}
            label="Approval Workflows"
            path={path}
            keyPath="/approval-workflows"
            isMinimized
          />
        )}
      </div>

      <div className="2xl:fixed bottom-12 flex flex-col gap-0 -2xl:mt-8 ">
        <div
          role="button"
          tabIndex={1}
          onClick={toggleMinimize}
          className={clsx(
            "hover:text-mti-rose -xl:hidden flex cursor-pointer items-center gap-4 rounded-full p-4 text-black transition duration-300 ease-in-out",
            isMinimized ? "w-fit" : "w-full min-w-[250px] px-8"
          )}
        >
          {isMinimized ? (
            <BsChevronBarRight size={24} />
          ) : (
            <BsChevronBarLeft size={24} />
          )}
          {!isMinimized && (
            <span className="text-lg font-medium">Minimize</span>
          )}
        </div>
        <div
          role="button"
          tabIndex={1}
          onClick={focusMode ? () => {} : logout}
          className={clsx(
            "hover:text-mti-rose flex cursor-pointer items-center gap-4 rounded-full p-4 text-black transition duration-300 ease-in-out -xl:px-4",
            isMinimized ? "w-fit" : "w-full min-w-[250px] px-8"
          )}
        >
          <RiLogoutBoxFill size={24} />
          {!isMinimized && (
            <span className="-xl:hidden text-lg font-medium">Log Out</span>
          )}
        </div>
      </div>
      {focusMode && (
        <FocusLayer onFocusLayerMouseEnter={onFocusLayerMouseEnter} />
      )}
    </section>
  );
}
