import { Link, usePage } from '@inertiajs/react';
import {
    AlertTriangle,
    ArrowDownToLine,
    ArrowUpFromLine,
    BookOpen,
    Boxes,
    Briefcase,
    Building,
    Building2,
    CalendarDays,
    ClipboardList,
    FileClock,
    FileSpreadsheet,
    FolderKanban,
    History,
    LayoutGrid,
    List,
    MapPin,
    Network,
    Archive,
    PieChart,
    Shield,
    ShoppingCart,
    Tags,
    Truck,
    UserCircle,
    Users,
    Warehouse,
    Wallet,
} from 'lucide-react';
import type { LucideIcon } from 'lucide-react';
import AppLogo from '@/components/app-logo';
import { NavFooter } from '@/components/nav-footer';
import { NavMain } from '@/components/nav-main';
import { NavUser } from '@/components/nav-user';
import {
    Sidebar,
    SidebarContent,
    SidebarFooter,
    SidebarHeader,
    SidebarMenu,
    SidebarMenuButton,
    SidebarMenuItem,
} from '@/components/ui/sidebar';
import { useCan, useCanAny } from '@/hooks/use-can';
import { dashboard } from '@/routes';
import { index as accountingProcurementIndex } from '@/routes/admin/accounting-procurement';
import {
    expenses as dashboardsExpenses,
    financial as dashboardsFinancial,
    payments as dashboardsPayments,
    services as dashboardsServices,
} from '@/routes/admin/dashboards';
import { index as auditLogsIndex } from '@/routes/admin/audit-logs';
import { index as budgetsIndex } from '@/routes/admin/budgets';
import { index as categoriesIndex } from '@/routes/admin/categories';
import { index as costCentersIndex } from '@/routes/admin/cost-centers';
import { index as chartOfAccountsIndex } from '@/routes/admin/chart-of-accounts';
import { index as customersIndex } from '@/routes/admin/customers';
import { index as departmentsIndex } from '@/routes/admin/departments';
import { index as employeesIndex } from '@/routes/admin/employees';
import { index as employeeLoansIndex } from '@/routes/admin/employee-loans';
import { index as hrArchivesIndex } from '@/routes/admin/hr-archives';
import { index as payrollRunsIndex } from '@/routes/admin/payroll-runs';
import { index as payrollTaxSettingsIndex } from '@/routes/admin/payroll-tax-settings';
import { index as jobPositionsIndex } from '@/routes/admin/job-positions';
import { index as expenseReportsIndex } from '@/routes/admin/expense-reports';
import { index as fixedAssetsIndex } from '@/routes/admin/fixed-assets';
import { index as inventoriesIndex } from '@/routes/admin/inventories';
import { index as journalEntriesIndex } from '@/routes/admin/journal-entries';
import {
    create as invoicesCreate,
    index as invoicesIndex,
} from '@/routes/admin/invoices';
import {
    calendar as leaveRequestsCalendar,
    index as leaveRequestsIndex,
} from '@/routes/admin/leave-requests';
import { index as leaveTypesIndex } from '@/routes/admin/leave-types';
import { index as organizationChartIndex } from '@/routes/admin/organization-chart';
import { index as productsIndex } from '@/routes/admin/products';
import { index as projectsIndex, kanban } from '@/routes/admin/projects';
import { index as servicesIndex } from '@/routes/admin/services';
import { index as purchaseOrdersIndex } from '@/routes/admin/purchase-orders';
import { index as rolesIndex } from '@/routes/admin/roles';
import { index as sitesIndex } from '@/routes/admin/sites';
import { edit as companySettingsEdit } from '@/routes/admin/settings/company';
import { index as stockAlertsIndex } from '@/routes/admin/stock-alerts';
import {
    create as stockExitsCreate,
    index as stockExitsIndex,
} from '@/routes/admin/stock-exits';
import { index as stockLevelsIndex } from '@/routes/admin/stock-levels';
import { index as stockMovementsIndex } from '@/routes/admin/stock-movements';
import {
    create as stockReturnsCreate,
    index as stockReturnsIndex,
} from '@/routes/admin/stock-returns';
import { index as suppliersIndex } from '@/routes/admin/suppliers';
import { index as supplierInvoicesIndex } from '@/routes/admin/supplier-invoices';
import { index as taxReportsIndex } from '@/routes/admin/tax-reports';
import { index as tasksIndex } from '@/routes/admin/tasks';
import { index as ticketsIndex } from '@/routes/admin/tickets';
import { index as usersIndex } from '@/routes/admin/users';
import { index as warehousesIndex } from '@/routes/admin/warehouses';
import {
    create as createReceipt,
    index as receiptsIndex,
} from '@/routes/admin/warehouses/receipts';
import type { Auth, NavItem } from '@/types';

