import { NgModule, CUSTOM_ELEMENTS_SCHEMA, LOCALE_ID, APP_INITIALIZER } from '@angular/core';
import { ConfigService } from './services/config.service';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AuthLayoutComponent } from './layout/auth-layout/auth-layout.component';
import { MainLayoutComponent } from './layout/main-layout/main-layout.component';
import { HeaderComponent } from './layout/header/header.component';
import { SidebarComponent } from './layout/sidebar/sidebar.component';
import { LoginComponent } from './components/login/login.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { CustomInterceptor } from './core/services/custom.interceptor';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatSidenavModule } from '@angular/material/sidenav';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { AdminComponent } from './components/admin/admin.component';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { UsersComponent } from './components/admin/users/users/users.component';
import { RolesComponent } from './components/admin/roles/roles/roles.component';
import { MatTableModule } from '@angular/material/table';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatDialogModule } from '@angular/material/dialog';
import { AddUserModalComponent } from './components/admin/users/users/add-user-modal/add-user-modal.component';
import { MatSelectModule } from '@angular/material/select';
import { AddRoleModalComponent } from './components/admin/roles/roles/add-role-modal/add-role-modal.component';
import { ChangePasswordModalComponent } from './components/admin/users/users/change-password-modal/change-password-modal.component';
import { GroupsComponent } from './components/groups/groups.component';
import { MatDividerModule } from '@angular/material/divider';
import { MatStepperModule } from '@angular/material/stepper';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { DeleteModalComponent } from './shared/delete_modal/delete-modal/delete-modal.component';
import { ClassroomViewComponent } from './components/groups/shared/classroom-view/classroom-view.component';
import { MatProgressSpinner } from "@angular/material/progress-spinner";
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatMenu, MatMenuItem, MatMenuTrigger } from "@angular/material/menu";
import { MatAutocomplete, MatAutocompleteTrigger } from "@angular/material/autocomplete";
import { MatChip, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule } from "@angular/material/chips";
import { ClientViewComponent } from './components/groups/shared/client-view/client-view.component';
import { MatTab, MatTabGroup } from "@angular/material/tabs";
import { MatTooltip } from "@angular/material/tooltip";
import { MatExpansionModule } from '@angular/material/expansion';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { ToastrModule } from 'ngx-toastr';
import { ShowOrganizationalUnitComponent } from './components/groups/shared/organizational-units/show-organizational-unit/show-organizational-unit.component';
import { MatGridList, MatGridTile } from "@angular/material/grid-list";
import {
  MatNestedTreeNode,
  MatTree,
  MatTreeNode,
  MatTreeNodeDef, MatTreeNodeOutlet,
  MatTreeNodePadding,
  MatTreeNodeToggle
} from "@angular/material/tree";
import { LegendComponent } from './components/groups/shared/legend/legend.component';
import { ClassroomViewDialogComponent } from './components/groups/shared/classroom-view/classroom-view-modal';
import { MatPaginator } from "@angular/material/paginator";
import { SaveFiltersDialogComponent } from './components/groups/shared/save-filters-dialog/save-filters-dialog.component';
import { PXEimagesComponent } from './components/ogboot/pxe-images/pxe-images.component';
import { CreatePXEImageComponent } from './components/ogboot/pxe-images/create-image/create-image/create-image.component';
import { InfoImageComponent } from './components/ogboot/pxe-images/info-image/info-image/info-image.component';
import { PxeComponent } from './components/ogboot/pxe/pxe.component';
import { CreatePxeTemplateComponent } from './components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component';
import { PxeBootFilesComponent } from './components/ogboot/pxe-boot-files/pxe-boot-files.component';
import { MatExpansionPanel, MatExpansionPanelDescription, MatExpansionPanelTitle } from "@angular/material/expansion";
import { OgbootStatusComponent } from './components/ogboot/ogboot-status/ogboot-status.component';
import { NgxChartsModule } from '@swimlane/ngx-charts';
import { CommandsComponent } from './components/commands/main-commands/commands.component';
import { CommandDetailComponent } from './components/commands/main-commands/detail-command/command-detail.component';
import { CreateCommandComponent } from './components/commands/main-commands/create-command/create-command.component';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatNativeDateModule } from '@angular/material/core';
import { CalendarComponent } from './components/calendar/calendar.component';
import { CreateCalendarComponent } from './components/calendar/create-calendar/create-calendar.component';
import { MatRadioButton, MatRadioGroup } from "@angular/material/radio";
import { CreateCalendarRuleComponent } from './components/calendar/create-calendar-rule/create-calendar-rule.component';
import { CommandsGroupsComponent } from './components/commands/commands-groups/commands-groups.component';
import { CommandsTaskComponent } from './components/commands/commands-task/commands-task.component';
import { CreateCommandGroupComponent } from './components/commands/commands-groups/create-command-group/create-command-group.component';
import { DetailCommandGroupComponent } from './components/commands/commands-groups/detail-command-group/detail-command-group.component';
import { CreateTaskComponent } from './components/commands/commands-task/create-task/create-task.component';
import { DetailTaskComponent } from './components/commands/commands-task/detail-task/detail-task.component';
import { TaskLogsComponent } from './components/commands/commands-task/task-logs/task-logs.component';
import { MatSliderModule } from '@angular/material/slider';
import { ClientMainViewComponent } from './components/groups/components/client-main-view/client-main-view.component';
import { ImagesComponent } from './components/images/images.component';
import { CreateImageComponent } from './components/images/create-image/create-image.component';
import { CreateClientImageComponent } from './components/groups/components/client-main-view/create-image/create-image.component';
import { PartitionAssistantComponent } from './components/groups/components/client-main-view/partition-assistant/partition-assistant.component';
import { SoftwareComponent } from './components/software/software.component';
import { CreateSoftwareComponent } from './components/software/create-software/create-software.component';
import { SoftwareProfileComponent } from './components/software-profile/software-profile.component';
import { CreateSoftwareProfileComponent } from './components/software-profile/create-software-profile/create-software-profile.component';
import { OperativeSystemComponent } from './components/operative-system/operative-system.component';
import { CreateOperativeSystemComponent } from './components/operative-system/create-operative-system/create-operative-system.component';
import { ShowTemplateContentComponent } from './components/ogboot/pxe/show-template-content/show-template-content.component';
import { RepositoriesComponent } from './components/repositories/repositories.component';
import { ManageRepositoryComponent } from './components/repositories/manage-repository/manage-repository.component';
import { ExecuteCommandComponent } from './components/commands/main-commands/execute-command/execute-command.component';
import { DeployImageComponent } from './components/groups/components/client-main-view/deploy-image/deploy-image.component';
import { MainRepositoryViewComponent } from './components/repositories/main-repository-view/main-repository-view.component';
import { ExecuteCommandOuComponent } from './components/groups/shared/execute-command-ou/execute-command-ou.component';
import { JoyrideModule } from 'ngx-joyride';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { EnvVarsComponent } from './components/admin/env-vars/env-vars.component';
import { MatSortModule } from '@angular/material/sort';
import { MenusComponent } from './components/menus/menus.component';
import { CreateMenuComponent } from './components/menus/create-menu/create-menu.component';
import { CreateMultipleClientComponent } from './components/groups/shared/clients/create-multiple-client/create-multiple-client.component';
import { ExportImageComponent } from './components/images/export-image/export-image.component';
import { ImportImageComponent } from "./components/repositories/import-image/import-image.component";
import { LoadingComponent } from './shared/loading/loading.component';
import { RepositoryImagesComponent } from './components/repositories/repository-images/repository-images.component';
import { InputDialogComponent } from './components/commands/commands-task/task-logs/input-dialog/input-dialog.component';
import { ManageOrganizationalUnitComponent } from './components/groups/shared/organizational-units/manage-organizational-unit/manage-organizational-unit.component';
import { BackupImageComponent } from './components/repositories/backup-image/backup-image.component';
import { ServerInfoDialogComponent } from "./components/ogdhcp/server-info-dialog/server-info-dialog.component";
import { StatusComponent } from "./components/ogdhcp/status/status.component";
import { OgDhcpSubnetsComponent } from "./components/ogdhcp/og-dhcp-subnets.component";
import { CreateSubnetComponent } from "./components/ogdhcp/create-subnet/create-subnet.component";
import { AddClientsToSubnetComponent } from "./components/ogdhcp/add-clients-to-subnet/add-clients-to-subnet.component";
import { ShowClientsComponent } from './components/ogdhcp/show-clients/show-clients.component';
import { OperationResultDialogComponent } from './components/ogdhcp/operation-result-dialog/operation-result-dialog.component';
import { ManageClientComponent } from './components/groups/shared/clients/manage-client/manage-client.component';
import { ConvertImageComponent } from './components/repositories/convert-image/convert-image.component';
import { registerLocaleData } from '@angular/common';
import localeEs from '@angular/common/locales/es';
import { GlobalStatusComponent } from './components/global-status/global-status.component';
import { ShowImagesComponent } from './components/repositories/show-images/show-images.component';
import { StatusTabComponent } from './components/global-status/status-tab/status-tab.component';
import { ConvertImageToVirtualComponent } from './components/repositories/convert-image-to-virtual/convert-image-to-virtual.component';
import { RunScriptAssistantComponent } from './components/groups/components/client-main-view/run-script-assistant/run-script-assistant.component';

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http, './locale/', '.json');
}

