"use client";

import dynamic from "next/dynamic";
import {
  ExclamationCircleFilled,
  FullscreenExitOutlined,
  FullscreenOutlined,
  HomeOutlined,
  LogoutOutlined,
  MenuOutlined,
  SearchOutlined,
  UserOutlined,
} from "@ant-design/icons";
import {ProConfigProvider} from "@ant-design/pro-components";
import type {SelectProps} from "antd";
import {App, Dropdown, MenuProps, Modal, Select} from "antd";
import {deleteCookie, getCookie} from "cookies-next";
import Link from "next/link";
import {usePathname, useRouter} from "next/navigation";
import {useEffect, useRef, useState} from "react";
import {IconMap, RouteInfo, UserInfo} from "../_modules/definies";
import "./styles.css";
import "../globals.css";
import {displayModeIsDark, fetchApi, watchDarkModeChange,} from "../_modules/func";

//动态引入 ProLayout，禁用 SSR
const ProLayout = dynamic(
  () => import("@ant-design/pro-components").then((mod) => mod.ProLayout),
  { ssr: false }
);

export default function RootLayout({
                                     children,
                                   }: {
  children: React.ReactNode;
}) {
  const { push } = useRouter();

  const redirectToLogin = () => {
    push("/login");
  };

  const [isDark, setIsDark] = useState(false);

  useEffect(() => {
    const token = getCookie("token");
    if (!token) {
      redirectToLogin();
      return;
    }
    getProfile();

    setIsDark(displayModeIsDark());
    const unsubscribe = watchDarkModeChange((matches: boolean) => {
      setIsDark(matches);
    });

    document.addEventListener("click", hideSearchInput);
    return () => {
      unsubscribe();
      document.removeEventListener("click", hideSearchInput);
    };
  }, []);

  const searchRef = useRef<HTMLDivElement>(null);
  const hideSearchInput = (e: any) => {
    if (searchRef.current && !searchRef.current.contains(e.target)) {
      setShowSearch(false);
      setSearchListData([]);
    }
  };

  const [showSearch, setShowSearch] = useState(false);
  const [isLogoutShow, setIsLogoutShow] = useState(false);
  const [confirmLoading, setConfirmLoading] = useState(false);

  const onActionClick: MenuProps["onClick"] = ({ key }) => {
    if (key === "logout") {
      setIsLogoutShow(true);
    } else if (key === "profile") {
      push("/user/profile");
    }
  };

  const [userInfo, setUserInfo] = useState<UserInfo>({
    nickName: "Monrtnon",
    avatar: "/avatar1.jpeg",
  });

  const getProfile = async () => {
    const data = await fetchApi("/api/getInfo", push);
    if (data) {
      setUserInfo({
        nickName: data.user.nickName,
        avatar:
          data.user.avatar === ""
            ? data.user.sex === "1"
              ? "/avatar1.jpeg"
              : "/avatar0.jpeg"
            : "/api" + data.user.avatar,
      });
    }
  };

  const [menuData, setMenuData] = useState<any[]>([]);
  const getRoutes = async () => {
    const body = await fetchApi("/api/getRouters", push);
    const rootChildren: Array<RouteInfo> = [];
    const searchMenuList: any[] = [];

    const indexRoute: RouteInfo = {
      path: "/home",
      name: "首页",
      icon: <HomeOutlined />,
    };
    searchMenuList.push({ value: indexRoute.path, text: indexRoute.name });
    rootChildren.push(indexRoute);

    if (body.data?.length > 0) {
      body.data.forEach((menu: any) => {
        const route: RouteInfo = {
          path: menu.path,
          name: menu.meta.title,
          icon:
            menu.meta.icon !== null ? (
              IconMap[menu.meta.icon.replace(/-/g, "") as "system"]
            ) : (
              <MenuOutlined />
            ),
        };
        if (menu.children?.length > 0) {
          if (route.name != null) {
            getSubMenu(route, menu.children, route.name, route.path, searchMenuList);
          }
        }
        rootChildren.push(route);
      });
    }
    setMenuData(searchMenuList);
    return rootChildren;
  };

  const getSubMenu = (
    parent: RouteInfo,
    menuChildren: any[],
    parentName: string,
    parentPath: string,
    searchMenuList: any[]
  ) => {
    const routeChildren: Array<RouteInfo> = [];
    menuChildren.forEach((menu: any) => {
      const route: RouteInfo = {
        path: menu.path,
        name: menu.meta.title,
        icon:
          menu.meta.icon !== null ? (
            IconMap[menu.meta.icon.replace(/-/g, "") as "system"]
          ) : (
            <MenuOutlined />
          ),
      };
      routeChildren.push(route);

      if (menu.children?.length > 0) {
        getSubMenu(
          route,
          menu.children,
          parentName + " > " + route.name,
          parentPath + "/" + route.path,
          searchMenuList
        );
      } else {
        searchMenuList.push({
          text: parentName + " > " + menu.meta.title,
          value: parentPath + "/" + route.path,
        });
      }
    });
    parent.routes = routeChildren;
  };

  const logout = async () => {
    setConfirmLoading(true);
    const data = await fetchApi("/api/logout", push, { method: "POST" });
    if (data.code === 200) {
      deleteCookie("token");
      redirectToLogin();
      setIsLogoutShow(false);
      setConfirmLoading(false);
    }
  };

  const pathName = usePathname();
  const [pathname, setPathname] = useState(pathName);

  const [searchListData, setSearchListData] = useState<SelectProps["options"]>([]);
  const handleSearch = (newValue: string) => {
    if (!newValue) return;
    setSearchListData(menuData.filter((item) => item.text.includes(newValue)));
  };
  const handleSearchChange = (path: string) => {
    setPathname(path || "/index");
    push(path);
  };

  const [isFullscreen, setIsFullscreen] = useState(false);
  const openFullscreen = () => {
    document.documentElement.requestFullscreen?.();
    setIsFullscreen(true);
  };
  const closeFullscreen = () => {
    document.exitFullscreen?.();
    setIsFullscreen(false);
  };

  return (
    <App>
      <ProConfigProvider dark={isDark}>
        <ProLayout
          title="沅陵县太常片区城市地下管网"
          logo="./logo.png"
          menu={{ request: getRoutes }}
          layout="mix"
          splitMenus={false}
          defaultCollapsed={false}
          breakpoint={false}
          fixedHeader={false}
          location={{ pathname }}
          onMenuHeaderClick={(e) => console.log(e)}
          menuItemRender={(item, dom) => (
            <div onClick={() => setPathname(item.path || "/index")}>
              <Link href={item.path ?? ""}>{dom}</Link>
            </div>
          )}
          subMenuItemRender={(item, dom) => dom}
          avatarProps={{
            src: userInfo.avatar,
            size: "small",
            title: userInfo.nickName,
            render: (_, dom) => (
              <Dropdown
                menu={{
                  items: [
                    { key: "profile", icon: <UserOutlined />, label: "个人中心" },
                    { type: "divider" },
                    { key: "logout", icon: <LogoutOutlined />, label: "退出登录" },
                  ],
                  onClick: onActionClick,
                }}
              >
                {dom}
              </Dropdown>
            ),
          }}
          actionsRender={(props) => {
            if (props.isMobile) return [];
            return [
              <div
                key="search"
                style={{ height: "100%", display: "flex", alignItems: "center" }}
                ref={searchRef}
              >
                <SearchOutlined
                  style={{ color: "var(--ant-primary-color)", marginRight: showSearch ? 8 : 0 }}
                  onClick={() => setShowSearch(!showSearch)}
                />
                {showSearch && (
                  <Select
                    showSearch
                    autoFocus
                    style={{ borderRadius: 4, marginInlineEnd: 12, width: 300 }}
                    suffixIcon={null}
                    placeholder="搜索菜单"
                    variant="borderless"
                    filterOption={false}
                    notFoundContent={null}
                    onSearch={handleSearch}
                    onChange={handleSearchChange}
                    options={searchListData?.map((d) => ({ value: d.value, label: d.text }))}
                  />
                )}
              </div>,
              isFullscreen ? (
                <FullscreenExitOutlined key="exit" onClick={closeFullscreen} />
              ) : (
                <FullscreenOutlined key="full" onClick={openFullscreen} />
              ),
            ];
          }}
          menuFooterRender={(props) =>
            props?.collapsed ? undefined : (
              <div style={{ textAlign: "center", paddingBlockStart: 12 }}>
                <div>©{new Date().getFullYear()} Mortnon.</div>
              </div>
            )
          }
        >
          <Modal
            title={<><ExclamationCircleFilled style={{ color: "#faad14" }} /> 提示</>}
            open={isLogoutShow}
            onOk={logout}
            onCancel={() => setIsLogoutShow(false)}
            confirmLoading={confirmLoading}
          >
            确定注销并退出系统吗？
          </Modal>
          {children}
        </ProLayout>
      </ProConfigProvider>
    </App>
  );
}
