import { useEffect, useMemo, useRef, useState } from 'react';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import { Layout, Menu, Typography, Button, Space, Badge } from 'antd';
import type { MenuProps } from 'antd';
import {
  RobotOutlined,
  DashboardOutlined,
  UserOutlined,
  ShoppingOutlined,
  ShopOutlined,
  TeamOutlined,
  GiftOutlined,
  CarOutlined,
  SafetyOutlined,
  LogoutOutlined,
  CloudUploadOutlined,
  FileTextOutlined,
  LockOutlined,
  SettingOutlined,
  AccountBookOutlined,
  ProjectOutlined,
} from '@ant-design/icons';
import {
  hasAnySystemSettingsPermission,
  hasAnyStoreMenuPermission,
  HQ_ADMIN_ROLES,
} from '@dukang/shared-types';
import { clearAuth, request, type HqProfile } from '../lib/api';
import { bindAdminEllipsisTitle } from '../lib/ellipsis-title';
import { AUDIT_NOTICE_CHANGED_EVENT, PACKAGE_AUDIT_CHANGED_EVENT } from '../lib/admin-events';
import { ListColumnPrefsProvider } from '../lib/ListColumnPrefsContext';

const { Header, Sider, Content } = Layout;

const HQ_ROLE_LABELS: Record<string, string> = Object.fromEntries(
  HQ_ADMIN_ROLES.map((r) => [r.value, r.label]),
);

type MenuItem = NonNullable<MenuProps['items']>[number];

const MENU_ITEMS: MenuProps['items'] = [
  { key: '/', icon: <DashboardOutlined />, label: '概览' },
  { key: '/users', icon: <UserOutlined />, label: '用户' },
  {
    key: 'products-group',
    icon: <ShoppingOutlined />,
    label: '商品',
    children: [
      { key: '/products', label: '商品列表' },
      { key: '/product-detail-templates', label: '详情模板' },
    ],
  },
  { key: '/orders', icon: <ShoppingOutlined />, label: '订单' },
  {
    key: 'partners-group',
    icon: <TeamOutlined />,
    label: '开城',
    children: [
      { key: '/cities', label: '城市' },
      { key: '/city-partners', label: '城市合伙人' },
      { key: '/city-warehouses', label: '仓库' },
      { key: '/fulfillment-providers', label: '仓配管理' },
    ],
  },
  {
    key: 'stores-group',
    icon: <ShopOutlined />,
    label: '门店',
    children: [
      { key: '/stores', label: '门店列表' },
      { key: '/store-package-audits', label: '审核通知' },
      { key: '/store-ratings', label: '门店评价' },
      { key: '/store-categories', label: '门店分类' },
      { key: '/store-accounts', label: '门店账户' },
      { key: '/store-media', label: '门店资源' },
    ],
  },
  {
    key: 'finance-group',
    icon: <AccountBookOutlined />,
    label: '财务',
    children: [
      { key: '/finance/store-bills', label: '门店账单' },
      { key: '/finance/partner-bills', label: '合伙人账单' },
      { key: '/finance/winery-bills', label: '酒厂账单' },
      { key: '/finance/logistics-bills', label: '物流对账' },
    ],
  },
  {
    key: 'benefit-group',
    icon: <GiftOutlined />,
    label: '好客权益',
    children: [
      { key: '/benefit/coupons', label: '权益券' },
      { key: '/benefit/ledgers', label: '流水' },
      { key: '/redeem-records', label: '核销记录' },
      { key: '/redeem-pending', label: '待处理核销' },
      { key: '/redeem/debug', label: '核销调试' },
    ],
  },
  {
    key: 'deliveries-group',
    icon: <CarOutlined />,
    label: '配送单',
    children: [
      { key: '/deliveries', label: '配送单列表' },
      { key: '/deliveries/xiaofeixia', label: '小飞侠联调' },
    ],
  },
  {
    key: 'tickets-group',
    icon: <CarOutlined />,
    label: '工单',
    children: [
      { key: '/tickets', label: '工单中心' },
      { key: '/tickets/support', label: '技术支持' },
    ],
  },
  { key: '/invoices', icon: <FileTextOutlined />, label: '发票' },
  { key: '/promo-codes', icon: <GiftOutlined />, label: '推广码' },
  { key: '/wechat-bindings', icon: <UserOutlined />, label: '微信绑定' },
  {
    key: 'wecom-group',
    icon: <TeamOutlined />,
    label: '企微机器人',
    children: [
      { key: '/wecom/bots', label: '智能机器人' },
      { key: '/wecom/pushes', label: '消息推送' },
    ],
  },
  { key: '/llm-configs', icon: <RobotOutlined />, label: '语言模型' },
  { key: '/knowledge-bases', icon: <FileTextOutlined />, label: '知识库' },
  {
    key: 'dev-plan-group',
    icon: <ProjectOutlined />,
    label: '开发计划',
    children: [
      { key: '/dev-plan/versions', label: '版本列表' },
      { key: '/dev-plan/tasks', label: '任务列表' },
      { key: '/dev-plan/settings', label: '开发设置' },
    ],
  },
  { key: '/resources', icon: <CloudUploadOutlined />, label: 'OSS 资源库' },
  {
    key: 'logs-group',
    icon: <FileTextOutlined />,
    label: '日志',
    children: [
      { key: '/logs/users', label: '用户日志' },
      { key: '/logs/stores', label: '商户日志' },
      { key: '/logs/partners', label: '合伙人日志' },
      { key: '/logs/hq', label: 'HQ 操作日志' },
      { key: '/logs/third-party', label: '第三方日志' },
      { key: '/logs/domain-events', label: '领域事件' },
      { key: '/logs/wecom-bots', label: '智能机器人日志' },
    ],
  },
  { key: '/hq-permissions', icon: <LockOutlined />, label: '权限分配' },
  { key: '/hq-accounts', icon: <SafetyOutlined />, label: 'HQ账户' },
  { key: '/test-whitelist', icon: <SafetyOutlined />, label: '白名单管理' },
  { key: '/system-settings', icon: <SettingOutlined />, label: '系统设置' },
];