export function initializeApp(configService: ConfigService) {
  return () => configService.loadConfig();
}

registerLocaleData(localeEs, 'es-ES');

@NgModule({
  declarations: [
    AppComponent,
    AuthLayoutComponent,
    MainLayoutComponent,
    HeaderComponent,
    SidebarComponent,
    LoginComponent,
    AdminComponent,
    MainLayoutComponent,
    UsersComponent,
    RolesComponent,
    AddUserModalComponent,
    AddRoleModalComponent,
    ChangePasswordModalComponent,
    GroupsComponent,
    ManageClientComponent,
    DeleteModalComponent,
    ClassroomViewComponent,
    ClientViewComponent,
    ShowOrganizationalUnitComponent,
    LegendComponent,
    ClassroomViewDialogComponent,
    SaveFiltersDialogComponent,
    PXEimagesComponent,
    CreatePXEImageComponent,
    InfoImageComponent,
    PxeComponent,
    CreatePxeTemplateComponent,
    PxeBootFilesComponent,
    OgbootStatusComponent,
    OgDhcpSubnetsComponent,
    CreateSubnetComponent,
    AddClientsToSubnetComponent,
    CommandsComponent,
    CommandDetailComponent,
    CreateCommandComponent,
    CalendarComponent,
    CreateCalendarComponent,
    CreateClientImageComponent,
    CreateCalendarRuleComponent,
    CommandsGroupsComponent,
    CommandsTaskComponent,
    CreateCommandGroupComponent,
    DetailCommandGroupComponent,
    CreateTaskComponent,
    DetailTaskComponent,
    TaskLogsComponent,
    ServerInfoDialogComponent,
    StatusComponent,
    ClientMainViewComponent,
    ImagesComponent,
    CreateImageComponent,
    PartitionAssistantComponent,
    SoftwareComponent,
    CreateSoftwareComponent,
    SoftwareProfileComponent,
    CreateSoftwareProfileComponent,
    OperativeSystemComponent,
    CreateOperativeSystemComponent,
    ShowTemplateContentComponent,
    RepositoriesComponent,
    ManageRepositoryComponent,
    ExecuteCommandComponent,
    ExecuteCommandOuComponent,
    DeployImageComponent,
    MainRepositoryViewComponent,
    ExecuteCommandOuComponent,
    EnvVarsComponent,
    MenusComponent,
    CreateMenuComponent,
    CreateMultipleClientComponent,
    ExportImageComponent,
    ImportImageComponent,
    LoadingComponent,
    RepositoryImagesComponent,
    InputDialogComponent,
    ManageOrganizationalUnitComponent,
    BackupImageComponent,
    ShowClientsComponent,
    OperationResultDialogComponent,
    ConvertImageComponent,
    GlobalStatusComponent,
    ShowImagesComponent,
    StatusTabComponent,
    ConvertImageToVirtualComponent,
    RunScriptAssistantComponent
  ],
  bootstrap: [AppComponent],
  imports: [BrowserModule,
    AppRoutingModule,
    FormsModule,
    ReactiveFormsModule,
    MatToolbarModule,
    MatIconModule,
    MatButtonToggleModule,
    MatButtonModule,
    MatSidenavModule,
    NoopAnimationsModule,
    MatCardModule,
    MatCheckboxModule,
    MatFormFieldModule,
    MatInputModule,
    MatListModule,
    MatTableModule,
    MatDialogModule,
    MatSelectModule,
    MatDividerModule,
    MatProgressBarModule,
    MatStepperModule,
    DragDropModule,
    MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem, MatAutocomplete, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule, MatChip, MatProgressSpinner, MatTabGroup, MatTab, MatTooltip,
    MatExpansionModule,
    NgxChartsModule,
    MatDatepickerModule,
    MatNativeDateModule,
    MatSliderModule,
    MatSortModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    }),
    JoyrideModule.forRoot(),
    ToastrModule.forRoot(
      {
        timeOut: 5000,
        positionClass: 'toast-bottom-right',
        preventDuplicates: true,
        progressBar: true,
        progressAnimation: 'increasing',
        closeButton: true
      }
    ), MatGridList, MatTree, MatTreeNode, MatNestedTreeNode, MatTreeNodeToggle, MatTreeNodeDef, MatTreeNodePadding, MatTreeNodeOutlet, MatPaginator, MatGridTile, MatExpansionPanel, MatExpansionPanelTitle, MatExpansionPanelDescription, MatRadioGroup, MatRadioButton, MatAutocompleteTrigger
  ],
  schemas: [
    CUSTOM_ELEMENTS_SCHEMA,
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: CustomInterceptor,
      multi: true
    },
    { provide: LOCALE_ID, useValue: 'es-ES' },
    provideAnimationsAsync(),
    provideHttpClient(withInterceptorsFromDi()),
    ConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializeApp,
      deps: [ConfigService],
      multi: true
    }
  ],
})
export class AppModule { }
