import {
  ApiOutlined,
  CheckCircleOutlined,
  CloudServerOutlined,
  CloseOutlined,
  DashboardOutlined,
  GlobalOutlined,
  InboxOutlined,
  KeyOutlined,
  MailOutlined,
  MenuOutlined,
  SafetyCertificateOutlined,
  SendOutlined,
  SettingOutlined,
  UserOutlined,
  WarningOutlined
} from '@ant-design/icons';
import {
  Avatar,
  Button,
  Drawer,
  Dropdown,
  Layout,
  Menu,
  Select,
  Space,
  Tag,
  Tooltip,
  Typography
} from 'antd';
import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';

import { useAppContext } from '../frontend/app-context';
import { useI18n } from '../frontend/i18n/react';
import { useMediaQuery } from '../frontend/use-media-query';

const { Header, Sider, Content } = Layout;

interface NavigationItem {
  path: string;
  labelKey: string;
  icon: ReactNode;
  adminOnly?: boolean;
}

interface NavigationGroup {
  key: string;
  labelKey: string;
  items: NavigationItem[];
}

export const navigationGroups: NavigationGroup[] = [
  {
    key: 'operations',
    labelKey: 'nav.group.operations',
    items: [
      { path: '/overview', labelKey: 'nav.overview', icon: <DashboardOutlined /> },
      { path: '/activity', labelKey: 'nav.activity', icon: <SendOutlined /> },
      { path: '/domains', labelKey: 'nav.domains', icon: <GlobalOutlined /> },
      { path: '/inbox', labelKey: 'nav.inbox', icon: <InboxOutlined /> }
    ]
  },
  {
    key: 'integrations',
    labelKey: 'nav.group.integrations',
    items: [
      { path: '/integrations/smtp', labelKey: 'nav.smtpIntegration', icon: <MailOutlined /> },
      { path: '/integrations/api-keys', labelKey: 'nav.apiKeys', icon: <KeyOutlined /> },
      { path: '/integrations/webhooks', labelKey: 'nav.webhooks', icon: <ApiOutlined /> },
      { path: '/integrations/dns', labelKey: 'nav.dnsIntegration', icon: <CloudServerOutlined /> }
    ]
  },
  {
    key: 'system',
    labelKey: 'nav.group.system',
    items: [
      { path: '/admin/users', labelKey: 'nav.adminCenter', icon: <SafetyCertificateOutlined />, adminOnly: true },
      { path: '/settings', labelKey: 'nav.settings', icon: <SettingOutlined />, adminOnly: true }
    ]
  }
];

export function visibleNavigation(isAdmin: boolean) {
  return navigationGroups
    .map((group) => ({
      ...group,
      items: group.items.filter((item) => !item.adminOnly || isAdmin)
    }))
    .filter((group) => group.items.length > 0);
}

export function navigationSelection(pathname: string) {
  if (pathname.startsWith('/activity')) return '/activity';
  if (pathname.startsWith('/domains')) return '/domains';
  if (pathname.startsWith('/inbox')) return '/inbox';
  if (pathname.startsWith('/integrations/smtp')) return '/integrations/smtp';
  if (pathname.startsWith('/integrations/api-keys')) return '/integrations/api-keys';
  if (pathname.startsWith('/integrations/webhooks')) return '/integrations/webhooks';
  if (pathname.startsWith('/integrations/dns')) return '/integrations/dns';
  if (pathname.startsWith('/admin')) return '/admin/users';
  if (pathname.startsWith('/settings')) return '/settings';
  return '/overview';
}

