import { useState, useCallback, useEffect, useRef } from "react";
import { Outlet, Navigate, useLocation } from "react-router-dom";
import { motion } from "framer-motion";
import Box from "@mui/material/Box";
import Drawer from "@mui/material/Drawer";
import IconButton from "@mui/material/IconButton";
import ScopedCssBaseline from "@mui/material/ScopedCssBaseline";
import { useAuth } from "../context/AuthContext";
import ThemeToggle from "./ThemeToggle";
import { setLogoutAlert } from "../utils/api";
import SidebarNav from "./SidebarNav";
import LoadingState from "./LoadingState";
import ShortcutsHelp from "../components/ShortcutsHelp";

const DRAWER_WIDTH = 248;

export default function AppShell() {
  const { isAuthenticated, loading, user, logout } = useAuth();
  const [mobileOpen, setMobileOpen] = useState(false);
  const [loggingOut, setLoggingOut] = useState(false);
  const location = useLocation();
  const logoutTimer = useRef<ReturnType<typeof setTimeout> | undefined>(
    undefined,
  );

  // Chat-style pages own the full mobile viewport: under md the shell header
  // disappears and main loses its padding — the page brings its own back
  // button. Desktop keeps the normal shell.
  const immersiveOnMobile = location.pathname === "/odin";

  const handleLogout = useCallback(() => {
    setLoggingOut(true);
    setMobileOpen(false);
    setLogoutAlert();
    // Delay so the blur/scale exit animation can play; store the id so an
    // unmount within the 400ms window cancels it (avoids logout() firing on
    // an unmounted tree).
    logoutTimer.current = setTimeout(() => logout(), 400);
  }, [logout]);

  useEffect(() => {
    return () => {
      if (logoutTimer.current) clearTimeout(logoutTimer.current);
    };
  }, []);

  if (loading) {
    return (
      <ScopedCssBaseline>
        <Box
          sx={{
            display: "flex",
            minHeight: "100dvh",
            alignItems: "center",
            justifyContent: "center",
            bgcolor: "background.default",
          }}
        >
          <LoadingState />
        </Box>
      </ScopedCssBaseline>
    );
  }
  if (!isAuthenticated) return <Navigate to="/login" replace />;
  if (user?.require2FA && !user?.totpEnabled && location.pathname !== "/") {
    return <Navigate to="/" replace />;
  }

  return (
    <ScopedCssBaseline>
      <motion.div
        initial={{ opacity: 0, scale: 0.98 }}
        animate={
          loggingOut
            ? { scale: 1.5, opacity: 0, filter: "blur(12px)" }
            : { scale: 1, opacity: 1, filter: "none" }
        }
        transition={{
          duration: loggingOut ? 0.4 : 0.25,
          ease: [0.4, 0, 0.2, 1],
        }}
        style={{ minHeight: "100dvh" }}
      >
        <Box
          sx={{
            display: "flex",
            minHeight: "100dvh",
            bgcolor: "background.default",
          }}
        >
          <Drawer
            variant="permanent"
            sx={{
              display: { xs: "none", md: "block" },
              width: DRAWER_WIDTH,
              flexShrink: 0,
              "& .MuiDrawer-paper": {
                width: DRAWER_WIDTH,
                boxSizing: "border-box",
                border: 0,
                bgcolor: "background.default",
              },
            }}
          >
            <SidebarNav onLogout={handleLogout} />
          </Drawer>

          <Drawer
            variant="temporary"
            open={mobileOpen}
            onClose={() => setMobileOpen(false)}
            ModalProps={{ keepMounted: true }}
            sx={{
              display: { xs: "block", md: "none" },
              "& .MuiDrawer-paper": {
                width: DRAWER_WIDTH,
                boxSizing: "border-box",
              },
            }}
          >
            <SidebarNav
              onNavigate={() => setMobileOpen(false)}
              onLogout={handleLogout}
            />
          </Drawer>

          <Box
            sx={{
              flex: 1,
              minWidth: 0,
              display: "flex",
              flexDirection: "column",
            }}
          >
            <Box
              component="header"
              sx={{
                display: immersiveOnMobile
                  ? { xs: "none", md: "flex" }
                  : "flex",
                alignItems: "center",
                gap: 1,
                px: 2,
                py: 1.5,
                minHeight: 64,
              }}
            >
              <IconButton
                onClick={() => setMobileOpen(true)}
                aria-label="Otevřít menu"
                sx={{ display: { md: "none" } }}
              >
                <svg
                  width="24"
                  height="24"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                  aria-hidden="true"
                >
                  <line x1="3" y1="12" x2="21" y2="12" />
                  <line x1="3" y1="6" x2="21" y2="6" />
                  <line x1="3" y1="18" x2="21" y2="18" />
                </svg>
              </IconButton>
              <Box sx={{ flex: 1 }} />
              <ThemeToggle />
            </Box>
            <Box
              component="main"
              sx={{
                flex: 1,
                px: immersiveOnMobile ? { xs: 0, md: 3 } : { xs: 2, md: 3 },
                pb: immersiveOnMobile ? { xs: 0, md: 4 } : 4,
              }}
            >
              <Outlet />
            </Box>
          </Box>
        </Box>
        <ShortcutsHelp />
      </motion.div>
    </ScopedCssBaseline>
  );
}