const footerNavItems: NavItem[] = [];

type NavSection = {
    label: string;
    items: NavItem[];
};

function buildListCreateNav({
    title,
    icon,
    listHref,
    createHref,
    canList,
    canCreate,
    listLabel = 'Liste',
    createLabel = 'Nouveau',
}: {
    title: string;
    icon: LucideIcon;
    listHref: NavItem['href'];
    createHref: NavItem['href'];
    canList: boolean;
    canCreate: boolean;
    listLabel?: string;
    createLabel?: string;
}): NavItem | null {
    const children: NavItem[] = [
        ...(canCreate
            ? [{ title: createLabel, href: createHref } satisfies NavItem]
            : []),
        ...(canList
            ? [{ title: listLabel, href: listHref } satisfies NavItem]
            : []),
    ];

    if (children.length === 0) {
        return null;
    }

    if (children.length === 1) {
        return {
            title,
            href: children[0].href,
            icon,
        };
    }

    return {
        title,
        href: canList ? listHref : createHref,
        icon,
        items: children,
    };
}

export function AppSidebar() {
    const { auth } = usePage<{ auth: Auth }>().props;
    const managedWarehouses = auth.user?.managed_warehouses ?? [];

    const canManageUsers = useCanAny([
        'users.view',
        'users.create',
        'users.update',
        'users.delete',
    ]);
    const canManageRoles = useCanAny([
        'roles.view',
        'roles.create',
        'roles.update',
        'roles.delete',
    ]);
    const canManageWarehouses = useCanAny([
        'warehouses.view',
        'warehouses.create',
        'warehouses.update',
        'warehouses.delete',
    ]);
    const isWarehouseManager =
        managedWarehouses.length > 0 && !canManageWarehouses;
    const canViewStockExits = useCan('stock_exits.view');
    const canCreateStockExits = useCan('stock_exits.create');
    const canViewStockReturns = useCan('stock_returns.view');
    const canCreateStockReturns = useCan('stock_returns.create');
    const canManageCategories = useCanAny([
        'categories.view',
        'categories.create',
        'categories.update',
        'categories.delete',
    ]);
    const canManageProducts = useCanAny([
        'products.view',
        'products.create',
        'products.update',
        'products.delete',
    ]);
    const canManageServices = useCanAny([
        'services.view',
        'services.create',
        'services.update',
        'services.delete',
    ]);
    const canManageSuppliers = useCanAny([
        'suppliers.view',
        'suppliers.create',
        'suppliers.update',
        'suppliers.delete',
    ]);
    const canViewPurchaseOrders = useCan('purchase-orders.view');
    const canViewExpenses = useCan('expenses.view');
    const canManageCustomers = useCanAny([
        'customers.view',
        'customers.create',
    ]);
    const canViewInvoices = useCan('invoices.view');
    const canCreateInvoices = useCan('invoices.create');
    const canViewProjects = useCan('projects.view');
    const canViewTickets = useCan('tickets.view');
    const canViewTasks = useCan('tasks.view');
    const canViewKanban = canViewTasks || canViewTickets;
    const canManageEmployees = useCanAny([
        'employees.view',
        'employees.create',
        'employees.update',
        'employees.delete',
    ]);
    const canViewOrganizationChart = useCan('organization-chart.view');
    const canManageDepartments = useCanAny([
        'departments.view',
        'departments.create',
        'departments.update',
        'departments.delete',
    ]);
    const canManageSites = useCanAny([
        'sites.view',
        'sites.create',
        'sites.update',
        'sites.delete',
    ]);
    const canManageJobPositions = useCanAny([
        'job-positions.view',
        'job-positions.create',
        'job-positions.update',
        'job-positions.delete',
    ]);
    const canViewLeave = useCan('leave.view');
    const canViewPayroll = useCanAny(['payroll.view', 'employee-loans.view']);
    const canViewPayrollRuns = useCan('payroll.view');
    const canViewEmployeeLoans = useCan('employee-loans.view');
    const canViewPayrollTaxSettings = useCan('payroll-tax-settings.view');
    const canManageLeaveTypes = useCanAny([
        'leave-types.view',
        'leave-types.create',
        'leave-types.update',
        'leave-types.delete',
    ]);
    const canManageSettings = useCanAny(['settings.view', 'settings.update']);
    const canViewChartOfAccounts = useCan('chart-of-accounts.view');
    const canViewJournalEntries = useCan('journal-entries.view');
    const canViewCostCenters = useCan('cost-centers.view');
    const canViewBudgets = useCan('budgets.view');
    const canViewTaxReports = useCan('tax-reports.view');
    const canViewAccountingProcurement = useCan('accounting-procurement.view');
    const canViewDashboards = useCan('dashboards.view');
    const canViewFixedAssets = useCan('fixed-assets.view');
    const canViewAuditLogs = useCan('audit-logs.view');

    const generalItems: NavItem[] = [
        {
            title: 'Tableau de bord',
            href: dashboard(),
            icon: LayoutGrid,
        },
    ];

    const catalogSubItems: NavItem[] = [
        ...(canManageCategories
            ? [{ title: 'Catégories', href: categoriesIndex() } satisfies NavItem]
            : []),
        ...(canManageProducts
            ? [{ title: 'Produits', href: productsIndex() } satisfies NavItem]
            : []),
        ...(canManageServices
            ? [{ title: 'Prestations', href: servicesIndex() } satisfies NavItem]
            : []),
    ];

    const catalogItems: NavItem[] =
        catalogSubItems.length > 0
            ? [
                  {
                      title: 'Catalogue',
                      href: catalogSubItems[0].href,
                      icon: Tags,
                      items: catalogSubItems,
                  } satisfies NavItem,
              ]
            : [];

    const stockExitsNav = buildListCreateNav({
        title: 'Sorties',
        icon: ArrowUpFromLine,
        listHref: stockExitsIndex(),
        createHref: stockExitsCreate(),
        canList: canViewStockExits,
        canCreate: canCreateStockExits,
        createLabel: 'Nouvelle sortie',
        listLabel: 'Liste',
    });

    const stockReturnsNav = buildListCreateNav({
        title: 'Retours',
        icon: ArrowDownToLine,
        listHref: stockReturnsIndex(),
        createHref: stockReturnsCreate(),
        canList: canViewStockReturns,
        canCreate: canCreateStockReturns,
        createLabel: 'Nouveau retour',
        listLabel: 'Liste',
    });

    const stockItems: NavItem[] = [
        ...(canManageWarehouses
            ? [
                  {
                      title: 'Entrepôts',
                      href: warehousesIndex(),
                      icon: Warehouse,
                  } satisfies NavItem,
                  {
                      title: 'Stock actuel',
                      href: stockLevelsIndex(),
                      icon: Boxes,
                  } satisfies NavItem,
                  {
                      title: 'Alertes de stock',
                      href: stockAlertsIndex(),
                      icon: AlertTriangle,
                  } satisfies NavItem,
                  {
                      title: 'Mouvements',
                      href: stockMovementsIndex(),
                      icon: History,
                  } satisfies NavItem,
                  {
                      title: 'Inventaires',
                      href: inventoriesIndex(),
                      icon: ClipboardList,
                  } satisfies NavItem,
              ]
            : []),
        ...(stockExitsNav ? [stockExitsNav] : []),
        ...(stockReturnsNav ? [stockReturnsNav] : []),
        ...(isWarehouseManager
            ? managedWarehouses.flatMap((warehouse): NavItem[] => {
                  const label =
                      managedWarehouses.length === 1
                          ? 'Réceptions'
                          : `Réceptions — ${warehouse.name}`;

                  const nav = buildListCreateNav({
                      title: label,
                      icon: ClipboardList,
                      listHref: receiptsIndex(warehouse.id),
                      createHref: createReceipt(warehouse.id),
                      canList: true,
                      canCreate: true,
                      createLabel: 'Nouvelle réception',
                      listLabel: 'Liste',
                  });

                  return nav ? [nav] : [];
              })
            : []),
    ];

    const purchasingSubItems: NavItem[] = [
        ...(canManageSuppliers
            ? [{ title: 'Fournisseurs', href: suppliersIndex() } satisfies NavItem]
            : []),
        ...(canViewPurchaseOrders
            ? [{ title: 'Commandes', href: purchaseOrdersIndex() } satisfies NavItem]
            : []),
        ...(canViewPurchaseOrders
            ? [
                  {
                      title: 'Factures fournisseurs',
                      href: supplierInvoicesIndex(),
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewExpenses
            ? [{ title: 'Notes de frais', href: expenseReportsIndex() } satisfies NavItem]
            : []),
    ];

    const purchasingItems: NavItem[] =
        purchasingSubItems.length > 0
            ? [
                  {
                      title: 'Achats',
                      href: purchasingSubItems[0].href,
                      icon: ShoppingCart,
                      items: purchasingSubItems,
                  } satisfies NavItem,
              ]
            : [];

    const invoicesNav = buildListCreateNav({
        title: 'Factures',
        icon: List,
        listHref: invoicesIndex(),
        createHref: invoicesCreate(),
        canList: canViewInvoices,
        canCreate: canCreateInvoices,
        createLabel: 'Nouvelle facture',
        listLabel: 'Liste',
    });

    const billingItems: NavItem[] = [
        ...(canManageCustomers
            ? [
                  {
                      title: 'Clients',
                      href: customersIndex(),
                      icon: UserCircle,
                  } satisfies NavItem,
              ]
            : []),
        ...(invoicesNav ? [invoicesNav] : []),
    ];

    const projectSubItems: NavItem[] = [
        ...(canViewProjects
            ? [{ title: 'Projets classiques', href: projectsIndex() } satisfies NavItem]
            : []),
        ...(canViewTickets
            ? [{ title: 'Tickets', href: ticketsIndex() } satisfies NavItem]
            : []),
        ...(canViewKanban
            ? [{ title: 'Kanban', href: kanban() } satisfies NavItem]
            : []),
        ...(canViewTasks
            ? [{ title: 'Tâches', href: tasksIndex() } satisfies NavItem]
            : []),
    ];

    const projectItems: NavItem[] =
        projectSubItems.length > 0
            ? [
                  {
                      title: 'Projets',
                      href: projectSubItems[0].href,
                      icon: FolderKanban,
                      items: projectSubItems,
                  } satisfies NavItem,
              ]
            : [];

    const leaveNav: NavItem | null = canViewLeave
        ? {
              title: 'Congés & absences',
              href: leaveRequestsIndex(),
              icon: CalendarDays,
              items: [
                  { title: 'Liste', href: leaveRequestsIndex() },
                  { title: 'Calendrier', href: leaveRequestsCalendar() },
                  ...(canManageLeaveTypes
                      ? [{ title: 'Types de congés', href: leaveTypesIndex() }]
                      : []),
              ],
          }
        : null;

    const hrItems: NavItem[] = [
        ...(canManageEmployees
            ? [
                  {
                      title: 'Collaborateurs',
                      href: employeesIndex(),
                      icon: Users,
                  } satisfies NavItem,
                  {
                      title: 'Archives RH',
                      href: hrArchivesIndex(),
                      icon: Archive,
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewOrganizationChart
            ? [
                  {
                      title: 'Organigramme',
                      href: organizationChartIndex(),
                      icon: Network,
                  } satisfies NavItem,
              ]
            : []),
        ...(canManageDepartments
            ? [
                  {
                      title: 'Départements',
                      href: departmentsIndex(),
                      icon: Building2,
                  } satisfies NavItem,
              ]
            : []),
        ...(canManageSites
            ? [
                  {
                      title: 'Sites',
                      href: sitesIndex(),
                      icon: MapPin,
                  } satisfies NavItem,
              ]
            : []),
        ...(canManageJobPositions
            ? [
                  {
                      title: 'Postes',
                      href: jobPositionsIndex(),
                      icon: Briefcase,
                  } satisfies NavItem,
              ]
            : []),
        ...(leaveNav ? [leaveNav] : []),
        ...(canViewPayroll
            ? [
                  {
                      title: 'Paie',
                      href: payrollRunsIndex(),
                      icon: Wallet,
                      items: [
                          ...(canViewPayrollRuns
                              ? [{ title: 'Cycles', href: payrollRunsIndex() }]
                              : []),
                          ...(canViewEmployeeLoans
                              ? [{ title: 'Avances et Prêts', href: employeeLoansIndex() }]
                              : []),
                          ...(canViewPayrollTaxSettings
                              ? [{ title: 'Barèmes', href: payrollTaxSettingsIndex() }]
                              : []),
                      ],
                  } satisfies NavItem,
              ]
            : []),
    ];

    const accountingItems: NavItem[] = [
        ...(canViewChartOfAccounts
            ? [
                  {
                      title: 'Plan Comptable',
                      href: chartOfAccountsIndex(),
                      icon: BookOpen,
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewJournalEntries
            ? [
                  {
                      title: 'Écritures',
                      href: journalEntriesIndex(),
                      icon: ClipboardList,
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewCostCenters
            ? [
                  {
                      title: 'Analytique',
                      href: costCentersIndex(),
                      icon: PieChart,
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewBudgets
            ? [
                  {
                      title: 'Budget',
                      href: budgetsIndex(),
                      icon: Wallet,
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewAccountingProcurement
            ? [
                  {
                      title: 'Approvisionnement',
                      href: accountingProcurementIndex(),
                      icon: Truck,
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewTaxReports
            ? [
                  {
                      title: 'Rapports Impôts',
                      href: taxReportsIndex(),
                      icon: FileSpreadsheet,
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewFixedAssets
            ? [
                  {
                      title: 'Immobilisation',
                      href: fixedAssetsIndex(),
                      icon: Building,
                  } satisfies NavItem,
              ]
            : []),
    ];

    const adminItems: NavItem[] = [
        ...(canManageUsers
            ? [
                  {
                      title: 'Utilisateurs',
                      href: usersIndex(),
                      icon: Users,
                  } satisfies NavItem,
              ]
            : []),
        ...(canManageRoles
            ? [
                  {
                      title: 'Rôles',
                      href: rolesIndex(),
                      icon: Shield,
                  } satisfies NavItem,
              ]
            : []),
        ...(canManageSettings
            ? [
                  {
                      title: 'Entreprise',
                      href: companySettingsEdit(),
                      icon: Building2,
                  } satisfies NavItem,
              ]
            : []),
        ...(canViewAuditLogs
            ? [
                  {
                      title: "Journal d'audit",
                      href: auditLogsIndex(),
                      icon: FileClock,
                  } satisfies NavItem,
              ]
            : []),
    ];

    const sections: NavSection[] = [
        { label: 'Général', items: [...generalItems, ...catalogItems] },
        { label: 'Stock', items: stockItems },
        { label: 'Achats', items: purchasingItems },
        { label: 'Facturation', items: billingItems },
        { label: 'Comptabilité', items: accountingItems },
        { label: 'Projets', items: projectItems },
        { label: 'Ressources Humaines', items: hrItems },
        { label: 'Administration', items: adminItems },
    ].filter((section) => section.items.length > 0);

    return (
        <Sidebar collapsible="icon" variant="inset">
            <SidebarHeader>
                <SidebarMenu>
                    <SidebarMenuItem>
                        <SidebarMenuButton size="lg" asChild>
                            <Link href={dashboard()} prefetch>
                                <AppLogo />
                            </Link>
                        </SidebarMenuButton>
                    </SidebarMenuItem>
                </SidebarMenu>
            </SidebarHeader>

            <SidebarContent>
                {sections.map((section) => (
                    <NavMain
                        key={section.label}
                        label={section.label}
                        items={section.items}
                    />
                ))}
            </SidebarContent>

            <SidebarFooter>
                {footerNavItems.length > 0 && (
                    <NavFooter items={footerNavItems} className="mt-auto" />
                )}
                <NavUser />
            </SidebarFooter>
        </Sidebar>
    );
}