export function AdminLayout() {
  const { locale, locales, setLocale, t } = useI18n();
  const { user, config, logout } = useAppContext();
  const location = useLocation();
  const navigate = useNavigate();
  const isDesktop = useMediaQuery('(min-width: 1024px)');
  const [mobileNavigationOpen, setMobileNavigationOpen] = useState(false);
  const mainRef = useRef<HTMLElement>(null);
  const isAdmin = user?.role === 'admin';

  useEffect(() => {
    setMobileNavigationOpen(false);
    const frame = window.requestAnimationFrame(() => mainRef.current?.focus({ preventScroll: true }));
    return () => window.cancelAnimationFrame(frame);
  }, [location.pathname]);

  useEffect(() => {
    if (isDesktop) setMobileNavigationOpen(false);
  }, [isDesktop]);

  const menuItems = useMemo(() => visibleNavigation(isAdmin).map((group) => ({
    type: 'group' as const,
    key: group.key,
    label: t(group.labelKey),
    children: group.items.map((item) => ({
      key: item.path,
      icon: item.icon,
      label: t(item.labelKey)
    }))
  })), [isAdmin, t]);

  const menu = (
    <Menu
      theme="dark"
      mode="inline"
      selectedKeys={[navigationSelection(location.pathname)]}
      items={menuItems}
      onClick={({ key }) => navigate(key)}
      className="admin-menu"
    />
  );

  const environmentReady = Boolean(config?.mailHostname && config?.sendingIp);
  const environmentDetails = config
    ? `${config.mailHostname} · ${config.sendingIp || t('common.unsetSendingIp')}`
    : t('common.loadingConfig');

  return (
    <Layout className="admin-layout">
      <a className="skip-link" href="#main-content">{t('shell.skipToMain')}</a>
      <Sider width={252} className="admin-sider desktop-sider" trigger={null}>
        <NavigationPanel menu={menu} userName={user?.username} role={user?.role} />
      </Sider>

      <Drawer
        className="mobile-navigation-drawer"
        placement="left"
        width={288}
        open={mobileNavigationOpen && !isDesktop}
        onClose={() => setMobileNavigationOpen(false)}
        closable={false}
        styles={{ body: { padding: 0, background: '#0F172A' } }}
        aria-label={t('shell.mainNavigation')}
      >
        <NavigationPanel
          menu={menu}
          userName={user?.username}
          role={user?.role}
          onClose={() => setMobileNavigationOpen(false)}
          closeLabel={t('shell.closeNavigation')}
        />
      </Drawer>

      <Layout className="admin-main-layout">
        <Header className="admin-header">
          <Space size={12} className="header-status">
            <Button
              className="mobile-nav-trigger"
              type="text"
              icon={<MenuOutlined />}
              aria-label={t('shell.openNavigation')}
              onClick={() => setMobileNavigationOpen(true)}
            />
            <Tooltip title={environmentDetails}>
              <Tag
                className="environment-status"
                aria-label={environmentReady ? t('shell.envReady') : t('shell.envNeedsSetup')}
                icon={environmentReady ? <CheckCircleOutlined /> : <WarningOutlined />}
                color={environmentReady ? 'success' : 'warning'}
              >
                <span className="environment-status__label">
                  {environmentReady ? t('shell.envReady') : t('shell.envNeedsSetup')}
                </span>
              </Tag>
            </Tooltip>
          </Space>

          <Space size={8} className="header-actions">
            <Select
              aria-label="Language"
              value={locale}
              options={locales}
              onChange={setLocale}
              className="language-select"
            />
            <Dropdown
              trigger={['click']}
              menu={{
                items: [
                  {
                    key: 'account',
                    label: (
                      <div className="account-menu-summary">
                        <Typography.Text strong>{user?.username || t('common.user')}</Typography.Text>
                        <Typography.Text type="secondary">{user?.email || '—'}</Typography.Text>
                      </div>
                    ),
                    disabled: true
                  },
                  ...(isAdmin ? [{ key: 'settings', label: t('nav.settings'), onClick: () => navigate('/settings') }] : []),
                  { type: 'divider' as const },
                  { key: 'logout', label: t('common.logout'), onClick: () => void logout() }
                ]
              }}
            >
              <Button className="user-button" aria-label={t('shell.accountMenu')}>
                <Space size={8}>
                  <Avatar size={24} icon={<UserOutlined />} />
                  <span className="user-button__name" title={user?.username || t('common.user')}>
                    {user?.username || t('common.user')}
                  </span>
                </Space>
              </Button>
            </Dropdown>
          </Space>
        </Header>

        <Content
          id="main-content"
          ref={mainRef}
          tabIndex={-1}
          className="admin-content"
        >
          <Outlet />
        </Content>
      </Layout>
    </Layout>
  );
}

function NavigationPanel({
  menu,
  userName,
  role,
  onClose,
  closeLabel
}: {
  menu: ReactNode;
  userName?: string;
  role?: string;
  onClose?: () => void;
  closeLabel?: string;
}) {
  return (
    <div className="admin-sider-inner">
      <div className="brand">
        <div className="brand-logo" aria-hidden="true">MH</div>
        <div>
          <div className="brand-title">MailHub</div>
          <div className="brand-subtitle">Delivery Operations</div>
        </div>
        {onClose ? (
          <Button
            type="text"
            className="mobile-nav-close"
            icon={<CloseOutlined />}
            aria-label={closeLabel}
            style={{ minHeight: 44, minWidth: 44 }}
            onClick={onClose}
          />
        ) : null}
      </div>
      {menu}
      {userName ? (
        <div className="admin-sider-footer">
          <Avatar size={28} icon={<UserOutlined />} className="sider-user-avatar" />
          <div className="sider-user-meta">
            <div className="sider-user-name">{userName}</div>
            <div className="sider-user-role">{role || '—'}</div>
          </div>
        </div>
      ) : null}
    </div>
  );
}