function menuAllowed(key: string, permissionKeys: string[]): boolean {
  if (key === 'tickets-group') {
    return permissionKeys.includes('tickets') || permissionKeys.includes('tech_support');
  }
  if (key === 'stores-group') {
    return hasAnyStoreMenuPermission(permissionKeys);
  }
  if (key === 'dev-plan-group') {
    return permissionKeys.includes('dev_plan');
  }
  const map: Record<string, string | 'system_settings_any'> = {
    '/': 'dashboard',
    '/users': 'users',
    '/wechat-bindings': 'wechat_bindings',
    'products-group': 'products',
    '/products': 'products',
    '/product-detail-templates': 'products',
    '/orders': 'orders',
    '/promo-codes': 'promo_codes',
    '/wecom/bots': 'wecom_bots',
    '/wecom/pushes': 'wecom_bots',
    'wecom-group': 'wecom_bots',
    '/llm-configs': 'llm_configs',
    '/knowledge-bases': 'knowledge_bases',
    'stores-group': 'stores',
    '/stores': 'stores',
    '/store-package-audits': 'store_audits',
    '/store-ratings': 'store_ratings',
    '/store-categories': 'store_categories',
    '/store-accounts': 'store_accounts',
    '/store-media': 'store_media',
    'partners-group': 'partners',
    '/cities': 'partners',
    '/city-partners': 'partners',
    '/city-warehouses': 'partners',
    '/fulfillment-providers': 'partners',
    'finance-group': 'finance',
    '/finance/store-bills': 'finance',
    '/finance/store-withdrawals': 'finance',
    '/finance/partner-bills': 'finance',
    '/finance/winery-bills': 'finance',
    '/finance/logistics-bills': 'finance',
    'benefit-group': 'benefit',
    '/benefit/coupons': 'benefit',
    '/benefit/ledgers': 'benefit',
    '/redeem-records': 'benefit',
    '/redeem-pending': 'benefit',
    '/redeem/debug': 'benefit_debug',
    'deliveries-group': 'deliveries',
    '/deliveries': 'deliveries',
    '/deliveries/xiaofeixia': 'deliveries_debug',
    '/tickets': 'tickets',
    '/tickets/support': 'tech_support',
    'dev-plan-group': 'dev_plan',
    '/dev-plan/versions': 'dev_plan',
    '/dev-plan/tasks': 'dev_plan',
    '/dev-plan/settings': 'dev_plan',
    '/invoices': 'invoices',
    '/resources': 'resources',
    'logs-group': 'logs',
    '/logs/users': 'logs',
    '/logs/wecom-bots': 'logs',
    '/logs/stores': 'logs',
    '/logs/partners': 'logs',
    '/logs/hq': 'logs',
    '/logs/third-party': 'logs',
    '/logs/domain-events': 'logs',
    '/hq-permissions': 'hq_permissions',
    '/test-whitelist': 'test_whitelist',
    '/system-settings': 'system_settings_any',
    '/hq-accounts': 'hq_accounts',
  };
  const need = map[key];
  if (!need) return true;
  if (need === 'system_settings_any') return hasAnySystemSettingsPermission(permissionKeys);
  return permissionKeys.includes(need);
}

