import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart' as lucide;

import '../../features/approvals/history/presentation/pages/approval_history_page.dart';
import '../../features/approvals/request/presentation/pages/approval_request_page.dart';
import '../../features/approvals/step/presentation/pages/approval_step_page.dart';
import '../../features/approvals/template/presentation/pages/approval_template_page.dart';
import '../../features/dashboard/presentation/pages/dashboard_page.dart';
import '../../features/inventory/inbound/presentation/pages/inbound_page.dart';
import '../../features/inventory/outbound/presentation/pages/outbound_page.dart';
import '../../features/inventory/rental/presentation/pages/rental_page.dart';
import '../../features/inventory/summary/presentation/pages/inventory_summary_page.dart';
import '../../features/masters/customer/presentation/pages/customer_page.dart';
import '../../features/masters/group/presentation/pages/group_page.dart';
import '../../features/masters/group_permission/presentation/pages/group_permission_page.dart';
import '../../features/masters/menu/presentation/pages/menu_page.dart';
import '../../features/masters/product/presentation/pages/product_page.dart';
import '../../features/masters/user/presentation/pages/user_page.dart';
import '../../features/masters/vendor/presentation/pages/vendor_page.dart';
import '../../features/masters/warehouse/presentation/pages/warehouse_page.dart';
import '../../features/reporting/presentation/pages/reporting_page.dart';
import '../../features/util/postal_search/presentation/pages/postal_search_page.dart';
import '../permissions/permission_manager.dart';
import '../permissions/permission_resources.dart';
import '../routing/auth_guard.dart';
import 'route_paths.dart';

typedef MenuPageBuilder = Widget Function(BuildContext context, GoRouterState state);

/// 메뉴 코드 ↔ 라우트 정의를 연결하는 매니페스트.
class MenuRouteDefinition {
  const MenuRouteDefinition({
    required this.menuCode,
    this.aliases = const {},
    required this.routePath,
    required this.defaultLabel,
    required this.icon,
    required this.builder,
    this.defaultOrder = 0,
    this.extraRequirements = const [],
    this.showInNavigation = true,
  });

  final String menuCode;
  final Set<String> aliases;
  final String routePath;
  final String defaultLabel;
  final IconData icon;
  final MenuPageBuilder builder;
  final int defaultOrder;
  final List<PermissionRequirement> extraRequirements;
  final bool showInNavigation;

  Iterable<String> get codes sync* {
    yield menuCode;
    for (final alias in aliases) {
      yield alias;
    }
  }

  Iterable<PermissionRequirement> get requirements sync* {
    yield PermissionRequirement(resource: routePath);
    for (final requirement in extraRequirements) {
      yield requirement;
    }
  }

  bool canAccess(PermissionManager manager) {
    for (final requirement in requirements) {
      if (!manager.can(requirement.resource, requirement.action)) {
        return false;
      }
    }
    return true;
  }

  RouteGuard? buildGuard({String fallback = dashboardRoutePath}) {
    final guards = requirements.toList(growable: false);
    if (guards.isEmpty) {
      return null;
    }
    return AuthGuard.requireAll(requirements: guards, fallback: fallback);
  }
}

