import ExpandMore from "@mui/icons-material/ExpandMore";
import Inventory2Outlined from "@mui/icons-material/Inventory2Outlined";
import LockReset from "@mui/icons-material/LockReset";
import Logout from "@mui/icons-material/Logout";
import Menu from "@mui/icons-material/Menu";
import MenuOpen from "@mui/icons-material/MenuOpen";
import Person from "@mui/icons-material/Person";
import Refresh from "@mui/icons-material/Refresh";
import Search from "@mui/icons-material/Search";
import MuiMenu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";
import { lazy, Suspense, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useAppScope } from "@/app/app-scope/AppScopeProvider.jsx";
import { useAuth } from "@/app/auth/AuthProvider.jsx";
import { useTimeZone } from "@/app/timezone/TimeZoneProvider.jsx";
import { changePassword } from "@/features/auth/api";
import { AppIdentity } from "@/shared/ui/AppIdentity.jsx";
import { AdminFormDialog } from "@/shared/ui/AdminFormDialog.jsx";
import { IconButton } from "@/shared/ui/IconButton.jsx";
import { useToast } from "@/shared/ui/ToastProvider.jsx";

const SearchDialog = lazy(() => import("@/features/search/components/SearchDialog.jsx").then((module) => ({ default: module.SearchDialog })));
const emptyPasswordForm = { oldPassword: "", newPassword: "", confirmPassword: "" };