function filterMenuItems(items: MenuProps['items'], permissionKeys: string[]): MenuProps['items'] {
  if (!items) return items;
  return items
    .map((item) => {
      if (!item || typeof item !== 'object' || !('key' in item)) return item;
      const key = String(item.key);
      if ('children' in item && Array.isArray(item.children)) {
        if (!menuAllowed(key, permissionKeys)) return null;
        const children = filterMenuItems(item.children as MenuProps['items'], permissionKeys);
        if (!children?.length) return null;
        return { ...item, children } as MenuItem;
      }
      return menuAllowed(key, permissionKeys) ? item : null;
    })
    .filter(Boolean) as MenuProps['items'];
}

function attachAuditBadge(items: MenuProps['items'], pendingCount: number): MenuProps['items'] {
  if (!items) return items;
  return items.map((item) => {
    if (!item || typeof item !== 'object' || !('key' in item)) return item;
    if ('children' in item && Array.isArray(item.children)) {
      return {
        ...item,
        children: attachAuditBadge(item.children as MenuProps['items'], pendingCount),
      } as MenuItem;
    }
    if (String(item.key) === '/store-package-audits') {
      return {
        ...item,
        label: (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
            审核通知
            {pendingCount > 0 && <Badge count={pendingCount} size="small" />}
          </span>
        ),
      } as MenuItem;
    }
    return item;
  });
}

const IS_STAGING = import.meta.env.VITE_APP_ENV === 'staging';