final List<MenuRouteDefinition> menuRouteDefinitions = [
  MenuRouteDefinition(
    menuCode: 'dashboard',
    routePath: dashboardRoutePath,
    defaultLabel: '대시보드',
    icon: lucide.LucideIcons.layoutDashboard,
    builder: (context, state) => const DashboardPage(),
    defaultOrder: 10,
  ),
  MenuRouteDefinition(
    menuCode: 'inventory.summary',
    aliases: {'inventory'},
    routePath: inventorySummaryRoutePath,
    defaultLabel: '재고 현황',
    icon: lucide.LucideIcons.chartNoAxesColumnIncreasing,
    builder: (context, state) => InventorySummaryPage(routeUri: state.uri),
    defaultOrder: 20,
    extraRequirements: const [
      PermissionRequirement(resource: PermissionResources.inventoryScope),
    ],
  ),
  MenuRouteDefinition(
    menuCode: 'inventory.receipts',
    aliases: {'inventory.inbound'},
    routePath: inventoryReceiptsRoutePath,
    defaultLabel: '입고',
    icon: lucide.LucideIcons.packagePlus,
    builder: (context, state) => InboundPage(routeUri: state.uri),
    defaultOrder: 21,
  ),
  MenuRouteDefinition(
    menuCode: 'inventory.issues',
    aliases: {'inventory.outbound'},
    routePath: inventoryIssuesRoutePath,
    defaultLabel: '출고',
    icon: lucide.LucideIcons.packageMinus,
    builder: (context, state) => OutboundPage(routeUri: state.uri),
    defaultOrder: 22,
  ),
  MenuRouteDefinition(
    menuCode: 'inventory.rentals',
    routePath: inventoryRentalsRoutePath,
    defaultLabel: '대여',
    icon: lucide.LucideIcons.handshake,
    builder: (context, state) => RentalPage(routeUri: state.uri),
    defaultOrder: 23,
  ),
  MenuRouteDefinition(
    menuCode: 'inventory.vendors',
    aliases: {'inventory.manufacturers', 'masters.vendors'},
    routePath: inventoryVendorsRoutePath,
    defaultLabel: '제조사 관리',
    icon: lucide.LucideIcons.factory,
    builder: (context, state) => VendorPage(routeUri: state.uri),
    defaultOrder: 30,
  ),
  MenuRouteDefinition(
    menuCode: 'inventory.products',
    aliases: {'inventory.models', 'masters.products'},
    routePath: inventoryProductsRoutePath,
    defaultLabel: '제품 관리',
    icon: lucide.LucideIcons.box,
    builder: (context, state) => ProductPage(routeUri: state.uri),
    defaultOrder: 31,
  ),
  MenuRouteDefinition(
    menuCode: 'inventory.warehouses',
    aliases: {'masters.warehouses'},
    routePath: inventoryWarehousesRoutePath,
    defaultLabel: '입고지 관리',
    icon: lucide.LucideIcons.warehouse,
    builder: (context, state) => WarehousePage(routeUri: state.uri),
    defaultOrder: 32,
  ),
  MenuRouteDefinition(
    menuCode: 'inventory.customers',
    aliases: {'masters.customers'},
    routePath: inventoryCustomersRoutePath,
    defaultLabel: '회사 관리',
    icon: lucide.LucideIcons.building,
    builder: (context, state) => CustomerPage(routeUri: state.uri),
    defaultOrder: 33,
  ),
  MenuRouteDefinition(
    menuCode: 'settings.users',
    aliases: {'masters.users'},
    routePath: settingsUsersRoutePath,
    defaultLabel: '사용자 관리',
    icon: lucide.LucideIcons.users,
    builder: (context, state) => const UserPage(),
    defaultOrder: 40,
  ),
  MenuRouteDefinition(
    menuCode: 'settings.groups',
    aliases: {'masters.groups'},
    routePath: settingsGroupsRoutePath,
    defaultLabel: '그룹 관리',
    icon: lucide.LucideIcons.layers,
    builder: (context, state) => const GroupPage(),
    defaultOrder: 41,
  ),
  MenuRouteDefinition(
    menuCode: 'settings.menus',
    aliases: {'masters.menus'},
    routePath: settingsMenusRoutePath,
    defaultLabel: '메뉴 관리',
    icon: lucide.LucideIcons.listTree,
    builder: (context, state) => const MenuPage(),
    defaultOrder: 42,
  ),
  MenuRouteDefinition(
    menuCode: 'settings.group_permissions',
    aliases: {'settings.group-permissions', 'masters.group-permissions'},
    routePath: settingsGroupPermissionsRoutePath,
    defaultLabel: '그룹 메뉴 권한',
    icon: lucide.LucideIcons.shieldCheck,
    builder: (context, state) => const GroupPermissionPage(),
    defaultOrder: 43,
  ),
  MenuRouteDefinition(
    menuCode: 'approvals.requests',
    aliases: {'approvals'},
    routePath: approvalsRequestsRoutePath,
    defaultLabel: '결재 관리',
    icon: lucide.LucideIcons.fileCheck,
    builder: (context, state) => ApprovalRequestPage(routeUri: state.uri),
    defaultOrder: 50,
  ),
  MenuRouteDefinition(
    menuCode: 'approvals.steps',
    routePath: approvalsStepsRoutePath,
    defaultLabel: '결재 단계',
    icon: lucide.LucideIcons.workflow,
    builder: (context, state) => const ApprovalStepPage(),
    defaultOrder: 51,
  ),
  MenuRouteDefinition(
    menuCode: 'approvals.history',
    routePath: approvalsHistoryRoutePath,
    defaultLabel: '결재 이력',
    icon: lucide.LucideIcons.history,
    builder: (context, state) => const ApprovalHistoryPage(),
    defaultOrder: 52,
  ),
  MenuRouteDefinition(
    menuCode: 'approvals.templates',
    routePath: approvalsTemplatesRoutePath,
    defaultLabel: '결재 템플릿',
    icon: lucide.LucideIcons.fileSpreadsheet,
    builder: (context, state) => const ApprovalTemplatePage(),
    defaultOrder: 53,
  ),
  MenuRouteDefinition(
    menuCode: 'utilities.zipcodes',
    aliases: {'utilities.postal-search'},
    routePath: utilitiesPostalSearchRoutePath,
    defaultLabel: '우편번호 검색',
    icon: lucide.LucideIcons.search,
    builder: (context, state) => const PostalSearchPage(),
    defaultOrder: 60,
  ),
  MenuRouteDefinition(
    menuCode: 'reports.overview',
    aliases: {'reports'},
    routePath: reportsOverviewRoutePath,
    defaultLabel: '보고서',
    icon: lucide.LucideIcons.fileDown,
    builder: (context, state) => const ReportingPage(),
    defaultOrder: 70,
  ),
];

/// menu_code → 정의를 빠르게 조회하기 위한 맵.
final Map<String, MenuRouteDefinition> menuRouteDefinitionByCode = {
  for (final definition in menuRouteDefinitions)
    for (final code in definition.codes) code: definition,
};
