import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import { MagnitudesListItem, MagnitudesListResponse, UnitsByMagnitudeListItem, UnitsByMagnitudeListResponse } from '../../../interfaces/counters-activators.interface';
import { MaterialIcon, MaterialIconsResponse } from '../../../interfaces/material-icons.interface';
import { ModuleInterface } from '../../../interfaces/modules.interface';
import { Submodules } from '../../../interfaces/submodules.interface';
import { MenuFunction, MenuModule, MenuResponse, MenuSubmodule } from '../../../interfaces/menu.interface';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { TempFileInfo } from '../../../interfaces/temp-file-info.interface';
import { MatTableDataSource } from '@angular/material/table';
import { GetForms, ResponseDataGetForms } from '../../../interfaces/forms-management/form-management.interface';
import { TaxRegimeList, TaxRegimeListResponse } from '../../../interfaces/tax-regime-list.interface';
import { CountriesList, CountriesListResponse, LadaSelection } from '../../../interfaces/countries-list.interface';
import { CountryState, CountryStatesResponse } from '../../../interfaces/country-states.interface';
import { CityTown, CityTownsResponse } from '../../../interfaces/city-towns.interface';
import { StateCitiesResponse, StateCity } from '../../../interfaces/state-cities.interface';
import { CitySettings, CitySettingsResponse } from '../../../interfaces/city-settings.interface';
import { lastValueFrom, map, Observable, startWith } from 'rxjs';
import { DOCUMENT } from '@angular/common';
import { MatDialog } from '@angular/material/dialog';
import { EncService } from '../../../services/enc.service';
import { SystemAdminService } from '../../../services/system-admin.service';
import { ModulesService } from '../../../services/modules.service';
import { DynamicFormService } from '../../../services/forms-management/dynamic-form.service';
import { Router } from '@angular/router';
import { FunctionsService } from '../../../services/functions.service';
import { SocketService } from '../../../services/socket.service';
import { UsersProfilesService } from '../../../services/users-profiles.service';
import { GdelService } from '../../../services/gdel.service';
import { CatalogMeasuresService } from '../../../services/counters-and-triggers/catalog-measures.service';
import { ResourcesService, ResponseData } from '../../../services/resources.service';
import { UserConsultResponse } from '../../../interfaces/user.interface';
import { ProfileInterface } from '../../../interfaces/profile.interface';
import { HttpErrorResponse } from '@angular/common/http';
import { FormTaxInformation, ResponseDataGetTaxInformation } from '../../../interfaces/tax-information.interface';
import { LoginParamsResponse } from '../../../interfaces/login-params.interface';
import { Permissions } from '../../../interfaces/permissions.interface';
import { AlertComponent } from '../../resources/dialogs/alert/alert.component';
import { EditPriorityComponent } from './edit-priority/edit-priority.component';
import { AddressByZipCodeResponse } from '../../../interfaces/address-by-zip-code.interface';
import { MagnitudeFormComponent } from './magnitude-form/magnitude-form.component';
import { RequestDeleteMeasures, RequestFormMeasures } from '../../../interfaces/failure-analysis/catalog-measures.interface';
import { UnitFormComponent } from './unit-form/unit-form.component';
import { VIA_POSITIONS, ViaLocationPositions } from '../../equipment-management/equipment-location/equipment-location.component';
import { PlaneUploaderComponent } from './plane-uploader/plane-uploader.component';
import { PlaneViewerComponent } from './plane-viewer/plane-viewer.component';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { SelectColorComponent } from './select-color/select-color.component';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { GridIconsSelectorComponent } from './grid-icons-selector/grid-icons-selector.component';

@Component({
    selector: 'app-system-params',
    templateUrl: './system-params.component.html',
    styleUrl: './system-params.component.css',
    standalone: false
})
export class SystemParamsComponent implements OnInit {
  isLoading: boolean;
  isLoadingFormDynamic: boolean;
  hasError: boolean;
  errorStr: string;
  magnitudeSelected: string;
  hexColorStr: string;
  decColorStr: string;
  hexSecColorStr: string;
  decSecColorStr: string;
  primaryFontColor: string;
  secondaryFontColor: string;
  primaryDecFontColor: string;
  secondaryDecFontColor: string;
  uploadingCustomIcon: boolean;

  magnitudes: MagnitudesListItem[];
  unitsByMagnitude: UnitsByMagnitudeListItem[];
  magnitudesAux: MagnitudesListItem[];
  unitsByMagnitudeAux: UnitsByMagnitudeListItem[];
  materialIcons: MaterialIcon[];
  modules: ModuleInterface[];
  modulesStates: Map<string, boolean>;
  submodules: Map<string, MenuSubmodule[]>;
  functionsPerSubmodule: Map<string, Map<string, MenuFunction[]>>;
  functionsPerModule: Map<string, MenuFunction[]>;
  iconsArr: Map<string, string[]>;
  iconsCategories: string[];

  moduleNameModulesControl = new FormControl('');
  moduleCustomIconModulesControl = new FormControl({ value: false, disabled: true });
  moduleIconModulesControl = new FormControl({ value: '', disabled: true });
  moduleStatusModulesControl = new FormControl({ value: false, disabled: true });
  modulesSettings: Map<string, MenuModule>;
  modulesModuleSelected: MenuModule | null;

  moduleNameSubmodulesControl = new FormControl('');
  submoduleNameSubmodulesControl = new FormControl({ value: '', disabled: true });
  submoduleCustomIconSubmodulesControl = new FormControl({ value: false, disabled: true });
  submoduleIconSubmodulesControl = new FormControl({ value: '', disabled: true });
  submodulesSettings: Map<string, Map<string, MenuSubmodule>>;
  submodulesSubmoduleSelected: MenuSubmodule | null;

  moduleNameFunctionsControl = new FormControl('');
  submoduleNameFunctionsControl = new FormControl({ value: '', disabled: true });
  functionNameFunctionsControl = new FormControl({ value: '', disabled: true });
  functionCustomIconFunctionsControl = new FormControl({ value: false, disabled: true });
  functionIconFunctionsControl = new FormControl({ value: '', disabled: true });
  functionsSettings: Map<string, Map<string, Map<string, MenuFunction>> | Map<string, MenuFunction>>;
  functionsFunctionSelected: MenuFunction | null;

  moduleName = new FormControl('');
  moduleCustomIcon = new FormControl(false);
  moduleIcon = new FormControl('');
  submoduleModule = new FormControl('');
  submoduleName = new FormControl('');
  submoduleIcon = new FormControl('');
  functionModule = new FormControl('');
  functionSubmodule = new FormControl('');
  functionName = new FormControl('');
  functionIcon = new FormControl('');

  imageFormats = ["jpg", "png", "gif", "bmp", "tiff", "svg"];
  attached: TempFileInfo[];

  upImg: boolean;
  upBac: boolean;
  imgStr: string;
  bacStr: string;

  @ViewChild('file') file?: ElementRef;

  public txtBuscador: string;
  public btnSmall: boolean;
  public dataSource: MatTableDataSource<GetForms>;
  public isLoadingForm: boolean = false;
  public displayedColumns: string[];

  formsManagementEnabled: boolean;
  loginImagesEditEnabled: boolean;
  modulesIconsEditEnabled: boolean;
  submodulesIconsEditEnabled: boolean;
  functionsIconsEditEnabled: boolean;
  orderPrioritiesEnabled: boolean;
  unitsMagnitudesEnabled: boolean;
  taxInformationEnabled: boolean;

  currentHour: number;
  currentMinutes: number;
  currentSeconds: number;
  orderPrioritiesArr: PriorityInterface[];

  public formGroupTax: FormGroup;

  public arrTaxRegime: Array<TaxRegimeList>;
  public taxRegimeStr: string[];

  public arrCountries: Array<CountriesList>;
  public ladas: LadaSelection[];
  public ladasStr: string[];
  public countries: CountriesList[];
  public countryStates: CountryState[];
  public cityTowns: CityTown[];
  public stateCities: StateCity[];
  public citySettings: CitySettings[];
  public countriesStr: string[];
  public stateCitiesStr: string[];
  public countryStatesStr: string[];
  public cityTownsStr: string[];
  public citySettingsStr: string[];

  public searchingUnits: boolean;
  public searchingMagnitudes: boolean;
  public enableSearchByZipCode: boolean;
  public searchingStates: boolean;
  public searchingSettings: boolean;
  public searchingTowns: boolean;
  public searchingCities: boolean;
  public searchingAddress: boolean;
  public citiesInput: boolean;

  filteredLadas1?: Observable<string[]>;
  filteredLadas2?: Observable<string[]>;
  filteredTaxRegime?: Observable<string[]>;
  filteredCountries?: Observable<string[]>;
  filteredStates?: Observable<string[]>;
  filteredCities?: Observable<string[]>;
  filteredTowns?: Observable<string[]>;
  filteredSettings?: Observable<string[]>;

  viaPositions: ViaLocationPositions[];
  searchingStationPlans: boolean;
  stationInd: string | null;
  stationPlanesDataSource: MatTableDataSource<StationPlanesListItem>;
  stationPlanesDisplayedColumns = ['ID', 'ESTACION', 'ARCHIVO', 'NIVEL', 'ESTADO', 'USUARIO', 'FECHA', 'ACCIONES'];

  constructor(
    @Inject(DOCUMENT) private _document: Document,
    private _dialog: MatDialog,
    private _encService: EncService,
    private _sysAdminService: SystemAdminService,
    private _modulesService: ModulesService,
    private _matDialog: MatDialog,
    private _formService: DynamicFormService,
    private _router: Router,
    private _functionsService: FunctionsService,
    private _socketService: SocketService,
    private _usersProfilesService: UsersProfilesService,
    private _gdelService: GdelService,
    private _catalogMeasuresService: CatalogMeasuresService,
    private _resourcesService: ResourcesService,
    private _matIconRegistry: MatIconRegistry,
    private _domSanitizer: DomSanitizer,
  ) {
    this.isLoading = true;
    this.isLoadingFormDynamic = true;
    this.hasError = false;
    this.errorStr = "";
    this.magnitudeSelected = "";
    this.hexColorStr = "";
    this.decColorStr = "";
    this.hexSecColorStr = "";
    this.decSecColorStr = "";
    this.primaryFontColor = "";
    this.secondaryFontColor = "";
    this.primaryDecFontColor = "";
    this.secondaryDecFontColor = "";
    this.uploadingCustomIcon = false;

    this.modulesSettings = new Map();
    this.modulesModuleSelected = null;

    this.submodulesSettings = new Map();
    this.submodulesSubmoduleSelected = null;

    this.functionsSettings = new Map();
    this.functionsFunctionSelected = null;

    this.upImg = false;
    this.upBac = false;
    this.imgStr = "";
    this.bacStr = "";
    this.txtBuscador = '';
    this.btnSmall = window.innerWidth <= 1420;

    this.magnitudes = [];
    this.unitsByMagnitude = [];
    this.magnitudesAux = [];
    this.unitsByMagnitudeAux = [];
    this.materialIcons = [];
    this.modules = [];
    this.modulesStates = new Map<string, boolean>;
    this.iconsArr = new Map<string, string[]>;
    this.submodules = new Map<string, MenuSubmodule[]>;
    this.functionsPerSubmodule = new Map<string, Map<string, MenuFunction[]>>;
    this.functionsPerModule = new Map<string, MenuFunction[]>;
    this.iconsCategories = [];
    this.attached = [];

    this.dataSource = new MatTableDataSource<GetForms>();
    this.displayedColumns = [ 'CODIGO_FORMULARIO','TITULO_REGISTRO', 'TITULO_MODIFICACION', 'MODULO', 'FECHA_MODIFICA', 'ESTADO', 'ACCIONES' ];

    this.formsManagementEnabled = true;
    this.loginImagesEditEnabled = true;
    this.modulesIconsEditEnabled = true;
    this.submodulesIconsEditEnabled = true;
    this.functionsIconsEditEnabled = true;
    this.orderPrioritiesEnabled = true;
    this.unitsMagnitudesEnabled = true;
    this.taxInformationEnabled = true;

    this.currentHour = 0;
    this.currentMinutes = 0;
    this.currentSeconds = 0;
    this.orderPrioritiesArr = [];

    this.formGroupTax = this.createFormGroup();
    this.arrTaxRegime = [];
    this.taxRegimeStr = [];
    

    this.arrCountries = [];
    this.ladas = [];
    this.ladasStr = [];
    this.countries = [];
    this.countryStates = [];
    this.cityTowns = [];
    this.stateCities = [];
    this.citySettings = [];
    this.countriesStr = [];
    this.stateCitiesStr = [];
    this.countryStatesStr = [];
    this.cityTownsStr = [];
    this.citySettingsStr = [];

    this.searchingUnits = false;
    this.searchingMagnitudes = false;
    this.enableSearchByZipCode = true;
    this.searchingStates = false;
    this.searchingSettings = false;
    this.searchingTowns = false;
    this.searchingCities = false;
    this.searchingAddress = false;
    this.citiesInput = false;

    this.viaPositions = VIA_POSITIONS;
    this.searchingStationPlans = false;
    this.stationInd = null;
    this.stationPlanesDataSource = new MatTableDataSource();
  }