export default function AdminLayout() {
  const navigate = useNavigate();
  const location = useLocation();
  const contentRef = useRef<HTMLDivElement>(null);
  const [profile, setProfile] = useState<HqProfile | null>(null);
  const [auditPendingCount, setAuditPendingCount] = useState(0);

  function refreshAuditPendingCount() {
    Promise.all([
      request<{ pendingCount: number }>('/admin/store-package-audits/summary').catch(() => ({ pendingCount: 0 })),
      request<{ pendingCount: number; packagePendingCount?: number }>('/admin/store-info-change-requests/summary').catch(() => ({ pendingCount: 0 })),
    ])
      .then(([pkg, info]) => setAuditPendingCount((pkg.pendingCount ?? 0) + (info.pendingCount ?? 0)))
      .catch(() => {});
  }

  useEffect(() => {
    request<HqProfile>('/admin/auth/me').then(setProfile).catch(() => {});
  }, []);

  useEffect(() => {
    refreshAuditPendingCount();
  }, [location.pathname]);

  useEffect(() => {
    const onChanged = () => refreshAuditPendingCount();
    window.addEventListener(PACKAGE_AUDIT_CHANGED_EVENT, onChanged);
    window.addEventListener(AUDIT_NOTICE_CHANGED_EVENT, onChanged);
    return () => {
      window.removeEventListener(PACKAGE_AUDIT_CHANGED_EVENT, onChanged);
      window.removeEventListener(AUDIT_NOTICE_CHANGED_EVENT, onChanged);
    };
  }, []);

  useEffect(() => {
    contentRef.current?.scrollTo({ top: 0, left: 0 });
  }, [location.pathname]);

  useEffect(() => {
    return bindAdminEllipsisTitle();
  }, []);

  function logout() {
    clearAuth();
    navigate('/login');
  }

  const selectedKey = location.pathname.startsWith('/promo-codes')
    ? '/promo-codes'
    : location.pathname;

  const menuItems = useMemo(() => {
    const base =
      !profile || profile.adminRole === 'SUPER_ADMIN'
        ? MENU_ITEMS
        : filterMenuItems(MENU_ITEMS, profile.permissionKeys ?? []);
    return attachAuditBadge(base, auditPendingCount);
  }, [profile, auditPendingCount]);

  return (
    <Layout style={{ height: '100vh', overflow: 'hidden' }}>
      {IS_STAGING ? (
        <div
          style={{
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            zIndex: 1100,
            background: '#d48806',
            color: '#fff',
            textAlign: 'center',
            fontSize: 13,
            fontWeight: 600,
            lineHeight: '28px',
          }}
        >
          测试环境 · staging · 数据与生产隔离 · Mock 开启
        </div>
      ) : null}
      <Sider
        breakpoint="lg"
        collapsedWidth={64}
        theme="dark"
        width={220}
        style={{ height: '100vh', overflow: 'hidden', marginTop: IS_STAGING ? 28 : 0 }}
      >
        <div style={{ display: 'flex', flexDirection: 'column', height: IS_STAGING ? 'calc(100vh - 28px)' : '100vh' }}>
          <div style={{ flexShrink: 0, padding: '16px', color: '#fff', fontWeight: 600 }}>
            杜康 HQ{IS_STAGING ? ' · 测试' : ''}
          </div>
          <div className="admin-sider-menu-scroll" style={{ flex: 1, minHeight: 0, overflow: 'auto' }}>
            <Menu
              theme="dark"
              mode="inline"
              selectedKeys={[selectedKey]}
              defaultOpenKeys={[]}
              items={menuItems}
              onClick={({ key }) => {
                if (key.startsWith('/')) navigate(key);
              }}
            />
          </div>
        </div>
      </Sider>
      <Layout
        style={{
          height: IS_STAGING ? 'calc(100vh - 28px)' : '100vh',
          marginTop: IS_STAGING ? 28 : 0,
          overflow: 'hidden',
          display: 'flex',
          flexDirection: 'column',
        }}
      >
        <Header
          style={{
            flexShrink: 0,
            background: '#fff',
            padding: '0 24px',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            borderBottom: '1px solid #f0f0f0',
          }}
        >
          <Typography.Title level={4} style={{ margin: 0 }}>
            管理后台
          </Typography.Title>
          <Space>
            <span>{profile?.name || '—'}</span>
            <span style={{ color: '#999' }}>
              {HQ_ROLE_LABELS[profile?.adminRole ?? ''] || profile?.adminRole || ''}
            </span>
            <Button type="text" icon={<LogoutOutlined />} onClick={logout}>
              退出
            </Button>
          </Space>
        </Header>
        <div
          ref={contentRef}
          className="admin-layout"
          style={{ flex: 1, minHeight: 0, overflow: 'auto' }}
        >
          <Content style={{ margin: 24 }}>
            <ListColumnPrefsProvider initial={profile?.listColumnPrefs}>
              <Outlet />
            </ListColumnPrefsProvider>
          </Content>
        </div>
      </Layout>
    </Layout>
  );
}
