import { ApplicationConfig, provideZoneChangeDetection, APP_INITIALIZER, inject } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { provideStore } from '@ngrx/store';
import { provideEffects } from '@ngrx/effects';
import { provideStoreDevtools } from '@ngrx/store-devtools';
import { provideTranslateService } from '@ngx-translate/core';
import { provideTranslateHttpLoader } from '@ngx-translate/http-loader';
import { providePrimeNG } from 'primeng/config';
import Aura from '@primeuix/themes/aura';

import { routes } from './app.routes';
import { authInterceptor } from './core/interceptors/auth.interceptor';
import { authFeature } from './core/store/auth/auth.reducer';
import { AuthEffects } from './core/store/auth/auth.effects';
import { dashboardFeature } from './core/store/dashboard/dashboard.reducer';
import { DashboardEffects } from './core/store/dashboard/dashboard.effects';
import { branchesFeature } from './core/store/branches/branches.reducer';
import { BranchesEffects } from './core/store/branches/branches.effects';
import { usersFeature } from './core/store/users/users.reducer';
import { UsersEffects } from './core/store/users/users.effects';
import { settingsFeature } from './core/store/settings/settings.reducer';
import { SettingsEffects } from './core/store/settings/settings.effects';
import { sequencesFeature } from './core/store/sequences/sequences.reducer';
import { SequencesEffects } from './core/store/sequences/sequences.effects';
import { unitGroupsFeature } from './core/store/unit-groups/unit-groups.reducer';
import { UnitGroupsEffects } from './core/store/unit-groups/unit-groups.effects';
import { unitsFeature } from './core/store/units/units.reducer';
import { UnitsEffects } from './core/store/units/units.effects';
import { productCategoriesFeature } from './core/store/product-categories/product-categories.reducer';
import { ProductCategoriesEffects } from './core/store/product-categories/product-categories.effects';
import { productsFeature } from './core/store/products/products.reducer';
import { ProductsEffects } from './core/store/products/products.effects';
import { partnerCategoriesFeature } from './core/store/partner-categories/partner-categories.reducer';
import { PartnerCategoriesEffects } from './core/store/partner-categories/partner-categories.effects';
import { partnersFeature } from './core/store/partners/partners.reducer';
import { PartnersEffects } from './core/store/partners/partners.effects';
import { accountsFeature } from './core/store/accounts/accounts.reducer';
import { AccountsEffects } from './core/store/accounts/accounts.effects';
import { fiscalYearsFeature } from './core/store/fiscal-years/fiscal-years.reducer';
import { FiscalYearsEffects } from './core/store/fiscal-years/fiscal-years.effects';
import { currenciesFeature } from './core/store/currencies/currencies.reducer';
import { CurrenciesEffects } from './core/store/currencies/currencies.effects';
import { costCentersFeature } from './core/store/cost-centers/cost-centers.reducer';
import { CostCentersEffects } from './core/store/cost-centers/cost-centers.effects';
import { journalEntriesFeature } from './core/store/journal-entries/journal-entries.reducer';
import { JournalEntriesEffects } from './core/store/journal-entries/journal-entries.effects';
import { taxRatesFeature } from './core/store/tax-rates/tax-rates.reducer';
import { TaxRatesEffects } from './core/store/tax-rates/tax-rates.effects';
import { exchangeRatesFeature } from './core/store/exchange-rates/exchange-rates.reducer';
import { ExchangeRatesEffects } from './core/store/exchange-rates/exchange-rates.effects';
import { bankAccountsFeature } from './core/store/bank-accounts/bank-accounts.reducer';
import { BankAccountsEffects } from './core/store/bank-accounts/bank-accounts.effects';
import { checksReceivedFeature } from './core/store/checks-received/checks-received.reducer';
import { ChecksReceivedEffects } from './core/store/checks-received/checks-received.effects';
import { checksIssuedFeature } from './core/store/checks-issued/checks-issued.reducer';
import { ChecksIssuedEffects } from './core/store/checks-issued/checks-issued.effects';
import { pettyCashFeature } from './core/store/petty-cash/petty-cash.reducer';
import { PettyCashEffects } from './core/store/petty-cash/petty-cash.effects';
import { transfersFeature } from './core/store/transfers/transfers.reducer';
import { TransfersEffects } from './core/store/transfers/transfers.effects';
import { budgetsFeature } from './core/store/budgets/budgets.reducer';
import { BudgetsEffects } from './core/store/budgets/budgets.effects';
import { openingBalancesFeature } from './core/store/opening-balances/opening-balances.reducer';
import { OpeningBalancesEffects } from './core/store/opening-balances/opening-balances.effects';
import { warehousesFeature } from './core/store/warehouses/warehouses.reducer';
import { WarehousesEffects } from './core/store/warehouses/warehouses.effects';
import { salesQuotationsFeature } from './core/store/sales/quotations/quotations.reducer';
import { SalesQuotationsEffects } from './core/store/sales/quotations/quotations.effects';
import { salesOrdersFeature } from './core/store/sales/orders/orders.reducer';
import { SalesOrdersEffects } from './core/store/sales/orders/orders.effects';
import { salesInvoicesFeature } from './core/store/sales/invoices/invoices.reducer';
import { SalesInvoicesEffects } from './core/store/sales/invoices/invoices.effects';
import { salesReturnsFeature } from './core/store/sales/returns/returns.reducer';
import { SalesReturnsEffects } from './core/store/sales/returns/returns.effects';
import { salesDeliveryNotesFeature } from './core/store/sales/delivery-notes/delivery-notes.reducer';
import { SalesDeliveryNotesEffects } from './core/store/sales/delivery-notes/delivery-notes.effects';
import { salesPaymentsFeature } from './core/store/sales/payments/payments.reducer';
import { SalesPaymentsEffects } from './core/store/sales/payments/payments.effects';
import { salesCommissionsFeature } from './core/store/sales/commissions/commissions.reducer';
import { SalesCommissionsEffects } from './core/store/sales/commissions/commissions.effects';
import { purchaseRequestsFeature } from './core/store/purchases/requests/requests.reducer';
import { PurchaseRequestsEffects } from './core/store/purchases/requests/requests.effects';
import { purchaseOrdersFeature } from './core/store/purchases/orders/orders.reducer';
import { PurchaseOrdersEffects } from './core/store/purchases/orders/orders.effects';
import { purchaseGrnsFeature } from './core/store/purchases/grns/grns.reducer';
import { PurchaseGrnsEffects } from './core/store/purchases/grns/grns.effects';
import { purchaseBillsFeature } from './core/store/purchases/bills/bills.reducer';
import { PurchaseBillsEffects } from './core/store/purchases/bills/bills.effects';
import { purchaseReturnsFeature } from './core/store/purchases/returns/returns.reducer';
import { PurchaseReturnsEffects } from './core/store/purchases/returns/returns.effects';
import { purchasePaymentsFeature } from './core/store/purchases/payments/payments.reducer';
import { PurchasePaymentsEffects } from './core/store/purchases/payments/payments.effects';
import { supplierPricesFeature } from './core/store/purchases/supplier-prices/supplier-prices.reducer';
import { SupplierPricesEffects } from './core/store/purchases/supplier-prices/supplier-prices.effects';
import { hrDepartmentsFeature } from './core/store/hr/departments/departments.reducer';
import { HrDepartmentsEffects } from './core/store/hr/departments/departments.effects';
import { hrPositionsFeature } from './core/store/hr/positions/positions.reducer';
import { HrPositionsEffects } from './core/store/hr/positions/positions.effects';
import { hrEmployeesFeature } from './core/store/hr/employees/employees.reducer';
import { HrEmployeesEffects } from './core/store/hr/employees/employees.effects';
import { hrShiftsFeature } from './core/store/hr/shifts/shifts.reducer';
import { HrShiftsEffects } from './core/store/hr/shifts/shifts.effects';
import { hrLeaveTypesFeature } from './core/store/hr/leave-types/leave-types.reducer';
import { HrLeaveTypesEffects } from './core/store/hr/leave-types/leave-types.effects';
import { hrSalaryComponentsFeature } from './core/store/hr/salary-components/salary-components.reducer';
import { HrSalaryComponentsEffects } from './core/store/hr/salary-components/salary-components.effects';
import { hrPayrollFeature } from './core/store/hr/payroll/payroll.reducer';
import { HrPayrollEffects } from './core/store/hr/payroll/payroll.effects';
import { hrLoansFeature } from './core/store/hr/loans/loans.reducer';
import { HrLoansEffects } from './core/store/hr/loans/loans.effects';
import { LanguageService } from './core/services/language.service';
import { ThemeService } from './core/services/theme.service';
import { environment } from '../environments/environment';

