"use client"

import {
  AppShell,
  Box,
  Burger,
  Divider,
  Flex,
  Menu,
  NavLink,
  ScrollArea,
  Space,
  Stack,
  Text,
  Tooltip,
  UnstyledButton,
  useComputedColorScheme,
  useMantineColorScheme,
} from "@mantine/core"
import Avvvatars from "avvvatars-react"

import { useDisclosure, useMediaQuery } from "@mantine/hooks"
import {
  IconChevronDown,
  IconChevronLeft,
  IconChevronRight,
  IconLogout,
  IconMoon,
  IconSun,
} from "@tabler/icons-react"
import cx from "clsx"
import { Suspense, useEffect, useMemo, useState } from "react"
import actionToggleClasses from "./ActionToggle.module.css"
import headerLinkClasses from "./HeaderLink.module.css"

import { useUserStore } from "@/app/store/user"
import { usePathname, useRouter } from "next/navigation"
import { usePermissionStore } from "../label/store/auth"
import { deleteCookie } from "../login/api"
import classes from "./AppLayout.module.css"
import { MenuItem, withoutLayoutRoutes } from "./common"
import { ClientIcon } from "./components/ClientIcon"
import { LinksGroup } from "./components/NavbarLinks"
import { getShellNavLinkStyles } from "./navStyles"
import { useAppLayoutStore } from "./store"

const COMPOUND_SURNAMES = new Set([
  "欧阳",
  "太史",
  "端木",
  "上官",
  "司马",
  "东方",
  "独孤",
  "南宫",
  "万俟",
  "闻人",
  "夏侯",
  "诸葛",
  "尉迟",
  "公羊",
  "赫连",
  "澹台",
  "皇甫",
  "宗政",
  "濮阳",
  "公冶",
  "太叔",
  "申屠",
  "公孙",
  "慕容",
  "仲孙",
  "钟离",
  "长孙",
  "宇文",
  "司徒",
  "鲜于",
  "司空",
  "闾丘",
  "子车",
  "亓官",
  "司寇",
  "巫马",
  "公西",
  "颛孙",
  "壤驷",
  "公良",
  "漆雕",
  "乐正",
  "宰父",
  "谷梁",
  "拓跋",
  "轩辕",
  "令狐",
  "段干",
  "百里",
  "呼延",
  "东郭",
  "南门",
  "羊舌",
  "微生",
  "梁丘",
  "左丘",
  "东门",
  "西门",
  "南荣",
  "第五",
])

function isChineseName(value: string) {
  return /[\u4e00-\u9fff]/.test(value)
}

function getAvatarDisplayValue(rawValue?: string | null) {
  const value = rawValue?.trim() ?? ""

  if (!value) return "-"

  if (isChineseName(value)) {
    const normalized = value.replace(/[\s·•･・]/g, "")
    if (normalized.length <= 1) return normalized

    const surnameLength =
      normalized.length >= 3 && COMPOUND_SURNAMES.has(normalized.slice(0, 2))
        ? 2
        : 1
    const givenName = normalized.slice(surnameLength)

    if (!givenName) return normalized.slice(-1)
    if (givenName.length <= 2) return givenName
    return givenName.slice(-2)
  }

  const tokens = value.split(/[\s-_]+/).filter(Boolean)
  if (tokens.length >= 2) {
    return `${tokens[0][0] ?? ""}${tokens[tokens.length - 1][0] ?? ""}`
      .trim()
      .toUpperCase()
  }

  return value.slice(0, 2).toUpperCase()
}