  private createFormGroup() {
    return new FormGroup({
      NOMBRE_FISCAL: new FormControl('', Validators.required),
      RFC: new FormControl('', [Validators.required, Validators.pattern(new RegExp(/^([A-ZÑ&]{3,4}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/))]),
      CORREO_ELECTRONICO: new FormControl('', [Validators.required, Validators.email]),
      REGIMEN_FISCAL: new FormControl('', Validators.required),
      LADA1: new FormControl('', Validators.required),
      TELEFONO_FIJO: new FormControl('', Validators.required),
      LADA2: new FormControl('', Validators.required),
      TELEFONO_MOVIL: new FormControl('', Validators.required),
      CODIGO_POSTAL: new FormControl('', Validators.required),
      TIPOVIALIDAD: new FormControl('', Validators.required),
      NOMBRE_VIALIDAD: new FormControl('', Validators.required),
      ENTRE_CALLE: new FormControl('', Validators.required),
      Y_CALLE: new FormControl('', Validators.required),
      NUMERO_EXTERIOR: new FormControl('', Validators.required),
      NUMERO_INTERIOR: new FormControl(''),
      COLONIA: new FormControl('', Validators.required),
      LOCALIDAD: new FormControl('', Validators.required),
      MUNICIPIO: new FormControl('', Validators.required),
      ENTIDAD_FEDERATIVA: new FormControl('', Validators.required),
      PAIS: new FormControl('', Validators.required),
    });
  }

  ngOnInit(): void {
    this.getTaxRegimeActive();
    this.getCoutries();
    this.getTaxInformation();
    this.getMaterialIcons();
    this.getMagnitudes();

    let primaryColorTheme = localStorage.getItem('primary_color_theme');
    if(primaryColorTheme != null && primaryColorTheme != undefined && primaryColorTheme != ''){
      this.hexColorStr = primaryColorTheme;
      this.hexSecColorStr = localStorage.getItem('secondary_color_theme')!;
      this.decColorStr = localStorage.getItem('primary_color_theme_dec')!.replace('rgb', '');
      this.decSecColorStr = localStorage.getItem('secondary_color_theme_dec')!.replace('rgba', '');
      this.primaryFontColor = localStorage.getItem('primary_font_color_theme')!;
      this.secondaryFontColor = localStorage.getItem('secondary_font_color_theme')!;
      this.primaryDecFontColor = localStorage.getItem('primary_font_color_theme_dec')!.replace('rgb', '');
      this.secondaryDecFontColor = localStorage.getItem('secondary_font_color_theme_dec')!.replace('rgb', '');
    }else{
      let lineColorHex = 'F54A91';
      let lineColorRGB = this._functionsService.colorHEXtoRGB(lineColorHex);
      
      this.hexColorStr = `#${lineColorHex}`;
      this.decColorStr = `(${lineColorRGB})`;
      this.hexSecColorStr = `#${lineColorHex}33`;
      this.decSecColorStr = `(${lineColorRGB}, 0.2)`;

      this.primaryFontColor = '#000000';
      this.secondaryFontColor = '#FFFFFF';
      this.primaryDecFontColor = '(0, 0, 0)';
      this.secondaryDecFontColor = '(255, 255, 255)';

      localStorage.setItem('primary_color_theme', this.hexColorStr); // Color primario del tema en hexadecimal
      localStorage.setItem('secondary_color_theme', this.hexSecColorStr); // Color secundaro del tema en hexadecimal
      localStorage.setItem('primary_color_theme_dec', `rgb${this.decColorStr}`); // Color primario del tema en RGB
      localStorage.setItem('secondary_color_theme_dec', `rgba${this.decSecColorStr}`); // Color secundario del tema en RGBA
      localStorage.setItem('primary_font_color_theme', this.primaryFontColor); // Color primario de la fuente del tema en hexadecimal
      localStorage.setItem('secondary_font_color_theme', this.secondaryFontColor); // Color secundario de la fuente del tema en hexadecimal
      localStorage.setItem('primary_font_color_theme_dec', `rgb${this.primaryDecFontColor}`); // Color primario de la fuente del tema en RGB
      localStorage.setItem('secondary_font_color_theme_dec', `rgb${this.secondaryDecFontColor}`); // Color secundario de la fuente en RGB
    }

    this.moduleNameModulesControl.valueChanges.subscribe(async (value) => {
      if(value != null && value != undefined && value != ''){
        this.moduleCustomIconModulesControl.enable();
        this.moduleIconModulesControl.enable();
        this.moduleStatusModulesControl.enable();

        let moduleObj = this.modulesSettings.get(value);
        if(moduleObj == null || moduleObj == undefined){
          this.moduleNameModulesControl.setValue(null, {
            emitEvent: false,
          });
        }else{
          let customIconEncrypted = await this._encService.isEncrypted(moduleObj.ICONO_PERSONALIZADO);
          let customIcon = customIconEncrypted ? await this._encService.decrypt(moduleObj.ICONO_PERSONALIZADO) : moduleObj.ICONO_PERSONALIZADO;
          let idUser = localStorage.getItem('idusuario')!;

          if(customIcon == 'S'){
            this.moduleCustomIconModulesControl.setValue(true);

            let customIconFileURL = await lastValueFrom(this._gdelService.getPublicDocumentUrl(
              moduleObj.ARCHIVO_ICONO_PERSONALIZADO!,
              idUser,
              1
            ));

            this._matIconRegistry.addSvgIcon(
              moduleObj.ICONO_MODULO,
              this._domSanitizer.bypassSecurityTrustResourceUrl(customIconFileURL.response.public_uri)
            );
          }else{
            let iconFilt = this.materialIcons.filter(icon => icon.name == moduleObj.ICONO_MODULO);
            if(iconFilt.length > 0){
              this.moduleIconModulesControl.setValue(iconFilt[0].name);
            }else{
              this.moduleIconModulesControl.setValue(null);
            }
            
            this.moduleCustomIconModulesControl.setValue(false);
          }
          
          this.moduleStatusModulesControl.setValue(moduleObj.ESTADO == 'A');
          moduleObj.ICONO_PERSONALIZADO = customIcon;

          if(this.modulesModuleSelected != null){
            let idModule = this.modulesModuleSelected.ID_MODULO;
            this.modulesSettings.set(idModule, this.modulesModuleSelected);
          }

          this.modulesModuleSelected = moduleObj;
        }
      }else{
        this.moduleCustomIconModulesControl.disable();
        this.moduleIconModulesControl.disable();
        this.moduleStatusModulesControl.disable();
      }
    });

    this.moduleNameSubmodulesControl.valueChanges.subscribe(async (value) => {
      if(this.submodulesSubmoduleSelected != null){
        for(const key of this.submodules.keys()){
          let module = this.submodules.get(key)!;
          let submoduleFilt = module.filter(item => item.IDSUBMODULO == this.submodulesSubmoduleSelected!.IDSUBMODULO);

          if(submoduleFilt.length > 0){
            submoduleFilt[0] = this.submodulesSubmoduleSelected!;
          }
        }
      }
      
      this.submoduleNameSubmodulesControl.setValue(null);
      if(value != null && value != undefined && value != ''){
        this.submoduleNameSubmodulesControl.enable();
      }else{
        this.submoduleNameSubmodulesControl.disable();
      }

      this.submodulesSubmoduleSelected = null;
      this.submoduleCustomIconSubmodulesControl.setValue(null);
      this.submoduleIconSubmodulesControl.setValue(null);
    });
    
    this.submoduleNameSubmodulesControl.valueChanges.subscribe(async (value) => {
      if(this.submodulesSubmoduleSelected != null){
        for(const key of this.submodules.keys()){
          let module = this.submodules.get(key)!;
          let submoduleFilt = module.filter(item => item.IDSUBMODULO == this.submodulesSubmoduleSelected!.IDSUBMODULO);

          if(submoduleFilt.length > 0){
            submoduleFilt[0] = this.submodulesSubmoduleSelected;
            this.submoduleCustomIconSubmodulesControl.setValue(null);
            this.submoduleIconSubmodulesControl.setValue(null);
          }
        }
      }

      if(value != null && value != undefined && value != ''){
        let moduleSelected = this.moduleNameSubmodulesControl.value!;
        let submodulesByModule = this.submodulesSettings.get(moduleSelected);

        if(submodulesByModule != null && submodulesByModule != undefined){
          let submoduleSelected = submodulesByModule.get(value);
          if(submoduleSelected != null && submoduleSelected != undefined){
            let customIcon = submoduleSelected.ICONO_PERSONALIZADO == 'S';
            if(customIcon){
              let idUser = localStorage.getItem('idusuario')!;
              let customIconFileURL = await lastValueFrom(this._gdelService.getPublicDocumentUrl(
                submoduleSelected.ARCHIVO_ICONO_PERSONALIZADO!,
                idUser,
                1
              ));

              this._matIconRegistry.addSvgIcon(
                submoduleSelected.ICONOSUBMODULO,
                this._domSanitizer.bypassSecurityTrustResourceUrl(customIconFileURL.response.public_uri)
              );
            }

            this.submoduleCustomIconSubmodulesControl.setValue(customIcon);
            this.submoduleIconSubmodulesControl.setValue(submoduleSelected.ICONOSUBMODULO);
            this.submodulesSubmoduleSelected = submoduleSelected;
            this.submoduleCustomIconSubmodulesControl.enable();
            this.submoduleIconSubmodulesControl.enable();
          }else{
            this.submoduleCustomIconSubmodulesControl.disable();
            this.submoduleIconSubmodulesControl.disable();
          }
        }else{
          this.submoduleCustomIconSubmodulesControl.disable();
          this.submoduleIconSubmodulesControl.disable();
        }
      }else{
        this.submoduleCustomIconSubmodulesControl.disable();
        this.submoduleIconSubmodulesControl.disable();
      }
    })

    this.moduleNameFunctionsControl.valueChanges.subscribe(async (value) => {
      if(this.functionsFunctionSelected != null){
        for(const key of this.functionsPerSubmodule.keys()){
          let submodule = this.functionsPerSubmodule.get(key)!;
          for(const key1 of submodule.keys()){
            let functions = submodule.get(key1)!;
            let functionFilt = functions.filter(item => item.IDFUNCION == this.functionsFunctionSelected!.IDFUNCION);

            if(functionFilt.length > 0){
              functionFilt[0] = this.functionsFunctionSelected;
              this.functionCustomIconFunctionsControl.setValue(null);
              this.functionIconFunctionsControl.setValue(null);
            }
          }
        }

        for(const key of this.functionsPerModule.keys()){
          let functions = this.functionsPerModule.get(key)!;
          let functionFilt = functions.filter(item => item.IDFUNCION == this.functionsFunctionSelected!.IDFUNCION);

          if(functionFilt.length > 0){
            functionFilt[0] = this.functionsFunctionSelected;
            this.functionCustomIconFunctionsControl.setValue(null);
            this.functionIconFunctionsControl.setValue(null);
          }
        }
      }

      this.submoduleNameFunctionsControl.setValue(null);
      this.functionNameFunctionsControl.setValue(null);

      if(value != null && value != undefined && value != ''){
        if(this.submodules.has(value)){
          this.submoduleNameFunctionsControl.enable();
        }else{
          this.functionNameFunctionsControl.enable();
        }
      }else{
        this.submoduleNameFunctionsControl.disable();
        this.functionNameFunctionsControl.disable();
      }

      this.functionsFunctionSelected = null;
      this.functionCustomIconFunctionsControl.setValue(null);
      this.functionIconFunctionsControl.setValue(null);
    });

    this.submoduleNameFunctionsControl.valueChanges.subscribe(async (value) => {
      if(this.functionsFunctionSelected != null){
        for(const key of this.functionsPerSubmodule.keys()){
          let submodule = this.functionsPerSubmodule.get(key)!;
          for(const key1 of submodule.keys()){
            let functions = submodule.get(key1)!;
            let functionFilt = functions.filter(item => item.IDFUNCION == this.functionsFunctionSelected!.IDFUNCION);

            if(functionFilt.length > 0){
              functionFilt[0] = this.functionsFunctionSelected;
              this.functionCustomIconFunctionsControl.setValue(null);
              this.functionIconFunctionsControl.setValue(null);
            }
          }
        }

        for(const key of this.functionsPerModule.keys()){
          let functions = this.functionsPerModule.get(key)!;
          let functionFilt = functions.filter(item => item.IDFUNCION == this.functionsFunctionSelected!.IDFUNCION);

          if(functionFilt.length > 0){
            functionFilt[0] = this.functionsFunctionSelected;
            this.functionCustomIconFunctionsControl.setValue(null);
            this.functionIconFunctionsControl.setValue(null);
          }
        }
      }

      this.functionNameFunctionsControl.setValue(null);
      if(value != null && value != undefined && value != ''){
        this.functionNameFunctionsControl.enable();
      }else{
        this.functionNameFunctionsControl.disable();
      }

      this.functionsFunctionSelected = null;
      this.functionCustomIconFunctionsControl.setValue(null);
      this.functionIconFunctionsControl.setValue(null);
    });

    this.functionNameFunctionsControl.valueChanges.subscribe(async (value) => {
      if(this.functionsFunctionSelected != null){
        for(const key of this.functionsPerSubmodule.keys()){
          let submodule = this.functionsPerSubmodule.get(key)!;
          for(const key1 of submodule.keys()){
            let functions = submodule.get(key1)!;
            let functionFilt = functions.filter(item => item.IDFUNCION == this.functionsFunctionSelected!.IDFUNCION);

            if(functionFilt.length > 0){
              functionFilt[0] = this.functionsFunctionSelected;
              this.functionCustomIconFunctionsControl.setValue(null);
              this.functionIconFunctionsControl.setValue(null);
            }
          }
        }

        for(const key of this.functionsPerModule.keys()){
          let functions = this.functionsPerModule.get(key)!;
          let functionFilt = functions.filter(item => item.IDFUNCION == this.functionsFunctionSelected!.IDFUNCION);

          if(functionFilt.length > 0){
            functionFilt[0] = this.functionsFunctionSelected;
            this.functionCustomIconFunctionsControl.setValue(null);
            this.functionIconFunctionsControl.setValue(null);
          }
        }
      }

      if(value != null && value != undefined && value != ''){
        let moduleSelected = this.moduleNameFunctionsControl.value!;
        let submodulesByModule = this.functionsPerSubmodule.get(moduleSelected);
        let functionsByModule = this.functionsPerModule.get(moduleSelected);

        if(submodulesByModule != null && submodulesByModule != undefined){
          let submoduleSelected = this.submoduleNameFunctionsControl.value!;
          let functionsBySubmodule = submodulesByModule.get(submoduleSelected);

          if(functionsBySubmodule != null && functionsBySubmodule != undefined){
            let functionSelectedFilt = functionsBySubmodule.filter(item => item.IDFUNCION == value);

            if(functionSelectedFilt.length > 0){
              let functionSelected = functionSelectedFilt[0];
              let customIcon = functionSelected.ICONO_PERSONALIZADO == 'S';
              if(customIcon){
                let idUser = localStorage.getItem('idusuario')!;
                let customIconFileURL = await lastValueFrom(this._gdelService.getPublicDocumentUrl(
                  functionSelected.ARCHIVO_ICONO_PERSONALIZADO!,
                  idUser,
                  1
                ));

                this._matIconRegistry.addSvgIcon(
                  functionSelected.ICONOFUNCION,
                  this._domSanitizer.bypassSecurityTrustResourceUrl(customIconFileURL.response.public_uri)
                );
              }

              this.functionCustomIconFunctionsControl.setValue(customIcon);
              this.functionIconFunctionsControl.setValue(functionSelected.ICONOFUNCION);
              this.functionsFunctionSelected = functionSelected;
              this.functionCustomIconFunctionsControl.enable();
              this.functionIconFunctionsControl.enable();
            }else{
              this.functionCustomIconFunctionsControl.disable();
              this.functionIconFunctionsControl.disable();
            }
          }else{
            this.functionCustomIconFunctionsControl.disable();
            this.functionIconFunctionsControl.disable();
          }
        }else if(functionsByModule != null && functionsByModule != undefined){
          let functionSelectedFilt = functionsByModule.filter(item => item.IDFUNCION == value);

          if(functionSelectedFilt.length > 0){
            let functionSelected = functionSelectedFilt[0];
            let customIcon = functionSelected.ICONO_PERSONALIZADO == 'S';
            if(customIcon){
              let idUser = localStorage.getItem('idusuario')!;
              let customIconFileURL = await lastValueFrom(this._gdelService.getPublicDocumentUrl(
                functionSelected.ARCHIVO_ICONO_PERSONALIZADO!,
                idUser,
                1
              ));

              this._matIconRegistry.addSvgIcon(
                functionSelected.ICONOFUNCION,
                this._domSanitizer.bypassSecurityTrustResourceUrl(customIconFileURL.response.public_uri)
              );
            }

            this.functionCustomIconFunctionsControl.setValue(customIcon);
            this.functionIconFunctionsControl.setValue(functionSelected.ICONOFUNCION);
            this.functionsFunctionSelected = functionSelected;
            this.functionCustomIconFunctionsControl.enable();
            this.functionIconFunctionsControl.enable();
          }else{
            this.functionCustomIconFunctionsControl.disable();
            this.functionIconFunctionsControl.disable();
          }
        }else{
          this.functionCustomIconFunctionsControl.disable();
          this.functionIconFunctionsControl.disable();
        }
      }else{
        this.functionCustomIconFunctionsControl.disable();
        this.functionIconFunctionsControl.disable();
      }
    });
    
    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
      try{
        let idUser = localStorage.getItem('idusuario')!;
        let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesService.getUser(idUser, idUser, 1));
        
        if(usrInfo.error){
          this._resourcesService.openSnackBar('ERR_NPE000: Ocurrió un error inesperado.');
        }else{
          let idProfDec = await this._encService.decrypt(usrInfo.response.PERFIL);
          let currentProfile = await this._encService.decrypt(localStorage.getItem('perfil')!);

          if(idProfDec != currentProfile){
            this._router.navigate(['/sam/home']);
            return;
          }
          
          let profileUpdated = await this._encService.decrypt(`${profUpdEnc}`);
          if(profileUpdated == currentProfile){
            let profile = localStorage.getItem('perfil')!;
            let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesService.getProfile(
              profile,
              idUser,
              1
            ));

            let permArr = await this._functionsService.processPermissions(profInfo.response.PERMISOS.permissions);
            let modPerm = permArr.filter(item => item.id == 'S002V01M01ADSI');
            if(modPerm.length > 0){
              let funPerm = modPerm[0].children.filter(item => item.id == 'S002V01F11PASI');
              if(funPerm.length > 0){
                let formsManagementEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P01GEFO');
                if(formsManagementEnabled.length > 0){
                  this.formsManagementEnabled = formsManagementEnabled[0].access > 0;
                }

                let loginImagesEditEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P04EILO');
                if(loginImagesEditEnabled.length > 0){
                  this.loginImagesEditEnabled = loginImagesEditEnabled[0].access > 0;
                }

                let modulesIconsEditEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P05EIMO');
                if(modulesIconsEditEnabled.length > 0){
                  this.modulesIconsEditEnabled = modulesIconsEditEnabled[0].access > 0;
                }

                let submodulesIconsEditEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P06EISU');
                if(submodulesIconsEditEnabled.length > 0){
                  this.submodulesIconsEditEnabled = submodulesIconsEditEnabled[0].access > 0;
                }

                let functionsIconsEditEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P07EIFU');
                if(functionsIconsEditEnabled.length > 0){
                  this.functionsIconsEditEnabled = functionsIconsEditEnabled[0].access > 0;
                }

                let orderPrioritiesEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P08EPOT');
                if(orderPrioritiesEnabled.length > 0){
                  this.orderPrioritiesEnabled = orderPrioritiesEnabled[0].access > 0;
                }

                let unitsMagnitudesEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P09MAUN');
                if(unitsMagnitudesEnabled.length > 0){
                  this.unitsMagnitudesEnabled = unitsMagnitudesEnabled[0].access > 0;
                }

                let taxInformationEnabled = funPerm[0].children.filter(item => item.id == 'S002V01TP10INFI');
                if(taxInformationEnabled.length > 0){
                  this.taxInformationEnabled = taxInformationEnabled[0].access > 0;
                }
              }
            }
          }
        }
      }catch(error: any){
        if(error.error == undefined){
          this._resourcesService.openSnackBar('ERR_PAD001: Ocurrió un error inesperado.');
        }else if(error.error.msg == undefined){
          this._resourcesService.openSnackBar('ERR_PAD002: Ocurrió un error inesperado.');
        }else{
          this._resourcesService.openSnackBar(`ERR_PAD003: ${error.error.msg}`);
        }
      }
    });

    this.formGroupTax.controls['LOCALIDAD'].valueChanges.subscribe(value => {
      if(!this.enableSearchByZipCode) {
        let countryVal = this.formGroupTax.controls['PAIS'].value;
        let countryArr = countryVal.split('(').reverse();
        let countryCode = countryArr[0].replace(')', '');

        if(countryCode == 'MEX'){
          let validValue = this.cityTownsStr.filter(item => item == value);
          if(validValue.length > 0){
            let valueArr = value.split('(').reverse();
            let townCode = valueArr[0].replace(')', '');

            this.verifyTown(townCode);
          }else{
            this.formGroupTax.controls['COLONIA'].setValue('');
            this.formGroupTax.controls['COLONIA'].disable();
          }
        }else{
          this.formGroupTax.controls['COLONIA'].enable();
        }
      }
    })

    this.filteredLadas1 = this.formGroupTax.controls['LADA1'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.ladasStr.filter((item) => item.toLowerCase().includes(filterValue));
      })
    );

    this.filteredLadas2 = this.formGroupTax.controls['LADA2'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.ladasStr.filter((item) => item.toLowerCase().includes(filterValue));
      })
    );

    this.filteredTaxRegime = this.formGroupTax.controls['REGIMEN_FISCAL'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.taxRegimeStr.filter(item => item.toLowerCase().includes(filterValue));
      })
    );

    this.filteredSettings = this.formGroupTax.controls['COLONIA'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.citySettingsStr.filter(item => item.toLowerCase().includes(filterValue));
      }),
    );

    this.filteredTowns = this.formGroupTax.controls['LOCALIDAD'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.cityTownsStr.filter(item => item.toLowerCase().includes(filterValue));
      }),
    );
    
    this.filteredCities = this.formGroupTax.controls['MUNICIPIO'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.stateCitiesStr.filter(item => item.toLowerCase().includes(filterValue));
      })
    );

    this.filteredStates = this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.countryStatesStr.filter(item => item.toLowerCase().includes(filterValue));
      })
    );

    this.filteredCountries = this.formGroupTax.controls['PAIS'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        let countries = this.countriesStr.filter(item => item.toLowerCase().includes(filterValue));

        return countries;
      })
    );
  }

  openColorSelector(type: string){
    let dialogRef = this._dialog.open(SelectColorComponent, {
      width: '420px',
      minWidth: '420px',
      disableClose: true,
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        if(res.includes('rgb(')){
          let colorRGB = res.replace('rgb(', '').replace(')', '');
          let colorHEX = this._functionsService.colorRGBtoHEX(colorRGB);
          console.log(colorHEX);
        }
      }
    });
  }

  private async getTaxRegimeActive() {
    const idUser: string = this._resourcesService.getUser();
    const line: number =  this._resourcesService.getLineNumber();
    await lastValueFrom(this._sysAdminService.getTaxRegimeList(idUser, line)).then(
      (responseData: TaxRegimeListResponse) => {
        if (!responseData.error) {
          this.arrTaxRegime = responseData.response;
          let moralTaxRegime = this.arrTaxRegime.filter(item => item.APPLY_MORAL == 'Sí');
          this.taxRegimeStr = [];
          moralTaxRegime.forEach(item => {
            this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`);
          });
        } else {
          this._resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getTaxRegimeActive();
        }
      }
    );
  }

  private async getCoutries() {
    const idUser: string = this._resourcesService.getUser();
    const line: number = this._resourcesService.getLineNumber();
    await lastValueFrom(this._sysAdminService.getCountriesList(idUser, line)).then(
      (responseData: CountriesListResponse) => {
        if (!responseData.error) {
          this.arrCountries = responseData.response;

          let mex = responseData.response.filter(item => item.COUNTRY_ID == 'MEX');
          this.arrCountries.push(mex[0]);
          this.countriesStr.push(`${mex[0].NAME} (${mex[0].COUNTRY_ID})`);

          let mexLada: LadaSelection = {
            FLAG: '',
            LADA: mex[0].LADA!
          };          
          
          this.ladas.push(mexLada);
          this.ladasStr.push(`${mexLada.FLAG} ${mexLada.LADA}`);

          let usa = responseData.response.filter(item => item.COUNTRY_ID == 'USA');
          this.arrCountries.push(usa[0]);
          this.countriesStr.push(`${usa[0].NAME} (${usa[0].COUNTRY_ID})`);

          let usaLada: LadaSelection = {
            FLAG: '',
            LADA: usa[0].LADA!
          };
          
          this.ladas.push(usaLada);
          this.ladasStr.push(`${usaLada.FLAG} ${usaLada.LADA}`);

          let can = responseData.response.filter(item => item.COUNTRY_ID == 'CAN');
          this.arrCountries.push(can[0]);
          this.countriesStr.push(`${can[0].NAME} (${can[0].COUNTRY_ID})`);

          let canLada: LadaSelection = {
            FLAG: '',
            LADA: can[0].LADA!
          };
          
          this.ladas.push(canLada);
          this.ladasStr.push(`${canLada.FLAG} ${canLada.LADA}`);
                    
          responseData.response.forEach(country => {
            if(country.COUNTRY_ID != null && country.COUNTRY_ID != 'MEX' && country.COUNTRY_ID != 'USA' && country.COUNTRY_ID != 'CAN'){
              this.arrCountries.push(country);
              this.countriesStr.push(`${country.NAME} (${country.COUNTRY_ID})`);

              try{
                //flag(country.NOMECLARUTA_ISO2!);
                let hasLada = country.LADA != '';

                if(hasLada){
                  let lada: LadaSelection = {
                    FLAG: '',
                    LADA: country.LADA!
                  };

                  this.ladas.push(lada);
                  this.ladasStr.push(`${lada.FLAG} ${lada.LADA}`);
                }
              }catch(error: any){
                //Saltar país
              }
            }
          });

        } else {
          this._resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getCoutries();
        }
      }
    );
  }

  private async getTaxInformation() {

    this.isLoading = true;
    const LINE_NUMBER: number = this._resourcesService.getLineNumber();
    await lastValueFrom(this._sysAdminService.getTaxInformation(LINE_NUMBER)).then(
      (responseData: ResponseDataGetTaxInformation) => {
        if (!responseData.error) {
          if (responseData.response !== null) {
            this.formGroupTax.controls['NOMBRE_FISCAL'].setValue(responseData.response.INFI_NOFI);
            this.formGroupTax.controls['RFC'].setValue(responseData.response.INFI_XRFC);
            this.formGroupTax.controls['CORREO_ELECTRONICO'].setValue(responseData.response.INFI_COEL);
            this.formGroupTax.controls['REGIMEN_FISCAL'].setValue(responseData.response.INFI_CORF);
            this.formGroupTax.controls['LADA1'].setValue(responseData.response.INFI_LAD1);
            this.formGroupTax.controls['TELEFONO_FIJO'].setValue(responseData.response.INFI_TEL1);
            this.formGroupTax.controls['LADA2'].setValue(responseData.response.INFI_LAD2);
            this.formGroupTax.controls['TELEFONO_MOVIL'].setValue(responseData.response.INFI_TEL2);
            this.formGroupTax.controls['CODIGO_POSTAL'].setValue(responseData.response.INFI_COPO);
            this.formGroupTax.controls['TIPOVIALIDAD'].setValue(responseData.response.INFI_TIVI);
            this.formGroupTax.controls['NOMBRE_VIALIDAD'].setValue(responseData.response.INFI_VIAL);
            this.formGroupTax.controls['ENTRE_CALLE'].setValue(responseData.response.INFI_ENCA);
            this.formGroupTax.controls['Y_CALLE'].setValue(responseData.response.INFI_YCAL);
            this.formGroupTax.controls['NUMERO_EXTERIOR'].setValue(responseData.response.INFI_NUEX);
            this.formGroupTax.controls['NUMERO_INTERIOR'].setValue(responseData.response.INFI_NUIN);
            this.formGroupTax.controls['COLONIA'].setValue(responseData.response.INFI_COLO);
            this.formGroupTax.controls['LOCALIDAD'].setValue(responseData.response.INFI_LOCA);
            this.formGroupTax.controls['MUNICIPIO'].setValue(responseData.response.INFI_MUNI);
            this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].setValue(responseData.response.INFI_ENFE);
            this.formGroupTax.controls['PAIS'].setValue(responseData.response.INFI_PAIS);
          } else {
            this._resourcesService.openSnackBar(`No hay información fiscal registrada`);
          }
        } else {
          this._resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getTaxInformation();
        }
      }
    );
  }

  async getMaterialIcons(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let materialIcons: MaterialIconsResponse = await lastValueFrom(this._sysAdminService.getMaterialIcons(idUser, 1));

      this.hasError = materialIcons.error;
      if(!this.hasError){
        this.materialIcons = materialIcons.response;
      }else{
        this.errorStr = materialIcons.msg;
        this.isLoading = false;
      }

      this.materialIcons.forEach(icon => {
        let categorie = icon.categorie[0];
        if(this.iconsArr.has(categorie)){
          let arr = this.iconsArr.get(categorie);
          arr?.push(icon.name);
        }else{
          let arr = [icon.name];
          this.iconsArr.set(categorie, arr);
        }
      });

      this.iconsCategories = Array.from(this.iconsArr.keys());
      this.getModules();
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = "Ocurrió un error inesperado.";
      }else if(error.error.msg == undefined){
        this.errorStr = "Ocurrió un error inesperado.";
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = false;
    }
  }

  checkFileSVG(event: any, type: 'M' | 'S' | 'F'){
    this.uploadingCustomIcon = true;

    let extArr = event.target.files[0].name.split(".").reverse();
    let extStr = extArr[0];

    if(extStr.toLowerCase() != 'svg'){
      this.uploadingCustomIcon = false;
      this._resourcesService.openSnackBar(`Solamente se admiten archivos SVG para iconos personalizados.`);
      return;
    }

    if(this.imageFormats.includes(extStr)){
      let maxFileSize = 1048576 * 250;
      let fileSize = event.target.files[0].size;

      if(fileSize > maxFileSize){
        this._resourcesService.openSnackBar(`El tamaño del archivo supera el límite de 75 MB`);
        this.uploadingCustomIcon = false;
      }else{
        let dialogRef = this._matDialog.open(AlertComponent, {
          data: {
            title: 'Advertencia',
            icon: 'warning',
            description: '¿Está seguro de realizar la acción solicitada?'
          }
        });

        dialogRef.afterClosed().subscribe(res => {
          if(res == true){
            this._resourcesService.openSnackBar('Cargando icono...');
            this.uploadTmp(event.target.files[0], type);
          }else{
            this.uploadingCustomIcon = false;
          }
        });
      }
    }else{
      this.uploadingCustomIcon = false;
      this._resourcesService.openSnackBar('El archivo seleccionado no tiene un formato de imagen');
    }
  }

  async uploadTmp(fileData: any, type: 'M' | 'S' | 'F'){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();

      formData.append('file', fileData);
      formData.append('id_user', idUser);
      formData.append('linea', "1");

      let response = await lastValueFrom(this._gdelService.uploadTempFile(formData));

      if(response.error){
        this._resourcesService.openSnackBar(response.msg);
        this.uploadingCustomIcon = false;
      }else{
        let customIconURL = await lastValueFrom(this._gdelService.getPublicTempDocumentUrl(
          response.response.idArchivo,
          idUser,
          1
        ));
        
        let sanitizedIconName = this._functionsService.sanitizeIconName(fileData.name);
        this._matIconRegistry.addSvgIcon(
          sanitizedIconName,
          this._domSanitizer.bypassSecurityTrustResourceUrl(customIconURL.response.public_uri)
        );

        if(type == 'M'){
          this.modulesModuleSelected!.ICONO_MODULO = sanitizedIconName;
          this.modulesModuleSelected!.ICONO_PERSONALIZADO = "S";
          this.modulesModuleSelected!.ARCHIVO_ICONO_PERSONALIZADO = response.response.idArchivo;
        }else if(type == 'S'){
          this.submodulesSubmoduleSelected!.ICONOSUBMODULO = sanitizedIconName;
          this.submodulesSubmoduleSelected!.ICONO_PERSONALIZADO = "S";
          this.submodulesSubmoduleSelected!.ARCHIVO_ICONO_PERSONALIZADO = response.response.idArchivo;
        }else if(type == 'F'){
          this.functionsFunctionSelected!.ICONOFUNCION = sanitizedIconName;
          this.functionsFunctionSelected!.ICONO_PERSONALIZADO = "S";
          this.functionsFunctionSelected!.ARCHIVO_ICONO_PERSONALIZADO = response.response.idArchivo;
        }

        this.uploadingCustomIcon = false;
        this._resourcesService.openSnackBar(`El icono ${fileData.name} se cargó correctamente.`);
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.uploadingCustomIcon = false;
    }
  }

  customIconStatusUpdated(event: any, type: 'M' | 'S' | 'F'){
    if(!event.checked && type == 'M'){
      this.modulesModuleSelected!.ICONO_MODULO = "";
      this.modulesModuleSelected!.ICONO_PERSONALIZADO = "N";
      this.modulesModuleSelected!.ARCHIVO_ICONO_PERSONALIZADO = null;
      this.moduleIconModulesControl.setValue(null);
    }else if(!event.checked && type == 'S'){
      this.submodulesSubmoduleSelected!.ICONOSUBMODULO = "";
      this.submodulesSubmoduleSelected!.ICONO_PERSONALIZADO = "N";
      this.submodulesSubmoduleSelected!.ARCHIVO_ICONO_PERSONALIZADO = null;
      this.submoduleIconSubmodulesControl.setValue(null);
    }else if(!event.checked && type == 'F'){
      this.functionsFunctionSelected!.ICONOFUNCION = "";
      this.functionsFunctionSelected!.ICONO_PERSONALIZADO = "N";
      this.functionsFunctionSelected!.ARCHIVO_ICONO_PERSONALIZADO = null;
      this.functionIconFunctionsControl.setValue(null);
    }
  }

  openGridIcons(type: 'M' | 'S' | 'F'){
    if(this.moduleIconModulesControl.disabled && type == 'M') return;
    if(this.submoduleIconSubmodulesControl.disabled && type == 'S') return;
    
    let dialogRef = this._dialog.open(GridIconsSelectorComponent, {
      width: '640px',
      maxWidth: '640px',
      disableClose: true,
      data: {
        materialIcons: this.materialIcons,
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        if(type == 'M'){
          this.moduleIconModulesControl.setValue(res);
        }else if(type == 'S'){
          this.submoduleIconSubmodulesControl.setValue(res);
        }else if(type == 'F'){
          this.functionIconFunctionsControl.setValue(res);
        }

        this.updateModuleIcon(res, type);
      }
    });
  }

  async getModules(refresh: boolean = false){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let menu: MenuResponse = await lastValueFrom(this._modulesService.getMenu(idUser, 1));

      this.hasError = menu.error;
      if(this.hasError){
        this.errorStr = menu.msg;
        this.isLoading = false;
      }else{
        for(const mod of menu.response){
          if(mod.SUBMODULES.length > 0){
            let moduleSubmodules: Map<string, MenuSubmodule> = new Map();
            let moduleSubmoduleFunctions: Map<string, Map<string, MenuFunction>> = new Map();
            let submodules: MenuSubmodule[] = [];
            let functionsBySubmodule: Map<string, MenuFunction[]> = new Map();

            for(const submod of mod.SUBMODULES){
              let functions: MenuFunction[] = [];
              let submoduleFunctions: Map<string, MenuFunction> = new Map();

              for(const func of submod.FUNCIONES){
                functions.push(func);
                submoduleFunctions.set(func.IDFUNCION, func);
              }

              functionsBySubmodule.set(submod.IDSUBMODULO, functions);
              moduleSubmoduleFunctions.set(submod.IDSUBMODULO, submoduleFunctions);
              submodules.push(submod);
              moduleSubmodules.set(submod.IDSUBMODULO, submod);
            }

            this.functionsPerSubmodule.set(mod.ID_MODULO, functionsBySubmodule);
            this.submodules.set(mod.ID_MODULO, submodules);
            this.submodulesSettings.set(mod.ID_MODULO, moduleSubmodules);
            this.functionsSettings.set(mod.ID_MODULO, moduleSubmoduleFunctions);
          }else{
            let moduleFunctions: MenuFunction[] = [];
            let functionsByModule: Map<string, MenuFunction> = new Map();

            for(const menu of mod.MENUS){
              moduleFunctions.push(menu);
              functionsByModule.set(menu.IDFUNCION, menu);
            }

            this.functionsPerModule.set(mod.ID_MODULO, moduleFunctions);
            this.functionsSettings.set(mod.ID_MODULO, functionsByModule);
          }

          let module: ModuleInterface = {
            ID_MODULO: mod.ID_MODULO,
            NOMBRE_MODULO: mod.NOMBRE_MODULO,
            ICONO_MODULO: mod.ICONO_MODULO,
            ESTADO_MODULO: mod.ESTADO == 'E',
          };

          this.modules.push(module);
          this.modulesStates.set(mod.ID_MODULO, mod.ESTADO == 'E');
          this.modulesSettings.set(mod.ID_MODULO, mod);
        }
        
        if(!refresh) this.getLoginImages();
        else this.isLoading = false;
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = false;
    }
  }

  changeModuleState(event: MatSlideToggleChange){
    if(this.moduleName.value != null && this.moduleName.value != undefined && this.moduleName.value != ''){
      if(this.modulesStates.has(this.moduleName.value)){
        this.modulesStates.set(this.moduleName.value, event.checked);
        
        let moduleFilt = this.modules.filter(item => item.ID_MODULO == this.moduleName.value);
        if(moduleFilt.length > 0){
          moduleFilt[0].ESTADO_MODULO = event.checked;
        }
      }
    }
  }

  async getLoginImages(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let loginImages: LoginParamsResponse = await lastValueFrom(this._sysAdminService.getLoginImages(idUser, 1));

      if(loginImages.error){
        this.errorStr = loginImages.msg;
        this.hasError = true;
        this.isLoading = false;
      }else{
        this.imgStr = `http://git.ittec.mx/sam/public/assets/${loginImages.response.login_params.login_image}`;
        this.bacStr = `http://git.ittec.mx/sam/public/assets/${loginImages.response.login_params.login_background}`;

        this.upBac = false;
        this.upImg = false;
        this.obtenerFormularios();
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = false;
    }
  }

  public async obtenerFormularios() {
    this.isLoadingFormDynamic = true;
    const USER: string = this._resourcesService.getUser();
    const LINE: number = this._resourcesService.getLineNumber();
    await lastValueFrom(this._formService.getForms(USER, LINE)).then(
      (responseData: ResponseDataGetForms) => {        
        if (!responseData.error) {
          this.dataSource.data = responseData.response;
        } else {
          this._resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.obtenerFormularios();
        }
      }
    );
    this.isLoadingFormDynamic = false;

    let permissionsEnc = localStorage.getItem('permisos');
    let permissionsDec = await this._encService.decrypt(permissionsEnc!);
    let permissionsArr: Permissions = JSON.parse(permissionsDec);

    let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M01ADSI')[0];
    let funPerm = modPerm.children.filter(item => item.id == 'S002V01F11PASI')[0];

    this.formsManagementEnabled = funPerm.children.filter(item => item.id == 'S002V01P01GEFO')[0].access > 0;
    this.loginImagesEditEnabled = funPerm.children.filter(item => item.id == 'S002V01P04EILO')[0].access > 0;
    this.modulesIconsEditEnabled = funPerm.children.filter(item => item.id == 'S002V01P05EIMO')[0].access > 0;
    this.submodulesIconsEditEnabled = funPerm.children.filter(item => item.id == 'S002V01P06EISU')[0].access > 0;
    this.functionsIconsEditEnabled = funPerm.children.filter(item => item.id == 'S002V01P07EIFU')[0].access > 0;
    this.orderPrioritiesEnabled = funPerm.children.filter(item => item.id == 'S002V01P08EPOT')[0].access > 0;
    this.unitsMagnitudesEnabled = funPerm.children.filter(item => item.id == 'S002V01P09MAUN')[0].access > 0;
    this.taxInformationEnabled = funPerm.children.filter(item => item.id == 'S002V01TP10INFI')[0].access > 0;

    this.getOrderPriorities();
  }

  async getOrderPriorities(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let priorities = await lastValueFrom(this._sysAdminService.getOrderPriorities(idUser, 1));

      if(priorities.error){
        this.errorStr = priorities.msg;
        this.hasError = true;
      }else{
        this.orderPrioritiesArr = priorities.response.order_priorities;
      }

      this.isLoading = false;
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
    }
  }

  async getMagnitudes(){
    try{
      this.searchingMagnitudes = true;

      let idUser = localStorage.getItem('idusuario')!;
      let magnitudes: MagnitudesListResponse = await lastValueFrom(this._sysAdminService.getMagnitudes(idUser, 1));

      if(!magnitudes.error){
        let magnitudesArr: MagnitudesListItem[] = [];
        for(const magnitude of magnitudes.response){
          let idDec = await this._encService.decrypt(magnitude.ID_MAGNITUD);
          magnitude.MAGNITUD = `${magnitude.MAGNITUD} (${idDec})`;

          if(magnitude.ESTADO == 'Activo'){
            magnitudesArr.push(magnitude);
          }
        }

        this.magnitudes = magnitudesArr;
        this.magnitudesAux = this.magnitudes;
      }

      this.searchingMagnitudes = false;
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = 'Ocurrió un error inesperado.';
      }

      this.hasError = true;
      this.isLoading = false;
      this.searchingMagnitudes = false;
    }
  }

  private verifyTown(value: string){
    let stateVal = this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].value;
    let stateArr = stateVal.split('(').reverse();
    let stateCode = stateArr[0].replace(')', '');

    let cityVal = this.formGroupTax.controls['MUNICIPIO'].value;
    let cityArr = cityVal.split('(').reverse();
    let cityCode = cityArr[0].replace(')', '');
    
    this.citySettings = [];
    this.citySettingsStr = [];
    
    let townCode = value == 'Sin localidad' ? '-' : value;
    this.searchCitySettings(stateCode, cityCode, townCode);
  }
  
  private async searchCitySettings(stateCode: string, cityCode: string, townCode: string){
    this.searchingSettings = true;

    const idUser: string = this._resourcesService.getUser();
    const stateCodeEnc: string = await this._encService.encrypt(stateCode);
    const cityCodeEnc: string = await this._encService.encrypt(cityCode);
    const townCodeEnc: string = await this._encService.encrypt(townCode);
    const line: number = this._resourcesService.getLineNumber();

    await lastValueFrom(this._sysAdminService.getCitySettings(stateCodeEnc,cityCodeEnc,townCodeEnc,idUser,line)).then(
      (responseData: CitySettingsResponse) => {
        if (!responseData.error) {
          this.citySettings = responseData.response;
          this.citySettingsStr = [];

          this.citySettings.forEach(setting => {
            this.citySettingsStr.push(`${setting.NOMBRECOLONIA} (${setting.CODIGOCOLONIA})`);
          });

          this.formGroupTax.controls['COLONIA'].enable();
        } else {
          this._resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchCitySettings(stateCode, cityCode, townCode);
        }
      }
    );
    this.searchingSettings = false;
  }

  public onResize():void {
    this.btnSmall = window.innerWidth <= 1420;
  }

  goBack(steps: number){
    window.history.go(steps * -1);
  }

  imageHandler(type: string){
    if(type == 'img'){
      this.upImg = true;
      this.file?.nativeElement.click();
    }else{
      this.upBac = true;
      this.file?.nativeElement.click();
    }
  }

  checkFile(event: any){
    let extArr = event.target.files[0].name.split(".").reverse();
    let extStr = extArr[0];

    if(this.imageFormats.includes(extStr)){
      let maxFileSize = 1048576 * 250;
      let fileSize = event.target.files[0].size;

      if(fileSize > maxFileSize){
        this._resourcesService.openSnackBar(`El tamaño del archivo supera el límite de 75 MB`);
      }else{
        let dialogRef = this._matDialog.open(AlertComponent, {
          data: {
            title: 'Advertencia',
            icon: 'warning',
            description: '¿Está seguro de realizar la acción solicitada?'
          }
        });

        dialogRef.afterClosed().subscribe(res => {
          if(res == true){
            let type = this.upImg ? 'img' : 'bac';
            this.updateImg(type, event.target.files[0]);
          }else{
            this.upImg = false;
            this.upBac = false;
          }
        });
      }
    }else{
      this._resourcesService.openSnackBar('El archivo seleccionado no tiene un formato de imagen');
      this.cancelHandle();
    }
  }

  async updateImg(type: string, fileData: any){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();

      formData.append('file', fileData);
      formData.append('id_user', idUser);
      formData.append('linea', "1");

      let response = await lastValueFrom(this._gdelService.uploadTempFile(formData));
      if(response.error){
        this._resourcesService.openSnackBar(response.msg);
        this.upBac = false;
        this.upImg = false;
      }else{
        let tipo = type == 'img' ? 'image' : 'background';
        let formData = new FormData();

        formData.append('id_user', idUser!);
        formData.append('linea', '1');
        formData.append('tipo', tipo);
        formData.append('archivo', response.response.idArchivo);

        await lastValueFrom(this._sysAdminService.saveLoginImage(formData));

        window.location.reload();
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.upBac = false;
      this.upImg = false;
    }
  }

  cancelHandle(){
    this.upBac = false;
    this.upImg = false;
  }

  updateModuleIcon(newIcon: string, type: 'M' | 'S' | 'F'){
    if(type == 'M') this.modulesModuleSelected!.ICONO_MODULO = newIcon;
    if(type == 'S') this.submodulesSubmoduleSelected!.ICONOSUBMODULO = newIcon;
    if(type == 'F') this.functionsFunctionSelected!.ICONOFUNCION = newIcon;
  }

  async saveModules(){
    try{
      if(this.modulesModuleSelected != null && this.modulesSettings.has(this.modulesModuleSelected.ID_MODULO)){
        this.modulesSettings.set(this.modulesModuleSelected.ID_MODULO, this.modulesModuleSelected);
      }

      let modulesArr: MenuModule[] = [];
      for(const key of this.modulesSettings.keys()){
        if(this.modulesSettings.has(key)){
          let moduleObj = this.modulesSettings.get(key)!;
          let customIconEnc = await this._encService.isEncrypted(moduleObj.ICONO_PERSONALIZADO);
          
          if(!customIconEnc){
            moduleObj.ICONO_PERSONALIZADO = await this._encService.encrypt(moduleObj.ICONO_PERSONALIZADO);
          }

          modulesArr.push(moduleObj);
        }
      }
      
      let modulesStr = JSON.stringify(modulesArr);
      let modulesEnc = await this._encService.encrypt(modulesStr);
      let idUser = localStorage.getItem('idusuario');
      let info = new FormData();

      info.append('id_user', idUser!);
      info.append('linea', '1');
      info.append('module_icons', modulesEnc);

      await lastValueFrom(this._sysAdminService.updateModuleIcons(info));

      this.modulesModuleSelected = null;
      this._resourcesService.openSnackBar('Los iconos de los módulos se actualizaron correctamente.');
      this._socketService.modulesUpdated();

      this.isLoading = true;
      this.modules = [];
      this.modulesSettings = new Map();
      this.submodules = new Map();
      this.getModules(true);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async saveSubmodules(){
    try{
      let idUser = localStorage.getItem('idusuario');
      let submodulesStr = JSON.stringify(Object.fromEntries(this.submodules));
      let submodulesEnc = await this._encService.encrypt(submodulesStr);
      let formData = new FormData();

      formData.append('id_user', idUser!);
      formData.append('linea', '1');
      formData.append('submodule_icons', submodulesEnc);

      await lastValueFrom(this._sysAdminService.updateSubmoduleIcons(formData));
      this._resourcesService.openSnackBar('Los iconos de los submódulos se actualizaron correctamente.');

      this.isLoading = true;
      this.modules = [];
      this.modulesSettings = new Map();
      this.submodules = new Map();
      this.getModules(true);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async saveFunctions(){
    try{
      let functionsPerModuleStr = JSON.stringify(Object.fromEntries(this.functionsPerModule));
      let functionsPerModuleEnc = await this._encService.encrypt(functionsPerModuleStr);

      let functionsPerSubmoduleObjAuxStr = JSON.stringify(Object.fromEntries(this.functionsPerSubmodule));
      let functionsPerSubmoduleObjAux = JSON.parse(functionsPerSubmoduleObjAuxStr);

      this.functionsPerSubmodule.forEach((value, key) => {
        let functionsAux = Object.fromEntries(value);
        functionsPerSubmoduleObjAux[key] = functionsAux;
      });

      let functionsPerSubmoduleStr = JSON.stringify(functionsPerSubmoduleObjAux);
      let functionsPerSubmoduleEnc = await this._encService.encrypt(functionsPerSubmoduleStr);

      let idUser = localStorage.getItem('idusuario');
      let info = new FormData();

      info.append('id_user', idUser!);
      info.append('linea', '1');
      info.append('module_functions_icons', functionsPerModuleEnc);
      info.append('submodule_functions_icons', functionsPerSubmoduleEnc);

      await lastValueFrom(this._sysAdminService.updateFunctionIcons(info));
      this._resourcesService.openSnackBar('Los iconos de las funciones se actualizaron correctamente.');
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  editPriority(priorityVal: string){
    let priority = this.orderPrioritiesArr.filter(item => item.value == priorityVal)[0];
    let dialogReg = this._matDialog.open(EditPriorityComponent, {
      disableClose: true,
      width: '480px',
      data: {
        priority: priority,
      }
    });

    dialogReg.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ""){
        this.updatePriority(res);
      }
    });
  }

  async updatePriority(priorityStr: string){
    try{
      let idUser = localStorage.getItem('idusuario');
      let priorityObj: PriorityInterface = JSON.parse(priorityStr);
      let prioritiesArrAux: PriorityInterface[] = [];

      this.orderPrioritiesArr.forEach(item => {
        if(item.value == priorityObj.value){
          prioritiesArrAux.push(priorityObj);
        }else{
          prioritiesArrAux.push(item);
        }
      });

      this.orderPrioritiesArr = prioritiesArrAux;
      
      let prioritiesStr = JSON.stringify(this.orderPrioritiesArr);
      let formData = new FormData();

      formData.append('id_user', idUser!);
      formData.append('linea', '1');
      formData.append('priorities', prioritiesStr);

      await lastValueFrom(this._sysAdminService.updateOrderPriorities(formData));

      this._resourcesService.openSnackBar('La configuración de las prioridades se guardó correctamente.');
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  applyFilter(event: any, type: string){
    let filterValue:string;
    if (type == 'INP') {
      filterValue = (event.target as HTMLInputElement).value;
    }else{
      this.txtBuscador = event;
      filterValue = event;
    }
    this.dataSource!.filter = filterValue.trim().toLowerCase();

    if(this.dataSource?.paginator){
      this.dataSource.paginator.firstPage();
    }
  }

  public async openForm(type: 'R'|'M', idForm?: string) {
    if (type === 'R') {
      const STR_FORM = JSON.stringify({ TYPE_FORM: 'R' });
      const ENC_FORM = await this._encService.encrypt(STR_FORM);
      this._router.navigate([`/sam/ADSI/PASI/registrar-formulario/${ENC_FORM}`]);
    } else if (type === 'M' && idForm !== undefined) {
      const STR_FORM = JSON.stringify({ ID_FORM: idForm, TYPE_FORM: 'M' });
      const ENC_FORM = await this._encService.encrypt(STR_FORM);
      this._router.navigate([`/sam/ADSI/PASI/editar-formulario/${ENC_FORM}`]);
    } else {
      this._resourcesService.openSnackBar(`Opción no disponible.`);
    }
  }

  chipColor(chipState: string): string{
    return this._resourcesService.setChipList(chipState);
  }
  
  public async searchZipCode() {
    
    let postalCode:string = this.formGroupTax.controls['CODIGO_POSTAL'].value.toString();

    if (postalCode.length === 5 && this.enableSearchByZipCode) {
      
      this.formGroupTax.controls['COLONIA'].setValue('');
      this.formGroupTax.controls['MUNICIPIO'].setValue('');
      this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].setValue('');
      this.formGroupTax.controls['PAIS'].setValue('');
      
      this.formGroupTax.controls['CODIGO_POSTAL'].disable();
      this.formGroupTax.controls['COLONIA'].disable();
      this.formGroupTax.controls['MUNICIPIO'].disable();
      this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].disable();
      this.formGroupTax.controls['PAIS'].disable();

      this.isLoadingForm = true;
      this.searchingAddress = true;
      await this.searchAddressByZipCode(postalCode);
      this.searchingAddress = false;
      this.isLoadingForm = false;


      this.formGroupTax.controls['CODIGO_POSTAL'].enable();
      this.formGroupTax.controls['COLONIA'].enable();
      this.formGroupTax.controls['MUNICIPIO'].enable();
      this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].enable();
      this.formGroupTax.controls['PAIS'].enable();
    }
  }
  
  private async searchAddressByZipCode(postalCode:string) {
    const encPostalCode: string = await this._encService.encrypt(postalCode);
    const idUser: string = this._resourcesService.getUser();
    const lineNumber:number = this._resourcesService.getLineNumber();
    await lastValueFrom(this._sysAdminService.getAddressByZipCode(
      encPostalCode, idUser, lineNumber
    )).then(
      (responseData: AddressByZipCodeResponse) => {
        if (!responseData.error) {

          this.formGroupTax.controls['PAIS'].setValue('México (MEX)', { emitValue: false, });
          this.citySettings = [];
          this.citySettingsStr = [];

          if (responseData.response.CODIGO_LOCALIDAD !== null) {
            this.formGroupTax.controls['LOCALIDAD'].setValue(`${responseData.response.NOMBRE_LOCALIDAD} (${responseData.response.CODIGO_LOCALIDAD})`);
          } else {
            this.formGroupTax.controls['LOCALIDAD'].setValue(`Sin localidad`);
          }

          if (responseData.response.CODIGO_MUNICIPIO !== null) {
            this.formGroupTax.controls['MUNICIPIO'].setValue(`${responseData.response.NOMBRE_MUNICIPIO} (${responseData.response.CODIGO_MUNICIPIO})`);
          } else {
            this.formGroupTax.controls['MUNICIPIO'].setValue(`Sin municipio`);
          }
          
          if (responseData.response.CODIGO_ESTADO !== null) {
            this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].setValue(`${responseData.response.NOMBRE_ESTADO} (${responseData.response.CODIGO_ESTADO})`);
          } else {
            this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].setValue(`Sin entidad federativa`);
          }

          if(responseData.response.COLONIAS.length > 0){
            responseData.response.COLONIAS.forEach(item => {
              let setting: CitySettings = {
                CODIGOCOLONIA: item.CODIGO_COLONIA,
                CODIGOPOSTAL: postalCode,
                NOMBRECOLONIA: item.NOMBRE_COLONIA,
              };
              this.citySettings.push(setting);
              this.citySettingsStr.push(`${item.NOMBRE_COLONIA} (${item.CODIGO_COLONIA})`);
            });


          }else{
            this.formGroupTax.controls['COLONIA'].setValue('Sin colonia');
            this.formGroupTax.controls['LOCALIDAD'].setValue(`Sin localidad`);
            this.formGroupTax.controls['MUNICIPIO'].setValue(`Sin municipio`);
            this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].setValue(`Sin entidad federativa`);
          }

        } else {
          this._resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchAddressByZipCode(postalCode);
        }
      }
    );
  }

  // Filtra las Colonias
  public checkColony() {

    if(!this.enableSearchByZipCode) {
      let colony:string = this.formGroupTax.controls['COLONIA'].value;
    
      let validValue = this.citySettingsStr.filter(item => item == colony);
      if(validValue.length > 0){
        let valueArr = colony.split('(').reverse();
        let settingCode = valueArr[0].replace(')', '');
  
        this.verifySetting(settingCode);
      }
    }
  }
  
  private verifySetting(value: string){
    let settingValid = this.citySettings.filter(item => item.CODIGOCOLONIA == value);    
    if(settingValid.length > 0){
      this.formGroupTax.controls['CODIGO_POSTAL'].setValue(settingValid[0].CODIGOPOSTAL);
    }
  }

  // Filtra los Municipios
  public checkCity() {
    if(!this.enableSearchByZipCode) {
      let municipality: string = this.formGroupTax.controls['MUNICIPIO'].value;    

      let countryVal = this.formGroupTax.controls['PAIS'].value;
      let countryArr = countryVal.split('(').reverse();
      let countryCode = countryArr[0].replace(')', '');

      if(countryCode == 'MEX'){
        let validValue = this.stateCitiesStr.filter(item => item == municipality);
        if(validValue.length > 0){
          let valueArr = municipality.split('(').reverse();
          let cityCode = valueArr[0].replace(')', '');        
          this.verifyCity(cityCode);
        }else{
          this.formGroupTax.controls['LOCALIDAD'].setValue('');
          this.formGroupTax.controls['LOCALIDAD'].disable();
          this.formGroupTax.controls['COLONIA'].setValue('');
          this.formGroupTax.controls['COLONIA'].disable();
        }
      }else{
        this.formGroupTax.controls['LOCALIDAD'].enable();
      }
    }
  }
  
  private verifyCity(value: string){
    let stateVal = this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].value;
    let stateArr = stateVal.split('(').reverse();
    let stateCode = stateArr[0].replace(')', '');
    
    this.cityTowns = [];
    this.cityTownsStr = [];
    this.citySettings = [];
    this.citySettingsStr = [];
    
    this.searchStateTowns(stateCode, value);
  }
  
  private async searchStateTowns(stateCode: string, cityCode: string){
    
    this.searchingTowns = true;
    
    const idUser: string = this._resourcesService.getUser();
    const stateCodeEnc: string = await this._encService.encrypt(stateCode);
    const cityCodeEnc: string = await this._encService.encrypt(cityCode);
    const line: number = this._resourcesService.getLineNumber();

    await lastValueFrom(this._sysAdminService.getTowns(stateCodeEnc,cityCodeEnc,idUser,line)).then(
      (responseData: CityTownsResponse) => {
        if (!responseData.error) {
          
          this.cityTownsStr = [];
          this.cityTowns = responseData.response;

          this.cityTowns.forEach(town => {
            if(town.CODIGOLOCALIDAD == null){
              this.cityTownsStr.push('Sin localidad');
            }else{
              this.cityTownsStr.push(`${town.NOMBRELOCALIDAD} (${town.CODIGOLOCALIDAD})`);
            }
          });

          if(responseData.response.length > 1){
            this.formGroupTax.controls['LOCALIDAD'].enable();
          }else if(responseData.response.length == 1 && responseData.response[0].CODIGOLOCALIDAD != null){
            this.formGroupTax.controls['LOCALIDAD'].enable();
          }else{
            this.formGroupTax.controls['LOCALIDAD'].disable();
            this.formGroupTax.controls['LOCALIDAD'].setValue('Sin localidad');
          }
        } else {
          this._resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchStateTowns(stateCode, cityCode);
        }
      }
    );
    
    this.searchingTowns = false;
  }

  // Filtra las Entidades Federativas
  public checkEntity() {

    let entity: string = this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].value;
    if (entity === null || entity === undefined) {
      entity = '';
    }

    let countryVal = this.formGroupTax.controls['PAIS'].value;
    let countryArr = countryVal.split('(').reverse();
    let countryCode = countryArr[0].replace(')', '');

    if(countryCode == 'MEX' || countryCode == 'USA' || countryCode == 'CAN'){
      let validValue = this.countryStatesStr.filter(item => item == entity);
      if(validValue.length > 0){
        let valueArr = entity.split('(').reverse();
        let stateCode = valueArr[0].replace(')', '');

        this.verifyState(stateCode);
      }else{
        this.formGroupTax.controls['MUNICIPIO'].setValue('');
        this.formGroupTax.controls['MUNICIPIO'].disable();
        this.formGroupTax.controls['LOCALIDAD'].setValue('');
        this.formGroupTax.controls['LOCALIDAD'].disable();
        this.formGroupTax.controls['COLONIA'].setValue('');
        this.formGroupTax.controls['COLONIA'].disable();
      }
    }else{
      this.formGroupTax.controls['MUNICIPIO'].enable();
    }
  }
  
  private verifyState(value: string){
    let countryVal = this.formGroupTax.controls['PAIS'].value;
    let countryArr = countryVal.split('(').reverse();
    let countryCode = countryArr[0].replace(')', '');
    this.stateCities = [];
    this.stateCitiesStr = [];
    this.cityTowns = [];
    this.cityTownsStr = [];
    this.citySettings = [];
    this.citySettingsStr = [];

    if(countryCode == 'MEX'){
      this.citiesInput = false;
      this.searchStateCities(value);
    }else{
      this.citiesInput = true;
      this.formGroupTax.controls['MUNICIPIO'].enable();
    }
  }
  
  private async searchStateCities(stateCode: string){
    this.searchingCities = true;
    
    const idUser:string = this._resourcesService.getUser();
    const stateCodeEnc: string = await this._encService.encrypt(stateCode);
    const line: number = this._resourcesService.getLineNumber();

    await lastValueFrom(this._sysAdminService.getCitiesByStateCode(stateCodeEnc, idUser, line)).then(
      (responseData: StateCitiesResponse) => {
        if (!responseData.error) {
          this.stateCities = responseData.response;
          this.stateCitiesStr = [];
          this.stateCities.forEach(item => {
            this.stateCitiesStr.push(`${item.NOMBREMUNICIPIO} (${item.CODIGOMUNICIPIO})`);
          });
          this.formGroupTax.controls['MUNICIPIO'].enable();
        } else {
          this._resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchStateCities(stateCode);
        }
      }
    );
    
    this.searchingCities = false;
  }

  // Filtra los Paises
  public checkIfAddress() {
    let country:string = this.formGroupTax.controls['PAIS'].value;

    let validValue = this.countriesStr.filter(item => item == country);
    this.formGroupTax.controls['CODIGO_POSTAL'].setValue('', {
      emitEvent: false,
    });

    if(validValue.length > 0){
      let valueArr = country.split('(').reverse();
      let countryCode = valueArr[0].replace(')', '');

      this.formGroupTax.controls['CODIGO_POSTAL'].disable();
      this.enableSearchByZipCode = false;
      this.verifyCountry(countryCode);
    }else{
      this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].setValue('');
      this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].disable();
      this.formGroupTax.controls['MUNICIPIO'].setValue('');
      this.formGroupTax.controls['MUNICIPIO'].disable();
      this.formGroupTax.controls['LOCALIDAD'].setValue('');
      this.formGroupTax.controls['LOCALIDAD'].disable();
      this.formGroupTax.controls['COLONIA'].setValue('');
      this.formGroupTax.controls['COLONIA'].disable();

      this.formGroupTax.controls['CODIGO_POSTAL'].enable();
      this.enableSearchByZipCode = true;
    }
  }

  private verifyCountry(countryCode: string){
    this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].disable();
    this.countryStates = [];
    this.countryStatesStr = [];
    this.stateCities = [];
    this.stateCitiesStr = [];
    this.cityTowns = [];
    this.cityTownsStr = [];
    this.citySettings = [];
    this.citySettingsStr = [];

    if(countryCode != 'MEX'){
      this.formGroupTax.controls['CODIGO_POSTAL'].enable();
    }

    if(countryCode == 'CAN' || countryCode == 'MEX' || countryCode == 'USA'){
      this.searchCountryStates(countryCode);
    }else{
      this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].enable();
    }
  }
  
  private async searchCountryStates(contryCode: string){
    try{
      this.searchingStates = true;

      const idUser: string = this._resourcesService.getUser();
      const line: number = this._resourcesService.getLineNumber();
      const encCountryCode:string = await this._encService.encrypt(contryCode);

      await lastValueFrom(this._sysAdminService.getStatesByCountryCode( encCountryCode, idUser, line)).then(
        (responseData: CountryStatesResponse) => {
          if(!responseData.error){

            this.countryStatesStr = [];
            this.countryStates = responseData.response;    
            this.countryStates.forEach(item => {
              this.countryStatesStr.push(`${item.NOMBREESTADO} (${item.CODIGOESTADO})`);
            });
            this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].enable();

          } else {
            this._resourcesService.openSnackBar(responseData.msg);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this._resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.searchCountryStates(contryCode);
          }
        }
      );
      this.searchingStates = false;

    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.searchingStates = false;
    }
  }

  public async alert(typeAlert: string, data: any = null) {
    this.isLoadingForm = true;

    if (typeAlert === 'CONFIRM') {
      this._dialog.open(AlertComponent, {
        disableClose: true,
        data: {
          icon: "warning",
          title: "Confirmación",
          description: "¿Está seguro de modificar la información fiscal?"
        },
      }).afterClosed().subscribe((result) => {
        if (result && typeAlert === 'CONFIRM') {
          this.saveTaxInformation();
        }
      });
      this.isLoadingForm = false;
    }
  }

  public async saveTaxInformation() {
    this.isLoadingForm = true;
    let lada1:string = this.formGroupTax.controls['LADA1'].value.toString().trim();
    let arrLada1:Array<string> = lada1.split(' ');
    if (arrLada1.length > 1) {
      lada1 = arrLada1.pop()!;
    } 
    let lada2:string = this.formGroupTax.controls['LADA2'].value.toString().trim();
    let arrLada2:Array<string> = lada2.split(' ');
    if (arrLada2.length > 1) {
      lada2 = arrLada2.pop()!;
    } 

    let regimenFiscal:string = this.formGroupTax.controls['REGIMEN_FISCAL'].value.toString().trim();
    if (regimenFiscal.includes('(') && regimenFiscal.includes(')')) {
      regimenFiscal = regimenFiscal.split('(')[1].split(')')[0];
    } else {
      this._resourcesService.openSnackBar('Debe seleccionar una opción en el campo Régimen Fiscal');
      return;
    }

    const REQUEST_FORM: FormTaxInformation = {
      NOMBRE_FISCAL: this.formGroupTax.controls['NOMBRE_FISCAL'].value.toString().trim(),
      RFC: this.formGroupTax.controls['RFC'].value.toString().trim(),
      CORREO_ELECTRONICO: this.formGroupTax.controls['CORREO_ELECTRONICO'].value.toString().trim(),
      REGIMEN_FISCAL: regimenFiscal,
      LADA1: lada1,
      TELEFONO_FIJO: this.formGroupTax.controls['TELEFONO_FIJO'].value,
      LADA2: lada2,
      TELEFONO_MOVIL: this.formGroupTax.controls['TELEFONO_MOVIL'].value,
      CODIGO_POSTAL: this.formGroupTax.controls['CODIGO_POSTAL'].value.toString().trim(),
      TIPOVIALIDAD: this.formGroupTax.controls['TIPOVIALIDAD'].value.toString().trim(),
      NOMBRE_VIALIDAD: this.formGroupTax.controls['NOMBRE_VIALIDAD'].value.toString().trim(),
      ENTRE_CALLE: this.formGroupTax.controls['ENTRE_CALLE'].value.toString().trim(),
      Y_CALLE: this.formGroupTax.controls['Y_CALLE'].value.toString().trim(),
      NUMERO_EXTERIOR: this.formGroupTax.controls['NUMERO_EXTERIOR'].value.toString().trim(),
      NUMERO_INTERIOR: this.formGroupTax.controls['NUMERO_INTERIOR'].value === null ? this.formGroupTax.controls['NUMERO_INTERIOR'].value : this.formGroupTax.controls['NUMERO_INTERIOR'].value.toString().trim(),
      COLONIA: this.formGroupTax.controls['COLONIA'].value,
      LOCALIDAD: this.formGroupTax.controls['LOCALIDAD'].value.toString().trim(),
      MUNICIPIO: this.formGroupTax.controls['MUNICIPIO'].value.toString().trim(),
      ENTIDAD_FEDERATIVA: this.formGroupTax.controls['ENTIDAD_FEDERATIVA'].value.toString().trim(),
      PAIS: this.formGroupTax.controls['PAIS'].value.toString().trim(),
      USER: this._resourcesService.getUser(),
      LINE_NUMBER: this._resourcesService.getLineNumber(),
    }

    await lastValueFrom(this._sysAdminService.saveTaxInformation(REQUEST_FORM)).then(
      (responseData: ResponseData) => {
        if (!responseData.error) {
          this._resourcesService.openSnackBar(`¡La información fiscal ha sido actualizada!`);
        } else {
          this._resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.saveTaxInformation();
        }
      }
    );
    this.isLoadingForm = false;
  }

  filterMagnitudesUnits(value: string, mode: string, type: string){
    let filterValue = value.toLowerCase();

    if(mode == 'clear'){
      if(type == 'magnitudes'){
        let magnitudesFilter = this._document.getElementById('magnitudesFilt') as HTMLInputElement;
        magnitudesFilter.value = '';
        this.magnitudes = this.magnitudesAux;
      }

      if(type == 'units'){
        let unitsFilter = this._document.getElementById('unitsFilt') as HTMLInputElement;
        unitsFilter.value = '';
        this.unitsByMagnitude = this.unitsByMagnitudeAux;
      }
    }else{
      if(type == 'magnitudes' && value != ''){
        let magnitudesFilt = this.magnitudesAux.filter(item => item.MAGNITUD.toLowerCase().includes(filterValue));
        this.magnitudes = magnitudesFilt;
      }else if(type == 'magnitudes' && value == ''){
        this.magnitudes = this.magnitudesAux;
      }

      if(type == 'units' && value != ''){
        let unitsFilt = this.unitsByMagnitudeAux.filter(item => item.NOMBRE_UNIDAD.toLowerCase().includes(filterValue) || item.ACRONIMO_UNIDAD.toLowerCase().includes(filterValue));
        this.unitsByMagnitude = unitsFilt;
      }else if(type == 'units' && value == ''){
        this.unitsByMagnitude = this.unitsByMagnitudeAux;
      }
    }
  }

  openMagnitudeForm(type: string, idMagnitude: string = '-'){
    let dialogRef = this._matDialog.open(MagnitudeFormComponent, {
      width: '520px',
      disableClose: true,
      data: {
        idMagnitude: idMagnitude,
        type: type
      }
    });
    
    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        this.saveMagnitude(type, res, idMagnitude);
      }
    });
  }

  private async saveMagnitude(type: string, magnitude: string, idMagnitude: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('magnitude', magnitude);

      if(type == 'nuevo'){
        await lastValueFrom(this._sysAdminService.registerMagnitude(formData));
        this._resourcesService.openSnackBar('La magnitud se regsitró correctamente.');
      }else{
        formData.append('id_magnitude', idMagnitude);

        await lastValueFrom(this._sysAdminService.updateMagnitude(formData));
        this._resourcesService.openSnackBar('La magnitud se actualizó correctamente.');
      }
      this.getMagnitudes();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async getUnitsByMagnitude(event: any){
    try{
      this.searchingUnits = true;

      let idUser = localStorage.getItem('idusuario')!;
      let magnitude = event.value;
      let units: UnitsByMagnitudeListResponse = await lastValueFrom(this._sysAdminService.getUnitsByMagnitude(magnitude, idUser, 1));

      if(units.error){
        this._resourcesService.openSnackBar(units.msg);
      }else{
        let unitsArr: UnitsByMagnitudeListItem[] = [];
        for(const unit of units.response){
          let idDec = await this._encService.decrypt(unit.ID_UNIDAD);
          unit.NOMBRE_UNIDAD = `${unit.NOMBRE_UNIDAD} (${idDec})`;

          if(unit.ESTADO == 'Activo'){
            unitsArr.push(unit);
          }
        }

        this.unitsByMagnitude = unitsArr;
        this.unitsByMagnitudeAux = this.unitsByMagnitude;
        this.magnitudeSelected = magnitude;
      }

      this.searchingUnits = false;
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.searchingUnits = false;
    }
  }

  openDeleteAlertDialog(mode: string, idRegister: string){
    let dialogRef = this._matDialog.open(AlertComponent, {
      width: '420px',
      data: {
        title: '¡Advertencia!',
        icon: 'warning',
        description: `¿Está seguro de eliminar la ${mode == 'magnitude' ? 'magnitud' : 'unidad'}?`,
        description2: 'Esta acción no se puede eliminar'
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res == true){
        if(mode == 'magnitude'){
          this.deleteMagnitude(idRegister);
        }else{
          this.deleteUnit(idRegister);
        }
      }
    });
  }

  private async deleteMagnitude(idMagnitude: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_magnitude', idMagnitude);

      await lastValueFrom(this._sysAdminService.deleteMagnitude(formData));
      
      this._resourcesService.openSnackBar('La magnitud se eliminó correctamente.');
      this.getMagnitudes();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  private async deleteUnit(idUnit: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let data: RequestDeleteMeasures = {
        ID_MEDIDA: idUnit,
        NUMERO_LINEA: 1,
        USUARIO: idUser,
        ID_MAGNITUD: this.magnitudeSelected,
      };

      await lastValueFrom(this._catalogMeasuresService.deleteCatalogMeasures(data));
      
      this._resourcesService.openSnackBar('La unidad de medida se eliminó correctamente.');
      this.getUnitsByMagnitude({value: this.magnitudeSelected});
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async openUnitForm(type: string, idUnit: string = '-'){
    let idMagnitudeDec = await this._encService.decrypt(this.magnitudeSelected);
    let magnitudeFilt: MagnitudesListItem | null = null;

    for(const magnitude of this.magnitudes){
      let idDec = await this._encService.decrypt(magnitude.ID_MAGNITUD);
      if(idMagnitudeDec == idDec){
        magnitudeFilt = magnitude;
      }
    }

    if(magnitudeFilt == null) return;

    let dialogRef = this._matDialog.open(UnitFormComponent, {
      width: '520px',
      disableClose: true,
      data: {
        idUnit: idUnit,
        magnitude: magnitudeFilt.MAGNITUD,
        type: type
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        let resArr = res.split('|');
        if(resArr.length < 2){
          this._resourcesService.openSnackBar('La información ingresada es inválida.');
        }else{
          this.saveUnit(type, resArr[0], resArr[1], idUnit);
        }
      }
    });
  }

  private async saveUnit(type: string, unit: string, acronymus: string, idUnit: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let data: RequestFormMeasures = {
        NOMBRE_MEDIDA: unit,
        ACRONIMO_MEDIDA: acronymus,
        NUMERO_LINEA: 1,
        USUARIO: idUser,
        ID_MAGNITUD: this.magnitudeSelected
      }

      if(type == 'nuevo'){
        await lastValueFrom(this._catalogMeasuresService.registerCatalogMeasures(data));
        this._resourcesService.openSnackBar('La unidad se regsitró correctamente.');
      }else{
        data.ID_MEDIDA = idUnit;

        await lastValueFrom(this._catalogMeasuresService.updateCatalogMeasures(data));
        this._resourcesService.openSnackBar('La unidad se actualizó correctamente.');
      }

      this.getUnitsByMagnitude({value: this.magnitudeSelected});
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async searchPlanes(stationInd: string){
    try{
      this.searchingStationPlans = true;
      
      let idUser = localStorage.getItem('idusuario')!;
      let stationIndEnc = await this._encService.encrypt(stationInd);
      let stationPlanes: StationPlanesListResponse = await lastValueFrom(this._sysAdminService.getStationPlanes(
        stationIndEnc,
        idUser,
        1
      ));

      if(stationPlanes.error){
        this._resourcesService.openSnackBar(stationPlanes.msg);
        this.stationInd = null;
      }else{
        this.stationInd = stationInd;

        let stationPlanesArr: StationPlanesListItem[] = [];
        for(const plane of stationPlanes.response){
          plane.ID_PLANO = await this._encService.decrypt(plane.ID_PLANO);
          let idStationDec = await this._encService.decrypt(plane.ID_ESTACION);
          let stationFilt = this.viaPositions.filter(item => item.stationInd == idStationDec);

          if(stationFilt.length > 0){
            plane.ID_ESTACION = stationFilt[0].name;
          }

          plane.ARCHIVO_RELACIONADO = await this._encService.decrypt(plane.ARCHIVO_RELACIONADO);
          plane.FECHA_REGISTRO = this._functionsService.orderDate(plane.FECHA_REGISTRO);
          plane.USUARIO_REG = await this._encService.decrypt(plane.USUARIO_REG);

          if(plane.FECHA_MODIFICACION != null){
            plane.FECHA_MODIFICACION = this._functionsService.orderDate(plane.FECHA_MODIFICACION);
          }

          if(plane.USUARIO_MOD != null){
            plane.USUARIO_MOD = this._functionsService.orderDate(plane.USUARIO_MOD);
          }

          stationPlanesArr.push(plane);
        }

        this.stationPlanesDataSource = new MatTableDataSource(stationPlanesArr);
      }
      
      this.searchingStationPlans = false;
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.searchingStationPlans = false;
    }
  }

  openPlaneUploader(stationInd: string){
    let dialogRef = this._dialog.open(PlaneUploaderComponent, {
      disableClose: true,
      minWidth: '480px',
      width: '480px',
    });
    
    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        this.uploadPlane(res, stationInd);
      }
    })
  }

  private async uploadPlane(dataEnc: string, stationInd: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let dataDec = await this._encService.decrypt(dataEnc);
      let dataObj = JSON.parse(dataDec);
      let stationIndEnc = await this._encService.encrypt(stationInd);
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('id_file', dataObj.file.id);
      formData.append('id_station', stationIndEnc);
      formData.append('level', dataObj.level);

      await lastValueFrom(this._sysAdminService.saveStationPlane(formData));
      this._resourcesService.openSnackBar('El plano fue registrado correctamente.');
      this.searchPlanes(stationInd);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async openPlaneViewer(idFile: string){
    let idFileEnc = await this._encService.encrypt(idFile);
    this._dialog.open(PlaneViewerComponent, {
      minWidth: '840px',
      width: '840px',
      data: {
        idFile: idFileEnc,
      }
    });
  }
}

export interface PriorityInterface{
  value: string,
  label: string,
  color: string,
}

export interface StationPlanesListResponse{
  error: boolean;
  msg: string;
  response: StationPlanesListItem[];
}

export interface StationPlanesListItem{
  ID_PLANO: string;
  ID_ESTACION: string;
  ARCHIVO_RELACIONADO: string;
  NIVEL: string;
  ESTADO: string;
  FECHA_REGISTRO: string;
  USUARIO_REG: string;
  FECHA_MODIFICACION: string | null;
  USUARIO_MOD: string | null;
  FAMILIAS: StationPlanesFamilies[];
}

export interface StationPlanesFamilies{
  FAMILIA: string,
  COLOR_COORDENADAS: string,
}