function initializeApp(): () => Promise<void> {
  const langService = inject(LanguageService);
  const themeService = inject(ThemeService);
  return async () => {
    await themeService.init();
    await langService.init();
  };
}

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(withInterceptors([authInterceptor])),
    provideAnimationsAsync(),

    // PrimeNG
    providePrimeNG({
      theme: {
        preset: Aura,
        options: {
          darkModeSelector: '.dark-mode',
          cssLayer: {
            name: 'primeng',
            order: 'theme, base, primeng, components, utilities',
          },
        },
      },
    }),

    // NgRx
    provideStore({
      auth: authFeature.reducer,
      dashboard: dashboardFeature.reducer,
      branches: branchesFeature.reducer,
      users: usersFeature.reducer,
      settings: settingsFeature.reducer,
      sequences: sequencesFeature.reducer,
      unitGroups: unitGroupsFeature.reducer,
      units: unitsFeature.reducer,
      productCategories: productCategoriesFeature.reducer,
      products: productsFeature.reducer,
      partnerCategories: partnerCategoriesFeature.reducer,
      partners: partnersFeature.reducer,
      accounts: accountsFeature.reducer,
      fiscalYears: fiscalYearsFeature.reducer,
      currencies: currenciesFeature.reducer,
      costCenters: costCentersFeature.reducer,
      journalEntries: journalEntriesFeature.reducer,
      taxRates: taxRatesFeature.reducer,
      exchangeRates: exchangeRatesFeature.reducer,
      bankAccounts: bankAccountsFeature.reducer,
      checksReceived: checksReceivedFeature.reducer,
      checksIssued: checksIssuedFeature.reducer,
      pettyCash: pettyCashFeature.reducer,
      transfers: transfersFeature.reducer,
      budgets: budgetsFeature.reducer,
      openingBalances: openingBalancesFeature.reducer,
      warehouses: warehousesFeature.reducer,
      salesQuotations: salesQuotationsFeature.reducer,
      salesOrders: salesOrdersFeature.reducer,
      salesInvoices: salesInvoicesFeature.reducer,
      salesReturns: salesReturnsFeature.reducer,
      salesDeliveryNotes: salesDeliveryNotesFeature.reducer,
      salesPayments: salesPaymentsFeature.reducer,
      salesCommissions: salesCommissionsFeature.reducer,
      purchaseRequests: purchaseRequestsFeature.reducer,
      purchaseOrders: purchaseOrdersFeature.reducer,
      purchaseGrns: purchaseGrnsFeature.reducer,
      purchaseBills: purchaseBillsFeature.reducer,
      purchaseReturns: purchaseReturnsFeature.reducer,
      purchasePayments: purchasePaymentsFeature.reducer,
      supplierPrices: supplierPricesFeature.reducer,
      hrDepartments: hrDepartmentsFeature.reducer,
      hrPositions: hrPositionsFeature.reducer,
      hrEmployees: hrEmployeesFeature.reducer,
      hrShifts: hrShiftsFeature.reducer,
      hrLeaveTypes: hrLeaveTypesFeature.reducer,
      hrSalaryComponents: hrSalaryComponentsFeature.reducer,
      hrPayroll: hrPayrollFeature.reducer,
      hrLoans: hrLoansFeature.reducer,
    }),
    provideEffects([
      AuthEffects, DashboardEffects, BranchesEffects, UsersEffects,
      SettingsEffects, SequencesEffects, UnitGroupsEffects, UnitsEffects,
      ProductCategoriesEffects, ProductsEffects,
      PartnerCategoriesEffects, PartnersEffects,
      AccountsEffects, FiscalYearsEffects, CurrenciesEffects, CostCentersEffects,
      JournalEntriesEffects, TaxRatesEffects, ExchangeRatesEffects,
      BankAccountsEffects, ChecksReceivedEffects, ChecksIssuedEffects,
      PettyCashEffects, TransfersEffects, BudgetsEffects, OpeningBalancesEffects,
      WarehousesEffects,
      SalesQuotationsEffects, SalesOrdersEffects, SalesInvoicesEffects,
      SalesReturnsEffects, SalesDeliveryNotesEffects, SalesPaymentsEffects,
      SalesCommissionsEffects,
      PurchaseRequestsEffects, PurchaseOrdersEffects, PurchaseGrnsEffects,
      PurchaseBillsEffects, PurchaseReturnsEffects, PurchasePaymentsEffects,
      SupplierPricesEffects,
      HrDepartmentsEffects, HrPositionsEffects, HrEmployeesEffects,
      HrShiftsEffects, HrLeaveTypesEffects, HrSalaryComponentsEffects,
      HrPayrollEffects, HrLoansEffects,
    ]),
    provideStoreDevtools({
      maxAge: 25,
      logOnly: environment.production,
    }),

    // i18n
    provideTranslateService({
      loader: provideTranslateHttpLoader({
        prefix: './assets/i18n/',
        suffix: '.json',
      }),
      fallbackLang: 'ar',
    }),

    // App initializer
    {
      provide: APP_INITIALIZER,
      useFactory: initializeApp,
      multi: true,
    },
  ],
};