export default function AppLayout({
  menu,
  children,
}: {
  menu: MenuItem[]
  children: React.ReactNode
}) {
  const [mobileOpened, { toggle: toggleMobile }] = useDisclosure()

  const { updateIsOpen } = useAppLayoutStore.getState()
  const { isOpen } = useAppLayoutStore()

  const [isClient, setIsClient] = useState(false)
  useEffect(() => {
    setIsClient(true)
  }, [])

  const { setColorScheme } = useMantineColorScheme()
  const computedColorScheme = useComputedColorScheme("light", {
    getInitialValueInEffect: true,
  })

  const pathname = usePathname()

  const withoutLayout = useMemo(
    () => withoutLayoutRoutes.includes(pathname),
    [pathname]
  )

  const router = useRouter()

  const activeHeaderMenu = useMemo(() => {
    return menu?.find((child) => pathname.startsWith(`/${child.url}`))
  }, [pathname, menu])

  const { menuDefaultRouter } = useAppLayoutStore.getState()

  const headItems = menu.map((item) => (
    <a
      key={item.url}
      href={`#`}
      className={headerLinkClasses.link}
      data-active={activeHeaderMenu?.url === item.url || undefined}
      onClick={(e) => {
        e.preventDefault()
        if (activeHeaderMenu?.url === item.url) return
        let toPathname = menuDefaultRouter[`/${item.url}`] || `/${item.url}`
        window.location.href = toPathname
        // router.replace(toPathname)
      }}>
      <ClientIcon icon={item.icon} style={{ width: 14, height: 14 }} />
      {item.title}
    </a>
  ))

  /**
   * 递归渲染 MenuItem
   */
  const renderMenuItem = (
    item: MenuItem,
    routerUrl?: string
  ): React.ReactNode => {
    if (item.items && item.items.length > 0) {
      // 有子菜单，递归渲染
      return (
        <Menu.Sub key={item.url}>
          <Menu.Sub.Target>
            <Menu.Sub.Item>{item.title}</Menu.Sub.Item>
          </Menu.Sub.Target>
          <Menu.Sub.Dropdown>
            {item.items.map((sub) =>
              renderMenuItem(sub, `${routerUrl}/${item.url}`)
            )}
          </Menu.Sub.Dropdown>
        </Menu.Sub>
      )
    } else {
      // 没有子菜单，普通 Menu.Item

      return (
        <Menu.Item key={item.url} p={0}>
          <NavLink
            noWrap={true}
            onClick={() => {
              router.push(`/${routerUrl}/${item.url}`)
            }}
            active={pathname === `/${routerUrl}/${item.url}`}
            leftSection={
              item.icon && (
                <ClientIcon
                  icon={item.icon}
                  style={{ width: "1rem", height: "1rem" }}
                />
              )
            }
            label={item.title}></NavLink>
        </Menu.Item>
      )
    }
  }

  const handleLogout = async () => {
    useUserStore.getState().removeUserInfo()
    usePermissionStore.getState().logout()
    process.env.NEXT_PUBLIC_OUTPUT_TYPE === "standalone" &&
      (await deleteCookie())
    router.push("/login")
    window.location.reload()
  }
  const matches = useMediaQuery("(min-width: 48em)")
  const userName = usePermissionStore((s) => s.user_name)
  const detailInfo = usePermissionStore((s) => s.detailInfo)
  const avatarDisplayValue = useMemo(
    () => getAvatarDisplayValue(userName),
    [userName]
  )

  return isClient ? (
    withoutLayout ? (
      <Suspense fallback={<></>}>{children}</Suspense>
    ) : (
      <AppShell
        header={{ height: 60 }}
        navbar={{
          width: isOpen ? 196 : 48,
          breakpoint: "sm",
          collapsed: { mobile: !mobileOpened },
        }}>
        <AppShell.Header className={classes.header}>
          <Flex className={classes.headerInner} align="center">
            <Burger
              opened={mobileOpened}
              onClick={toggleMobile}
              hiddenFrom="sm"
              size="sm"
            />
            <Flex className={classes.headerNav}>
              <Box className={classes.brand} visibleFrom="sm">
                <span className={classes.brandMark}>C</span>
                标注平台
              </Box>
              <Space w={"1rem"} hiddenFrom="sm" />
              {headItems}
            </Flex>
            <Flex
              className={classes.headerUser}
              justify="center"
              w={"max-content"}>
              <UnstyledButton
                display="none"
                onClick={() =>
                  setColorScheme(
                    computedColorScheme === "light" ? "dark" : "light"
                  )
                }
                aria-label="Toggle color scheme">
                <IconSun
                  className={cx(
                    actionToggleClasses.icon,
                    actionToggleClasses.light
                  )}
                  stroke={1.5}
                />
                <IconMoon
                  className={cx(
                    actionToggleClasses.icon,
                    actionToggleClasses.dark
                  )}
                  stroke={1.5}
                />
              </UnstyledButton>
              <Divider orientation="vertical" mx={"0.5rem"} display="none" />
              <Menu shadow="md" width={220}>
                <Menu.Target>
                  <Flex
                    align="center"
                    gap={12}
                    style={{
                      cursor: "pointer",
                    }}>
                    <Avvvatars
                      value={userName || "-"}
                      displayValue={avatarDisplayValue}
                      size={32}
                    />
                    <Stack gap={1}>
                      <Text className={classes.userName}>{userName}</Text>
                      <Text className={classes.userBaseCity}>
                        {detailInfo?.base_city || "-"}
                      </Text>
                    </Stack>
                    <IconChevronDown
                      className={classes.userBaseCity}
                      size={12}
                    />
                  </Flex>
                </Menu.Target>
                <Menu.Dropdown>
                  <Menu.Label>用户信息</Menu.Label>
                  <Box px="sm" py={4}>
                    <Text size="sm" fw={500} style={{ wordBreak: "break-all" }}>
                      {userName || "-"}
                    </Text>
                  </Box>
                  <Menu.Divider />
                  <Menu.Label>操作</Menu.Label>
                  <Menu.Item
                    leftSection={<IconLogout size={14} />}
                    onClick={handleLogout}>
                    退出登录
                  </Menu.Item>
                </Menu.Dropdown>
              </Menu>
            </Flex>
          </Flex>
        </AppShell.Header>
        <AppShell.Navbar className={classes.navbar}>
          <Stack justify="start" gap={4} flex={1}>
            <ScrollArea className={classes.navbarScroll}>
              {activeHeaderMenu?.items?.map((item) => {
                if (item.items?.length) {
                  if (matches) {
                    if (isOpen) {
                      return (
                        <LinksGroup
                          key={item.url}
                          item={item}
                          toggleMobile={toggleMobile}
                          routerUrl={activeHeaderMenu.url}
                          initiallyOpened={true}
                        />
                      )
                    } else {
                      const isGroupActive = pathname.startsWith(
                        `/${activeHeaderMenu.url}/${item.url}`
                      )

                      return (
                        <Menu
                          width={"auto"}
                          key={item.url + "desktop"}
                          position="right-start"
                          trigger="hover"
                          openDelay={100}
                          closeDelay={200}>
                          <Menu.Target>
                            <Tooltip
                              label={item.title || ""}
                              position="right"
                              openDelay={100}
                              closeDelay={200}
                              transitionProps={{ duration: 100 }}>
                              <UnstyledButton
                                className={cx(classes.navbarIconLink, {
                                  [classes.navbarIconLinkActive]: isGroupActive,
                                })}
                                aria-label={item.title}>
                                {item.icon ? (
                                  <ClientIcon
                                    icon={item.icon}
                                    style={{ width: 14, height: 14 }}
                                  />
                                ) : null}
                              </UnstyledButton>
                            </Tooltip>
                          </Menu.Target>
                          <Menu.Dropdown>
                            {item.items?.map((sub) =>
                              renderMenuItem(
                                sub,
                                `${activeHeaderMenu.url}/${item.url}`
                              )
                            )}
                          </Menu.Dropdown>
                        </Menu>
                      )
                    }
                  } else {
                    return (
                      <Box key={item.url + "mobile"} hiddenFrom="sm">
                        <LinksGroup
                          item={item}
                          toggleMobile={toggleMobile}
                          routerUrl={activeHeaderMenu.url}
                          initiallyOpened={true}
                        />
                      </Box>
                    )
                  }
                } else {
                  const isActive = pathname.startsWith(
                    `/${activeHeaderMenu.url}/${item.url}`
                  )

                  return (
                    <Tooltip
                      key={item.url}
                      events={{
                        hover: !isOpen && !mobileOpened,
                        focus: false,
                        touch: false,
                      }}
                      label={item.title || ""}
                      position="right"
                      openDelay={100}
                      closeDelay={200}
                      transitionProps={{ duration: 100 }}>
                      {isOpen ? (
                        <NavLink
                          // href={`/${activeHeaderMenu.url}/${item.url}`}
                          onClick={() => {
                            toggleMobile()
                            router.push(`/${activeHeaderMenu.url}/${item.url}`)
                          }}
                          noWrap={true}
                          active={isActive}
                          leftSection={
                            <ClientIcon
                              icon={item.icon}
                              style={{ width: 14, height: 14 }}
                            />
                          }
                          label={item.title}
                          styles={getShellNavLinkStyles(isActive)}
                        />
                      ) : (
                        <UnstyledButton
                          className={cx(classes.navbarIconLink, {
                            [classes.navbarIconLinkActive]: isActive,
                          })}
                          aria-label={item.title}
                          onClick={() => {
                            toggleMobile()
                            router.push(`/${activeHeaderMenu.url}/${item.url}`)
                          }}>
                          <ClientIcon
                            icon={item.icon}
                            style={{ width: 14, height: 14 }}
                          />
                        </UnstyledButton>
                      )}
                    </Tooltip>
                  )
                }
              })}
            </ScrollArea>
          </Stack>
          <Stack justify="center" gap={0} className={classes.navbarFooter}>
            <Flex justify={isOpen ? "flex-end" : "center"} align="center">
              <Box visibleFrom="sm">
                <Tooltip
                  events={{
                    hover: !isOpen,
                    focus: false,
                    touch: false,
                  }}
                  label={isOpen ? "收起菜单" : "展开菜单"}
                  position="right"
                  openDelay={100}
                  closeDelay={200}
                  transitionProps={{ duration: 100 }}>
                  <UnstyledButton
                    className={classes.navbarToggleIcon}
                    aria-label={isOpen ? "收起菜单" : "展开菜单"}
                    onClick={() => updateIsOpen(!isOpen)}>
                    {isOpen ? (
                      <IconChevronLeft size={18} />
                    ) : (
                      <IconChevronRight size={18} />
                    )}
                  </UnstyledButton>
                </Tooltip>
              </Box>
            </Flex>
          </Stack>
        </AppShell.Navbar>
        <AppShell.Main className={classes.main}>
          <Suspense fallback={<></>}>{children}</Suspense>
        </AppShell.Main>
      </AppShell>
    )
  ) : null
}