export function Header({ activeLabel, isSidebarCollapsed, menuItems = [], onRefresh, onToggleSidebar }) {
  const [searchOpen, setSearchOpen] = useState(false);
  const [searchMounted, setSearchMounted] = useState(false);
  const [userMenuAnchor, setUserMenuAnchor] = useState(null);
  const [passwordDialogOpen, setPasswordDialogOpen] = useState(false);
  const [passwordForm, setPasswordForm] = useState(emptyPasswordForm);
  const [passwordError, setPasswordError] = useState("");
  const [changingPassword, setChangingPassword] = useState(false);
  const navigate = useNavigate();
  const { logout, user } = useAuth();
  const appScope = useAppScope();
  const { showToast } = useToast();
  const { setTimeZone, timeZone, timeZoneOptions } = useTimeZone();
  const ToggleIcon = isSidebarCollapsed ? MenuOpen : Menu;
  const userMenuOpen = Boolean(userMenuAnchor);

  useEffect(() => {
    if (searchOpen) {
      setSearchMounted(true);
      return undefined;
    }

    const timeout = window.setTimeout(() => setSearchMounted(false), 280);
    return () => window.clearTimeout(timeout);
  }, [searchOpen]);

  const openSearch = () => {
    setSearchMounted(true);
    setSearchOpen(true);
  };

  const closeUserMenu = () => {
    setUserMenuAnchor(null);
  };

  const openPasswordDialog = () => {
    closeUserMenu();
    setPasswordForm(emptyPasswordForm);
    setPasswordError("");
    setPasswordDialogOpen(true);
  };

  const closePasswordDialog = () => {
    if (changingPassword) {
      return;
    }
    setPasswordDialogOpen(false);
    setPasswordError("");
  };

  const handleLogout = async () => {
    closeUserMenu();
    await logout();
    navigate("/login", { replace: true });
  };

  const handlePasswordFieldChange = (field) => (event) => {
    setPasswordForm((current) => ({ ...current, [field]: event.target.value }));
    if (passwordError) {
      setPasswordError("");
    }
  };

  const handlePasswordSubmit = async (event) => {
    event.preventDefault();
    const { oldPassword, newPassword, confirmPassword } = passwordForm;

    if (!oldPassword || !newPassword || !confirmPassword) {
      setPasswordError("请填写原密码、新密码和确认密码");
      return;
    }
    if (newPassword.length < 6) {
      setPasswordError("新密码至少 6 位");
      return;
    }
    if (newPassword.length > 72) {
      setPasswordError("新密码不能超过 72 位");
      return;
    }
    if (newPassword !== confirmPassword) {
      setPasswordError("两次输入的新密码不一致");
      return;
    }

    setChangingPassword(true);
    try {
      await changePassword({ oldPassword, newPassword });
      showToast("密码已修改，请重新登录", "success");
      await logout();
      navigate("/login", { replace: true });
    } catch (err) {
      setPasswordError(err.message || "修改密码失败");
    } finally {
      setChangingPassword(false);
    }
  };

  const handleSearchSelect = (result) => {
    if (result?.target) {
      navigate(result.target);
    }
  };

  const refresh = () => {
    onRefresh();
    showToast("已刷新当前页面", "success");
  };

  return (
    <header className="header">
      <div className="brand">
        <div className="brand-mark">
          <Inventory2Outlined fontSize="small" />
        </div>
        <div className="brand-text">
          <span className="brand-title">HYApp 管理平台</span>
          <span className="brand-meta">Admin Platform</span>
        </div>
      </div>

      <div className="header-tools">
        <div className="header-left-tools">
          <IconButton label={isSidebarCollapsed ? "展开菜单" : "收起菜单"} onClick={onToggleSidebar}>
            <ToggleIcon fontSize="small" />
          </IconButton>
          <div className="header-location">{activeLabel}</div>
        </div>

        <div className="header-right-tools">
          <TextField
            className="app-switch"
            disabled={appScope.loading || !appScope.hasAppAccess}
            label="应用"
            select
            size="small"
            slotProps={{ select: { displayEmpty: true } }}
            value={appScope.hasAppAccess ? appScope.appCode : ""}
            onChange={(event) => appScope.setAppCode(event.target.value)}
          >
            {appScope.hasAppAccess ? (
              appScope.apps.map((app) => (
                <MenuItem key={app.appCode} value={app.appCode}>
                  <AppIdentity app={app} size="small" />
                </MenuItem>
              ))
            ) : (
              <MenuItem value="">通用</MenuItem>
            )}
          </TextField>
          <TextField
            className="timezone-switch"
            label="时区"
            select
            size="small"
            slotProps={{ htmlInput: { "aria-label": "显示时区" } }}
            value={timeZone}
            onChange={(event) => setTimeZone(event.target.value)}
          >
            {timeZoneOptions.map((option) => (
              <MenuItem key={option.value} value={option.value}>
                {option.label}
              </MenuItem>
            ))}
          </TextField>
          <button className="search-trigger" type="button" onClick={openSearch}>
            <span className="search-trigger__label">
              <Search fontSize="inherit" />
              <span>搜索</span>
            </span>
            <span className="search-trigger__value">搜索菜单、用户、角色...</span>
          </button>
          <IconButton label="刷新" onClick={refresh}>
            <Refresh fontSize="small" />
          </IconButton>
          <button className="user-pill" type="button" onClick={(event) => setUserMenuAnchor(event.currentTarget)}>
            <Person fontSize="small" />
            <span>{user?.name || user?.account || "admin"}</span>
            <ExpandMore fontSize="inherit" />
          </button>
          <MuiMenu
            anchorEl={userMenuAnchor}
            className="user-menu"
            onClose={closeUserMenu}
            open={userMenuOpen}
            transformOrigin={{ horizontal: "right", vertical: "top" }}
            anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
          >
            <MenuItem className="user-menu__item" onClick={openPasswordDialog}>
              <LockReset fontSize="small" />
              修改密码
            </MenuItem>
            <MenuItem className="user-menu__item" onClick={handleLogout}>
              <Logout fontSize="small" />
              退出
            </MenuItem>
          </MuiMenu>
        </div>
      </div>

      {searchMounted ? (
        <Suspense fallback={null}>
          <SearchDialog menuItems={menuItems} open={searchOpen} onClose={() => setSearchOpen(false)} onSelect={handleSearchSelect} />
        </Suspense>
      ) : null}
      <AdminFormDialog
        loading={changingPassword}
        onClose={closePasswordDialog}
        onSubmit={handlePasswordSubmit}
        open={passwordDialogOpen}
        size="narrow"
        submitDisabled={
          changingPassword ||
          !passwordForm.oldPassword ||
          !passwordForm.newPassword ||
          !passwordForm.confirmPassword
        }
        submitLabel="确认修改"
        title="修改密码"
      >
        <TextField
          autoComplete="current-password"
          autoFocus
          disabled={changingPassword}
          error={Boolean(passwordError)}
          helperText={passwordError || "修改成功后将自动退出登录"}
          label="原密码"
          onChange={handlePasswordFieldChange("oldPassword")}
          required
          type="password"
          value={passwordForm.oldPassword}
        />
        <TextField
          autoComplete="new-password"
          disabled={changingPassword}
          label="新密码"
          onChange={handlePasswordFieldChange("newPassword")}
          required
          type="password"
          value={passwordForm.newPassword}
        />
        <TextField
          autoComplete="new-password"
          disabled={changingPassword}
          label="确认新密码"
          onChange={handlePasswordFieldChange("confirmPassword")}
          required
          type="password"
          value={passwordForm.confirmPassword}
        />
      </AdminFormDialog>
    </header>
  );
}
