import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { CatalogData, CatalogForm, ConditionData, ConditionForm, ContactForm, InformationData, ProviderSave, ReferenceData, RegisterForm, RegisterProvider, RevisionData, SaveData, TypeForm } from '../../../../../interfaces/acquisition-management/provider.interface';
import { MatTableDataSource } from '@angular/material/table';
import { GetPaymentMethod } from '../../../../../interfaces/payment-method.interface';
import { SelectionModel } from '@angular/cdk/collections';
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 { ResourcesService } from '../../../../../services/resources.service';
import { MatDialog } from '@angular/material/dialog';
import { EncService } from '../../../../../services/enc.service';
import { ProviderService } from '../../../../../services/acquisition-management/provider.service';
import { ActivatedRoute, Router } from '@angular/router';
import { SystemAdminService } from '../../../../../services/system-admin.service';
import { SocketService } from '../../../../../services/socket.service';
import { SubcontratistService } from '../../../../../services/personal-management/subcontratist.service';
import { BudgetManagementService } from '../../../../../services/budget-management/budget-management.service';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { RequestFormValidateCatalog, ResponseDataGetValidateCatalog } from '../../../../../interfaces/validate-catalog.interface';
import { ResponseDataGetPaymentMethodActive } from '../../../../../interfaces/budget-management/budget-management.interface';
import { AlertData } from '../../../../../interfaces/alert.interface';
import { AlertComponent } from '../../../../resources/dialogs/alert/alert.component';
import { ResponseData } from '../../../../../interfaces/response-data';
import { ResponseDataSubcontratist } from '../../../../../interfaces/personal-managment/subcontractist.interface';
import { AddressByZipCodeResponse } from '../../../../../interfaces/address-by-zip-code.interface';
import { ReferencesFormComponent } from '../references-provider/references-form/references-form.component';
import { ContactProviderFormComponent } from '../contact-provider/contact-provider-form/contact-provider-form.component';
import { ConditionProviderFormComponent } from '../condition-provider/condition-provider-form/condition-provider-form.component';
import { CatalogsProviderFormComponent } from '../catalogs-provider/catalogs-provider-form/catalogs-provider-form.component';

@Component({
    selector: 'app-provider-form',
    templateUrl: './provider-form.component.html',
    styleUrl: './provider-form.component.css',
    standalone: false
})
export class ProviderFormComponent implements OnInit {
  public isLoading: boolean;
  public isLoadingForm: boolean;
  public isLinear:boolean;
  public isFormLocalSave: boolean;

  public formGroupInformation: FormGroup;

  public typeForm:TypeForm;

  public displayedColumnsReferences: Array<string>;
  public dataSourceReference: MatTableDataSource<ReferenceData>;
  public displayedColumnsContact: Array<string>;
  public dataSourceContact: MatTableDataSource<ContactForm>;
  public displayedColumnsCondition: Array<string>;
  public dataSourceCondition: MatTableDataSource<ConditionData>;
  public displayedColumnsCatalog: Array<string>;
  public dataSourceCatalog: MatTableDataSource<CatalogData>;
  public displayedColumnsRevision: Array<string>;
  public dataSourceRevision: MatTableDataSource<RevisionData>;
  public displayedColumnsPaymentMethod: Array<string>;
  public dataSourcePaymentMethod: MatTableDataSource<GetPaymentMethod>;
  public arrPaymentMethod: Array<GetPaymentMethod>;

  public selection: SelectionModel<GetPaymentMethod> ;

  public arrTaxRegime: Array<TaxRegimeList>;
  public taxRegimeStr: string[];
  public taxLength: number;
  public enableSearchByZipCode: boolean;
  public searchingStates: boolean;
  public searchingSettings: boolean;
  public searchingTowns: boolean;
  public searchingCities: boolean;
  public searchingAddress: boolean;
  public citiesInput: boolean;

  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[];

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

  public idFunction: string;
  public getReferencesEnabled:boolean;
  public websiteLinkEnabled:boolean;
  public contactEnabled:boolean;
  public conditionPaymentEnabled:boolean;
  public conditionPurchaseEnabled:boolean;
  public webCatalogEnabled:boolean;

  flags: Map<string, string>;

  constructor(
    public resourcesService: ResourcesService,
    private _dialog: MatDialog,
    private _encService: EncService,
    private _providerService: ProviderService,
    private _activatedRouter: ActivatedRoute,
    private _router: Router,
    private _socketService: SocketService,
    private _subcontratistService: SubcontratistService,
    private _budgetManagementService: BudgetManagementService,
    private _httpClient: HttpClient,
    private _systemAdminService: SystemAdminService,
  ) {

    this.formGroupInformation = this.createFormGroupInformation();

    this.isLoading = true;
    this.isLoadingForm = true;
    this.isLinear = false;
    this.isFormLocalSave = false;

    this.dataSourceReference = new MatTableDataSource();
    this.dataSourceContact = new MatTableDataSource();
    this.dataSourceCondition = new MatTableDataSource();
    this.dataSourceCatalog = new MatTableDataSource();
    this.displayedColumnsReferences = [ 'NO', 'EMPRESA', 'CORREO', 'TELEFONO', 'RFC', 'ESTADO', 'ACCIONES' ];
    this.displayedColumnsContact = [ 'NO', 'NOMBRE_CONTACTO', 'TIPO_CONTACTO', 'CORREO1', 'TELEFONO1', 'ESTADO', 'ACCIONES' ];
    this.displayedColumnsCondition = [ 'NO', 'TIPO_CONDITION', 'INFORMACION', 'ESTADO', 'ACCIONES' ];
    this.displayedColumnsCatalog = [ 'NO', 'CATALAGO', 'DESCRIPCION', 'ESTADO', 'ACCIONES' ];
    this.displayedColumnsPaymentMethod = [ 'SELECT', 'C_FORMAPAGO', 'DESCRIPCION'];

    this.selection = new SelectionModel<GetPaymentMethod>(true)

    this.dataSourceRevision = new MatTableDataSource();
    this.displayedColumnsRevision = [ 'NO', 'FORMULARIO', 'MENSAJE' ];

    this.typeForm = {} as TypeForm;

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

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

    this.taxLength = 12;

    // Se obtienen los métodos de pago
    this.dataSourcePaymentMethod = new MatTableDataSource();
    this.arrPaymentMethod = [];

    this.idFunction = '';
    this.getReferencesEnabled = false;
    this.websiteLinkEnabled = false;
    this.contactEnabled = false;
    this.conditionPaymentEnabled = false;
    this.conditionPurchaseEnabled = false;
    this.webCatalogEnabled = false;

    this.flags = new Map();

  }
  
  private createFormGroupInformation(): FormGroup {
    return new FormGroup({
      NUMERO_PROVEEDOR: new FormControl(''),
      RAZON_SOCIAL: new FormControl('', Validators.required),
      CORREO: new FormControl('', [Validators.required, Validators.email]),
      NOMBRE: new FormControl('', Validators.required),
      PRIMER_APELLIDO: new FormControl('', Validators.required),
      SEGUNDO_APELLIDO: new FormControl(''),
      LADA1: new FormControl(null, Validators.required),
      TELEFONO1: new FormControl('', Validators.required),
      LADA2: new FormControl(null),
      TELEFONO2: new FormControl(''),
      REGIMEN_FISCAL: new FormControl('', Validators.required),
      TIPO: new FormControl('', Validators.required),
      TIPO_CONTRIBUYENTE: new FormControl('', Validators.required),
      RFC: new FormControl('', [Validators.required]),
      TAXID: new FormControl( '', [Validators.required]),
      SITIOWEB: new FormControl(''),
      ESTADO: new FormControl('Nuevo', Validators.required),
      CALLE: new FormControl('', Validators.required),
      EXTERIOR: new FormControl('', Validators.required),
      INTERIOR: new FormControl(''),
      CODIGO_POSTAL: new FormControl('', Validators.required),
      LOCALIDAD: new FormControl('', Validators.required),
      COLONIA: new FormControl('', Validators.required),
      MUNICIPIO: new FormControl('', Validators.required),
      ENTIDAD: new FormControl('', Validators.required),
      PAIS: new FormControl('', Validators.required),
    })
  }

  async ngOnInit() {
    // Se obtienen los borradores guardados
    await this._validateCatalog();
    await this.checkPermissions();
    await this.getPaymentMethodActive();
    await this.getLocalProvider();
    await this.getCoutries();
    await this.getTaxRegimeActive();
    await this.getDataForm();

    this.formGroupInformation.controls['LOCALIDAD'].valueChanges.subscribe(value => {
      if(!this.enableSearchByZipCode) {
        let countryVal = this.formGroupInformation.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.formGroupInformation.controls['COLONIA'].setValue('');
            this.formGroupInformation.controls['COLONIA'].disable();
          }
        }else{
          this.formGroupInformation.controls['COLONIA'].enable();
        }
      }
    })

    this.filteredLadas1 = this.formGroupInformation.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.formGroupInformation.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.formGroupInformation.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.formGroupInformation.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.formGroupInformation.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.formGroupInformation.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.formGroupInformation.controls['ENTIDAD'].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.formGroupInformation.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;
      })
    );
    
    this.isLoading = false;
    this.isLoadingForm = false;
  }
  
  private async _validateCatalog() {
    const FORM_REQUEST: RequestFormValidateCatalog = {
      CODIGO_POSTAL: true,
      COLONIAS: true,
      LOCALIDADES: true,
      MUNICIPIOS: true,
      ESTADOS: true,
      PAISES: true,
      REGIMEN_FISCAL: true,
      USUARIO: this.resourcesService.getUser(),
      NUMERO_LINEA: this.resourcesService.getLineNumber(),
    }
    await lastValueFrom(this._systemAdminService.validateCatalog(FORM_REQUEST)).then(
      (responseData: ResponseDataGetValidateCatalog) => {
        if (!responseData.error) {
          
          if (responseData.response.CODIGO_POSTAL) {
            this.resourcesService.openSnackBar(`No existen datos en el catálogo de códigos postales, contacte al administrador del sistema.`);
            this.resourcesService.goBack();
            return;
          }
          if (responseData.response.COLONIAS) {
            this.resourcesService.openSnackBar(`No existen datos en el catálogo de colonias, contacte al administrador del sistema.`);
            this.resourcesService.goBack();
            return;
          }
          if (responseData.response.LOCALIDADES) {
            this.resourcesService.openSnackBar(`No existen datos en el catálogo de localidades, contacte al administrador del sistema.`);
            this.resourcesService.goBack();
            return;
          }
          if (responseData.response.MUNICIPIOS) {
            this.resourcesService.openSnackBar(`No existen datos en el catálogo de municipios, contacte al administrador del sistema.`);
            this.resourcesService.goBack();
            return;
          }
          if (responseData.response.ESTADOS) {
            this.resourcesService.openSnackBar(`No existen datos en el catálogo de estados, contacte al administrador del sistema.`);
            this.resourcesService.goBack();
            return;
          }
          if (responseData.response.PAISES) {
            this.resourcesService.openSnackBar(`No existen datos en el catálogo de paises, contacte al administrador del sistema.`);
            this.resourcesService.goBack();
            return;
          }
          if (responseData.response.REGIMEN_FISCAL) {
            this.resourcesService.openSnackBar(`No existen datos en el catálogo de regimen fiscal, contacte al administrador del sistema.`);
            this.resourcesService.goBack();
            return;
          }
        } else {
          this.resourcesService.openSnackBar(`${ responseData.msg }`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this._validateCatalog();
        }
      }
    );
  }
  
  private async checkPermissions() {
    const navigate:string = this._router.routerState.snapshot.url;
    let arrNavigate: Array<string> = navigate.split(`/`);
    if (arrNavigate.length !== 6) {
      this.resourcesService.openSnackBar(`Ocurrió un error al obtener el URL.`);
      this._router.navigate(['/sam/home']);
      return;
    }
    let functionTemp = arrNavigate.pop()!;
    functionTemp = arrNavigate.pop()!;
    if (functionTemp === undefined) {
      this.resourcesService.openSnackBar(`Ocurrió un error al obtener la función del módulo.`)
      this._router.navigate(['/sam/home']);
      return ;
    }
    this.idFunction = functionTemp;    

    if (this.idFunction === 'CRPR') {
      this.dataSourceRevision = new MatTableDataSource([
        {
          NO: 1,
          FORMULARIO_REV:'Información Personal',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        },
        {
          NO: 2,
          FORMULARIO_REV:'Referencias',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        }
      ]);
      this.getReferencesEnabled = true;
    }
    if (this.idFunction === 'ESWP') {
      this.dataSourceRevision = new MatTableDataSource([
        {
          NO: 1,
          FORMULARIO_REV:'Información Personal',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        }
      ]);
      this.websiteLinkEnabled = true;
      this.formGroupInformation.controls['SITIOWEB'].setValidators([Validators.required, Validators.pattern("[Hh][Tt][Tt][Pp][Ss]?:\/\/(?:(?:[a-zA-Z\u00a1-\uffff0-9]+-?)*[a-zA-Z\u00a1-\uffff0-9]+)(?:\.(?:[a-zA-Z\u00a1-\uffff0-9]+-?)*[a-zA-Z\u00a1-\uffff0-9]+)*(?:\.(?:[a-zA-Z\u00a1-\uffff]{2,}))(?::\d{2,5})?(?:\/[^\s]*)?")])
    }
    if (this.idFunction === 'COPR') {
      this.dataSourceRevision = new MatTableDataSource([
        {
          NO: 1,
          FORMULARIO_REV:'Información Personal',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        },
        {
          NO: 2,
          FORMULARIO_REV:'Contactos',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        }
      ]);
      this.contactEnabled = true;
    }
    if (this.idFunction === 'DCMP') {
      this.dataSourceRevision = new MatTableDataSource([
        {
          NO: 1,
          FORMULARIO_REV:'Información Personal',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        },
        {
          NO: 2,
          FORMULARIO_REV:'Medios de Pago',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        }
      ]);
      this.conditionPaymentEnabled = true;
    }
    if (this.idFunction === 'DCCE') {
      this.dataSourceRevision = new MatTableDataSource([
        {
          NO: 1,
          FORMULARIO_REV:'Información Personal',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        },
        {
          NO: 2,
          FORMULARIO_REV:'Condiciones',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        }
      ]);
      this.conditionPurchaseEnabled = true;
    }
    if (this.idFunction === 'CCPR') {
      this.dataSourceRevision = new MatTableDataSource([
        {
          NO: 1,
          FORMULARIO_REV:'Información Personal',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        },
        {
          NO: 2,
          FORMULARIO_REV:'Catálagos',
          MENSAJE_REV:'',
          TYPE_REV: 'DEFAULT'
        }
      ]);
      this.webCatalogEnabled = true;      
    }
  }
  
  private async getPaymentMethodActive() {
    const USER: string = this.resourcesService.getUser(); 
    const LINE: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._budgetManagementService.getPaymentMethodActive(USER, LINE)).then(
      (responseData: ResponseDataGetPaymentMethodActive) => {
        if (!responseData.error) {
          if (responseData.response.length === 0) {
            this.resourcesService.openSnackBar(`No existen métodos de pago registrados`);
            this.resourcesService.goBack()
            return;
          }
          this.dataSourcePaymentMethod.data = responseData.response;
          this.arrPaymentMethod = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getPaymentMethodActive();
        }
      }
    );
  }
  
  private async getLocalProvider(){
    let saveProvider = localStorage.getItem('save_provider');
    let encUser: string = this.resourcesService.getUser();
    let user: string = await this._encService.decrypt(encUser);

    if (saveProvider !== null) {
      let arrSaveLocal:Array<string> = JSON.parse(saveProvider);
      arrSaveLocal.map(async (element:string)=>{
        let decSaveProvier: string = await this._encService.decrypt(element);
        let objSaveLocal: ProviderSave = JSON.parse(decSaveProvier);

        let userSaveLocal = await this._encService.decrypt(objSaveLocal.USER)
        if ( userSaveLocal === user && this.typeForm.type === 'REGI') {
          this.alert('SET_REV', objSaveLocal.OBJ_DATA);
        }
      });
    }
  }
  
  public async alert(type: string, dataElement: any = null):Promise<void> {
    // this.isLoadingForm = true;
    let dataDialog: AlertData = {} as AlertData;
    if(type === 'REG_REV'){
      dataDialog = {
        icon: "warning",
        title: "Confirmación",
        description: "¿Está seguro de registrar el proveedor?"
      };
    }else if(type === 'SAV_REV'){
      dataDialog = {
        icon: "warning",
        title: "Guardar Información",
        description: "¿Está seguro de guardar la información del proveedor?"
      };
    }else if(type === 'SET_REV' && this.typeForm.type === 'REGI'){
      dataDialog = {
        icon: "warning",
        title: "Establecer Información",
        description: "¿Deseas establecer la información guardada del proveedor?"
      };
    }else if(type === 'EXIT' && this.typeForm.type === 'REGI'){
      dataDialog = {
        icon: "warning",
        title: "Salir",
        description: "¿Deseas guardar la información del registro antes de salir?",
        btnRechazar: true,
      };
    }else if (type === 'EXIT' && this.typeForm.type === 'EDIT') {
      dataDialog = {
        icon: "warning",
        title: "Salir",
        description: "¿Está seguro de salir? No se guardarán los cambios realizados",
      };
    }else if(type === 'UPD_REV'){
      dataDialog = {
        icon: "warning",
        title: "Confirmación",
        description: "¿Está seguro de modificar al proveedor?",
      };
    }

    // Se ejecuta la alerta
    this._dialog.open(AlertComponent, {
      data: dataDialog,
      disableClose: true,
    }).afterClosed().subscribe((result) => {
      if (type === 'REG_REV' && result) {
        this.revisionForms();
      }else if (type === 'UPD_REV' && result) {
        this.revisionForms();
      }else if ((type === 'SAV_REV' || type === 'EXIT') && result === true && this.typeForm.type === 'REGI') {
        this.saveLocalProvider();
      }else if (type === 'SET_REV' && result) {
        this.setLocalProvider(dataElement);
      }else if (type === 'EXIT' && result === 'rechazar'){
        this.resourcesService.goBack();
      }else if(type === 'EXIT' && result && this.typeForm.type === 'EDIT'){
        this.resourcesService.goBack();
      }
    });
  }

  public revisionForms(){
    let hasErrorForm:boolean = false;
    this.dataSourceRevision.data.map((element:RevisionData)=>{
      switch (element.NO) {
        case 1:
          if(this.formGroupInformation.invalid){
            element.TYPE_REV = 'ERROR';
            element.MENSAJE_REV = 'Formulario incorrecto';
            hasErrorForm = true;
          }else{
            element.TYPE_REV = 'EXITO';
          }
          break;
        case 2:
          if(this.dataSourceReference.data.length < 0){
            element.TYPE_REV = 'ERROR';
            element.MENSAJE_REV = 'Debe haber al menos un registro en la tabla de Referencias';
            hasErrorForm = true;
          }else{
            element.TYPE_REV = 'EXITO';
          }
          break;
        case 3:
          if(this.dataSourceContact.data.length < 0){
            element.TYPE_REV = 'ERROR';
            element.MENSAJE_REV = 'Debe haber al menos un registro en la tabla de Contactos';
            hasErrorForm = true;
          }else{
            element.TYPE_REV = 'EXITO';
          }
          break;
        case 4:
          if(this.selection.selected.length < 0){
            element.TYPE_REV = 'ERROR';
            element.MENSAJE_REV = 'Debe haber al menos un registro en la tabla de Condiciones';
            hasErrorForm = true;
          }else{
            element.TYPE_REV = 'EXITO';
          }
          break;
        case 5:
          if ( this.selection.selected.length === 0 ) {
            element.TYPE_REV = 'ERROR';
            element.MENSAJE_REV = 'Debe haber al menos un registro seleccionado en los Medios de Pago';
            hasErrorForm = true;
          }else{
            element.TYPE_REV = 'EXITO';
          }
          break;
        case 6:
          if(this.dataSourceCatalog.data.length < 0){
            element.TYPE_REV = 'ERROR';
            element.MENSAJE_REV = 'Debe haber al menos un registro en la tabla de Catálagos';
            hasErrorForm = true;
          }else{
            element.TYPE_REV = 'EXITO';
          }
          break;
        default:
          hasErrorForm = true;
          break;
      }
    });
    if (!hasErrorForm) {
      this.createProvider();
    }
  }
  
  private async createProvider(){
    const responseObjectForm = await this.generateObjForm();
    if (responseObjectForm === false) {
      return;
    }

    const formulario: RegisterProvider = {
      user: this.resourcesService.getUser(),
      line: this.resourcesService.getLineNumber(),
      obj_response: responseObjectForm
    }

    if (this.typeForm.type === 'REGI') {
      await lastValueFrom(this._providerService.registerForm(formulario)).then(
        (responseData: ResponseData) => {
          if (!responseData.error) {
            this.resourcesService.openSnackBar('¡Registro de proveedor correcto!');
            if (this.typeForm.subcontract === null) {
              this._socketService.registerProvider(`${responseData.response.idProvider}`);
            }
            this.resourcesService.goBack();
          } else {
            this.resourcesService.openSnackBar(`${responseData.msg}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.createProvider();
          }
        }
      );
      
    }else{
      await lastValueFrom(this._providerService.updateForm(formulario)).then(
        (responseData: ResponseData) => {
          if (!responseData.error) {
            
            if ( 'subcontract' in responseData.response ) {
              this._socketService.sendNotice(`El subcontratista #${responseData.response.subcontract.PESU_IDPS} fue modificado desde el Módulo de Adquisiciones.`);
            }
            
            this.resourcesService.openSnackBar('¡Modificación de proveedor correcto!');
            this.resourcesService.goBack();
          } else {
            this.resourcesService.openSnackBar(`${responseData.msg}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.createProvider();
          }
        }
      );
    }
    
    this.isLoadingForm = false;
  }

  public async generateObjForm() {
    let lada1 = this.formGroupInformation.controls['LADA1'].value;
    lada1 = lada1.toString().trim();
    lada1 = lada1.split('-')[0];
    
    let lada2: string = this.formGroupInformation.controls['LADA2'].value;
    if (lada2 !== null && lada2 !== undefined && lada2 !== '') {
      lada2 = lada2.toString().trim();
      lada2 = lada2.split('-')[0];
    }

    let regimenFiscal: string = (this.formGroupInformation.controls['REGIMEN_FISCAL'].value).trim();
    regimenFiscal = regimenFiscal.substring( regimenFiscal.length - 4, regimenFiscal.length - 1)
    
    
    let numeroProveedor = this.formGroupInformation.controls['NUMERO_PROVEEDOR'].value;
    numeroProveedor = numeroProveedor.toString().trim();

    let razonSocial = this.formGroupInformation.controls['RAZON_SOCIAL'].value;
    razonSocial = razonSocial.toString().trim();

    let correo = this.formGroupInformation.controls['CORREO'].value;
    correo = correo.toString().trim();

    let nombre = this.formGroupInformation.controls['NOMBRE'].value;
    nombre = nombre.toString().trim();

    let primerApellido = this.formGroupInformation.controls['PRIMER_APELLIDO'].value;
    primerApellido = primerApellido.toString().trim();

    let segundoApellido = this.formGroupInformation.controls['SEGUNDO_APELLIDO'].value;
    if (segundoApellido !== null && segundoApellido !== '' && segundoApellido !== undefined) {
      segundoApellido = segundoApellido.toString().trim();
    } else {
      segundoApellido = null;
    }

    let telefono1 = this.formGroupInformation.controls['TELEFONO1'].value;
    telefono1 = telefono1.toString().trim();

    let telefono2 = this.formGroupInformation.controls['TELEFONO2'].value;
    if (telefono2 !== null && telefono2 !== '' && telefono2 !== undefined) {
      telefono2 = telefono2.toString().trim();
    } else {
      telefono2 = null;
    }

    let tipo = this.formGroupInformation.controls['TIPO'].value;
    tipo = tipo.toString().trim();

    let tipoContribuyente = this.formGroupInformation.controls['TIPO_CONTRIBUYENTE'].value;
    tipoContribuyente = tipoContribuyente.toString().trim();

    let rfc = this.formGroupInformation.controls['RFC'].value;
    if (rfc !== null && rfc !== '' && rfc !== undefined) {
      rfc = rfc.toString().trim();
    }

    let taxid = this.formGroupInformation.controls['TAXID'].value;
    if (taxid !== null && taxid !== '' && taxid !== undefined) {
      taxid = taxid.toString().trim();
    }

    let sitioweb = this.formGroupInformation.controls['SITIOWEB'].value;
    if (sitioweb !== null && sitioweb !== '' && sitioweb !== undefined) {
      sitioweb = sitioweb.toString().trim();
    }

    let estado = this.formGroupInformation.controls['ESTADO'].value;
    estado = estado.toString().trim();

    let calle = this.formGroupInformation.controls['CALLE'].value;
    calle = calle.toString().trim();

    let exterior = this.formGroupInformation.controls['EXTERIOR'].value;
    exterior = exterior.toString().trim();

    let interior = this.formGroupInformation.controls['INTERIOR'].value;
    if (interior !== null && interior !== '' && interior !== undefined) {
      interior = interior.toString().trim();
    }

    let codigoPostal = this.formGroupInformation.controls['CODIGO_POSTAL'].value;
    codigoPostal = codigoPostal.toString().trim();

    let colonia = this.formGroupInformation.controls['COLONIA'].value;
    colonia = colonia.toString().trim();
    
    if (tipo === 'Nacional') {
      try {
        colonia = colonia.split('(')[1].split(')')[0];
      } catch (error) {
        this.resourcesService.openSnackBar(`Ocurrió un error con el campo Colonia`);
        return false;
      }
    }
    let localidad = this.formGroupInformation.controls['LOCALIDAD'].value;
    localidad = localidad.toString().trim();
    if (tipo === 'Nacional') {
      if (localidad !== `Sin localidad`) {
        try {
          localidad = localidad.split('(')[1].split(')')[0];
        } catch (error) {
          this.resourcesService.openSnackBar(`Ocurrió un error con el campo Localidad`);
          return false;
        }
      }
    }
    
    let municipio = this.formGroupInformation.controls['MUNICIPIO'].value;
    municipio = municipio.toString().trim();
    if (tipo === 'Nacional') {
      try {
        municipio = municipio.split('(')[1].split(')')[0];
      } catch (error) {
        this.resourcesService.openSnackBar(`Ocurrió un error con el campo Municipio`);
        return false;
      }
    }
    let entidad = this.formGroupInformation.controls['ENTIDAD'].value;
    entidad = entidad.toString().trim();
    if (tipo === 'Nacional') {
      try {
        entidad = entidad.split('(')[1].split(')')[0];
      } catch (error) {
        this.resourcesService.openSnackBar(`Ocurrió un error con el campo Entidad Federativa`);
        return false;
      }
    }
    
    let pais = this.formGroupInformation.controls['PAIS'].value;
    pais = pais.toString().trim();
    // if (tipo === 'Nacional') {
      try {
        pais = pais.split('(')[1].split(')')[0];
      } catch (error) {
        this.resourcesService.openSnackBar(`Ocurrió un error con el campo País`);
        return false;
      } 
    // }

    let idSubcontract = this.typeForm.subcontract;
    if (idSubcontract !== null) {
      idSubcontract = idSubcontract.toString().trim();
    }

    let formPersonal: InformationData = {
      NUMERO_PROVEEDOR: numeroProveedor,
      RAZON_SOCIAL: razonSocial,
      CORREO: correo,
      NOMBRE: nombre,
      PRIMER_APELLIDO: primerApellido,
      SEGUNDO_APELLIDO: segundoApellido,
      LADA1: lada1,
      TELEFONO1: telefono1,
      LADA2: lada2,
      TELEFONO2: telefono2,
      REGIMEN_FISCAL: regimenFiscal,
      TIPO: tipo,
      TIPO_CONTRIBUYENTE: tipoContribuyente,
      RFC: rfc,
      TAXID: taxid,
      SITIOWEB: sitioweb,
      ESTADO: estado,
      CALLE: calle,
      EXTERIOR: exterior,
      INTERIOR: interior,
      CODIGO_POSTAL: codigoPostal,
      COLONIA: colonia,
      LOCALIDAD: localidad,
      MUNICIPIO: municipio,
      ENTIDAD: entidad,
      PAIS: pais,
      ID_SUBCONTRACT: idSubcontract,
    }
    

    let arrReferences: Array<ReferenceData> = [];
    this.dataSourceReference.data.forEach((element:ReferenceData) => {
      arrReferences.push({
        NUMERO_REFERENCIA: element.NUMERO_REFERENCIA,
        RAZON_SOCIAL: element.RAZON_SOCIAL,
        CORREO: element.CORREO,
        LADA: element.LADA,
        TELEFONO: element.TELEFONO,
        RFC: element.RFC,
        DIRECCION: element.DIRECCION,
        ESTADO: element.ESTADO,
      });
    });

    let arrContacts: Array<ContactForm> = [];
    this.dataSourceContact.data.forEach((element: ContactForm) => {
      arrContacts.push({
        ID_CONTACTO: element.ID_CONTACTO,
        NOMBRE_CONTACTO: element.NOMBRE_CONTACTO,
        TIPO_CONTACTO: element.TIPO_CONTACTO,
        CALLE: element.CALLE,
        NUMERO_EXTERIOR: element.NUMERO_EXTERIOR,
        NUMERO_INTERIOR: element.NUMERO_INTERIOR,
        COLONIA: element.COLONIA,
        CODIGO_POSTAL: element.CODIGO_POSTAL,
        LOCALIDAD: element.LOCALIDAD,
        MUNICIPIO: element.MUNICIPIO,
        ENTIDAD: element.ENTIDAD,
        PAIS: element.PAIS,
        LADA1: lada1,
        TELEFONO1: (element.TELEFONO1.toString()).trim(),
        LADA2: lada2,
        TELEFONO2: element.TELEFONO2 !== null ? (element.TELEFONO2.toString()).trim() : '',
        CORREO1: (element.CORREO1).trim(),
        CORREO2: element.CORREO2 !== null ? (element.CORREO2).trim() : '',
        OBSERVACIONES: element.OBSERVACIONES !== null ? (element.OBSERVACIONES).trim() : '',
        ESTADO: (element.ESTADO).trim(),
      });
    });

    let arrCondition: Array<ConditionForm> = [];
    this.dataSourceCondition.data.forEach((element: ConditionData) => {
      arrCondition.push({
        NUMERO_CONDICION: (element.ID_CONDICION?.toString()!).trim(),
        TIPO_CONDICION: (element.TIPO_CONDICION).trim(),
        INFORMACION: (element.INFORMACION).trim(),
        ESTADO: (element.ESTADO).trim(),
      });
    });

    let arrCatalog: Array<CatalogForm> = [];
    this.dataSourceCatalog.data.forEach((element: CatalogData) => {
      arrCatalog.push({
        NUMERO_CATALAGO: (element.ID_CATALOG?.toString()!).trim(),
        CATALAGO: (element.CATALAGO).trim(),
        DESCRIPCION: (element.DESCRIPCION).trim(),
        URL_CATALAGO: (element.URL_CATALAGO).trim(),
        ESTADO: (element.ESTADO).trim(),
      });
    });

    let objResponse: RegisterForm = {
      INFORMACION: formPersonal,
      REFERENCIAS: arrReferences,
      CONTACTOS: arrContacts,
      CONDICIONES: arrCondition,
      METODOS_PAGO: this.selection.selected,
      CATALAGOS: arrCatalog,
    }
    return objResponse;
  }

  private async saveLocalProvider(){
    let encUser: string = this.resourcesService.getUser();
    let user: string = await this._encService.decrypt(encUser);

    // Se guarda en un objeto la información del formulario
    let objectSaveData: SaveData = {
      INFORMATION_PERSONAL: this.formGroupInformation.value,
      REFERENCES: this.dataSourceReference.data,
      CONTACTS: this.dataSourceContact.data,
      CONDITIONS: this.dataSourceCondition.data,
      PAYMENT_MEDIA: this.selection.selected,
      CATALOGS: this.dataSourceCatalog.data
    };

    // El objeto del formulario se guarda en otro objeto con información del usuario
    let objSaveLocal: ProviderSave = {
      USER: encUser,
      OBJ_DATA: objectSaveData,
      FERE: this.resourcesService.getDateFormat()
    }

    // El objeto se transforma a una cadena
    let strSaveLocal: string = JSON.stringify(objSaveLocal);
    // La cadena es encriptada
    let encSaveLocal: string = await this._encService.encrypt(strSaveLocal);

    // Se obtienen los borradores guardados
    let saveProvider = localStorage.getItem('save_provider');

    // Si
    if (saveProvider === null) {
      let strProvider = JSON.stringify([encSaveLocal]);
      localStorage.setItem('save_provider', strProvider);
    }else{
      let arrSaveLocal:Array<string> = JSON.parse(saveProvider);
      let isLocatedUser: boolean = false;
      let arrSaveLocalTemp: Array<string> = [];
      await Promise.all( arrSaveLocal.map(async (element:string)=>{
        let decSaveProvier: string = await this._encService.decrypt(element);
        let objSaveLocal: ProviderSave = JSON.parse(decSaveProvier);
        let userSaveLocal = await this._encService.decrypt(objSaveLocal.USER)
        if ( userSaveLocal === user) {
          isLocatedUser = true;
          arrSaveLocalTemp.push(encSaveLocal);
        }else{
          arrSaveLocalTemp.push(element);
        }
      }));

      arrSaveLocal = arrSaveLocalTemp;
      if (!isLocatedUser) {
        arrSaveLocal.push(encSaveLocal);
      }

      // El objeto se transforma a una cadena
      let strSaveLocal: string = JSON.stringify(arrSaveLocal);
      localStorage.setItem('save_provider', strSaveLocal);
    }
    this.resourcesService.openSnackBar('La información del proveedor ha sido guardada exitosamente');
    this.isLoadingForm = false;
    this.resourcesService.goBack();
  }
  
  private async setLocalProvider(elementData:SaveData){
    this.formGroupInformation.setValue( this.formatInfo(elementData.INFORMATION_PERSONAL) );
    this.dataSourceReference.data = elementData.REFERENCES;
    this.dataSourceContact.data = elementData.CONTACTS;
    this.dataSourceCondition.data = elementData.CONDITIONS;
    this.dataSourceCatalog.data = elementData.CATALOGS;
    this.isFormLocalSave = true;
  }
  
  private formatInfo(elementInformation: InformationData) : InformationData{
    if (elementInformation.TAXID === undefined) {
      elementInformation.TAXID = '';
    }
    if (elementInformation.RFC === undefined) {
      elementInformation.RFC = '';
    }
    return elementInformation;
  }
  
  private async getCoutries() {
    const idUser: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._systemAdminService.getCountriesList(idUser, line)).then(
      async (responseData: CountriesListResponse) => {
        if (!responseData.error) {
          this.arrCountries = responseData.response;
          
          if (this.arrCountries.length === 0) {
            this.resourcesService.openSnackBar(`No existen paises registrados en el sistema.`);
            this.resourcesService.goBack()
            return;
          }

          let mex = responseData.response.filter(item => item.COUNTRY_ID == 'MEX');
          
          this.countries.push(mex[0]);
          this.countriesStr.push(`${mex[0].NAME} (${mex[0].COUNTRY_ID})`);
          this.flags.set(`${mex[0].LADA!}-${mex[0].NOMECLARUTA_ISO2!}`, mex[0].NOMECLARUTA_ISO2!);
          this.ladasStr.push(`${mex[0].LADA!}-${mex[0].NOMECLARUTA_ISO2!}`);

          let usa = responseData.response.filter(item => item.COUNTRY_ID == 'USA');
          this.countries.push(usa[0]);
          this.countriesStr.push(`${usa[0].NAME} (${usa[0].COUNTRY_ID})`);
          this.flags.set(`${usa[0].LADA!}-${usa[0].NOMECLARUTA_ISO2!}`, usa[0].NOMECLARUTA_ISO2!);
          this.ladasStr.push(`${usa[0].LADA!}-${usa[0].NOMECLARUTA_ISO2!}`);

          let can = responseData.response.filter(item => item.COUNTRY_ID == 'CAN');
          this.countries.push(can[0]);
          this.countriesStr.push(`${can[0].NAME} (${can[0].COUNTRY_ID})`);
          this.flags.set(`${can[0].LADA!}-${can[0].NOMECLARUTA_ISO2!}`, can[0].NOMECLARUTA_ISO2!);
          this.ladasStr.push(`${can[0].LADA!}-${can[0].NOMECLARUTA_ISO2!}`);
          
          for(const country of responseData.response){
            if(country.COUNTRY_ID != null && country.COUNTRY_ID != 'MEX' && country.COUNTRY_ID != 'USA' && country.COUNTRY_ID != 'CAN'){
              this.countries.push(country);
              this.countriesStr.push(`${country.NAME} (${country.COUNTRY_ID})`);
              
              if(country.LADA != '' && country.NOMECLARUTA_ISO2 != '' && country.NOMECLARUTA_ISO2 != '0'){
                let currentURI = window.location.href;
                let currentURIArr = currentURI.split('#');
                let flagURI = `${currentURIArr[0]}assets/img/flags/${country.NOMECLARUTA_ISO2!}.png`;
                let fileExists = await this.fileExists(flagURI);

                if(fileExists){
                  this.flags.set(`${country.LADA!}-${country.NOMECLARUTA_ISO2!}`, country.NOMECLARUTA_ISO2!);
                  this.ladasStr.push(`${country.LADA!}-${country.NOMECLARUTA_ISO2!}`);
                }
              }
            }
          }
        } 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 fileExists(url: string){
    try{
      let res: any = await lastValueFrom(this._httpClient.get(url).pipe());
      if(res.status == 200){
        return true;
      }else{
        return false;
      }
    }catch(error: any){
      if(error.status == 200){
        return true;
      }else{
        return false;
      }
    }
  }
  
  private async getTaxRegimeActive() {
    const idUser: string = this.resourcesService.getUser();
    const line: number =  this.resourcesService.getLineNumber();
    await lastValueFrom(this._systemAdminService.getTaxRegimeList(idUser, line)).then(
      (responseData: TaxRegimeListResponse) => {
        if (!responseData.error) {
          if (responseData.response.length === 0) {
            this.resourcesService.openSnackBar(`No existen regimen fiscales registrados.`);
            this.resourcesService.goBack()
            return;
          }
          this.arrTaxRegime = responseData.response;
        } 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 getDataForm(){
    let encForm:string = this._activatedRouter.snapshot.paramMap.get('form')!;
    let strForm:string = await this._encService.decrypt(encForm);
    this.typeForm = JSON.parse(strForm);

    let informationPersonal:InformationData = this.typeForm.element!;
    

    if (this.typeForm.subcontract !== null && this.typeForm.subcontract !== undefined) {
      await this.getSubcontractById(this.typeForm.subcontract);
    }

    if (this.typeForm.type === 'EDIT' && this.typeForm.element !== undefined && this.typeForm.element !== null) {

      if (this.typeForm.element.METODOS_PAGO !== null && this.typeForm.element.METODOS_PAGO !== undefined) {
        const paymentMethod = this.typeForm.element.METODOS_PAGO;
        const arrIdPayment = Object.keys(paymentMethod);
        const dataPaymentMethod = this.dataSourcePaymentMethod.data.filter((elementPaymentMethod:GetPaymentMethod) => arrIdPayment.includes(elementPaymentMethod.C_FORMAPAGO.toString()) );
        this.selection.setSelection(...dataPaymentMethod);
      }

      
      this.formGroupInformation.controls['NUMERO_PROVEEDOR'].setValue(informationPersonal.NUMERO_PROVEEDOR);
      this.formGroupInformation.controls['RAZON_SOCIAL'].setValue(informationPersonal.RAZON_SOCIAL);
      this.formGroupInformation.controls['NOMBRE'].setValue(informationPersonal.NOMBRE);
      this.formGroupInformation.controls['PRIMER_APELLIDO'].setValue(informationPersonal.PRIMER_APELLIDO);
      this.formGroupInformation.controls['SEGUNDO_APELLIDO'].setValue(informationPersonal.SEGUNDO_APELLIDO);
      this.formGroupInformation.controls['CORREO'].setValue(informationPersonal.CORREO);
      this.formGroupInformation.controls['SITIOWEB'].setValue(informationPersonal.SITIOWEB);

      this.formGroupInformation.controls['LADA1'].setValue(informationPersonal.LADA1);
      this.formGroupInformation.controls['TELEFONO1'].setValue(informationPersonal.TELEFONO1);
      this.formGroupInformation.controls['LADA2'].setValue(informationPersonal.LADA2);
      this.formGroupInformation.controls['TELEFONO2'].setValue(informationPersonal.TELEFONO2);
      
      this.formGroupInformation.controls['TIPO_CONTRIBUYENTE'].setValue(informationPersonal.TIPO_CONTRIBUYENTE);
      this.formGroupInformation.controls['REGIMEN_FISCAL'].setValue(informationPersonal.REGIMEN_FISCAL);
      this.formGroupInformation.controls['TIPO'].setValue(informationPersonal.TIPO);
      this.onchangeType();
      this.formGroupInformation.controls['RFC'].setValue(informationPersonal.RFC);
      this.formGroupInformation.controls['TAXID'].setValue(informationPersonal.TAXID);
      
      this.formGroupInformation.controls['CALLE'].setValue(informationPersonal.CALLE);
      this.formGroupInformation.controls['EXTERIOR'].setValue(informationPersonal.EXTERIOR);
      this.formGroupInformation.controls['INTERIOR'].setValue(informationPersonal.INTERIOR);
      this.formGroupInformation.controls['CODIGO_POSTAL'].setValue(informationPersonal.CODIGO_POSTAL);

      if ( informationPersonal.TIPO !== 'Extranjero') {
        await this.searchZipCode();
        // await this.searchAddressByZipCode(informationPersonal.CODIGO_POSTAL);
      } else {
        await this.getCoutries();
        this.formGroupInformation.controls['LOCALIDAD'].setValue(informationPersonal.LOCALIDAD);
        this.formGroupInformation.controls['MUNICIPIO'].setValue(informationPersonal.MUNICIPIO);
        this.formGroupInformation.controls['ENTIDAD'].setValue(informationPersonal.ENTIDAD);

        let country = this.arrCountries.find(element => element.COUNTRY_ID === informationPersonal.PAIS)
        if (country === undefined) {
          this.formGroupInformation.controls['PAIS'].setValue(informationPersonal.PAIS);
        } else {
          this.formGroupInformation.controls['PAIS'].setValue(`${country.NAME} (${country.COUNTRY_ID})`);
        }
        
      }
      
      let city = this.citySettingsStr.find((element) => element.split('(')[1].split(')')[0] === informationPersonal.COLONIA);
      city = city === undefined ? informationPersonal.COLONIA : city;      
      this.formGroupInformation.controls['COLONIA'].setValue(city);

      this.formGroupInformation.controls['ESTADO'].setValue(informationPersonal.ESTADO);

      let arrReferences:Array<ReferenceData> = this.typeForm.element?.REFERENCIAS!;
      let arrDataReference:Array<ReferenceData> = [];
      arrReferences.map((element:ReferenceData) => {
        arrDataReference.push({
          NUMERO_REFERENCIA: element.NUMERO_REFERENCIA,
          RAZON_SOCIAL: element.RAZON_SOCIAL,
          CORREO: element.CORREO,
          LADA: element.LADA,
          TELEFONO: element.TELEFONO,
          RFC: element.RFC,
          DIRECCION: element.DIRECCION,
          ESTADO: element.ESTADO,
        });
      });
      this.dataSourceReference.data = arrDataReference;

      let arrContacts:Array<ContactForm> = this.typeForm.element?.CONTACTOS!;
      let arrDataContacts:Array<ContactForm> = [];
      arrContacts.map((element:ContactForm) => {
        arrDataContacts.push({
          ID_CONTACTO: element.ID_CONTACTO,
          NOMBRE_CONTACTO: element.NOMBRE_CONTACTO,
          TIPO_CONTACTO: element.TIPO_CONTACTO,
          CALLE: element.CALLE,
          NUMERO_EXTERIOR: element.NUMERO_EXTERIOR,
          NUMERO_INTERIOR: element.NUMERO_INTERIOR,
          COLONIA: element.COLONIA,
          CODIGO_POSTAL: element.CODIGO_POSTAL,
          LOCALIDAD: element.LOCALIDAD,
          MUNICIPIO: element.MUNICIPIO,
          ENTIDAD: element.ENTIDAD,
          PAIS: element.PAIS,
          LADA1: element.LADA1,
          TELEFONO1: element.TELEFONO1,
          LADA2: element.LADA2,
          TELEFONO2: element.TELEFONO2,
          CORREO1: element.CORREO1,
          CORREO2: element.CORREO2,
          OBSERVACIONES: element.OBSERVACIONES,
          ESTADO: element.ESTADO,
        });
      });
      
      this.dataSourceContact.data = arrDataContacts;

      let arrConditions:Array<ConditionForm> = this.typeForm.element?.CONDICIONES!;
      let arrDataConditions: Array<ConditionData> = [];
      arrConditions.map((element:ConditionForm) => {
        arrDataConditions.push({
          ID_CONDICION: element.NUMERO_CONDICION?.toString(),
          TIPO_CONDICION: element.TIPO_CONDICION,
          INFORMACION: element.INFORMACION,
          ESTADO: element.ESTADO,
        });
      });
      this.dataSourceCondition.data = arrDataConditions;

      let arrCatalogs:Array<CatalogForm> = this.typeForm.element?.CATALAGOS!;
      let arrDataCatalogs: Array<CatalogData> = [];
      arrCatalogs.map((element:CatalogForm) => {
        arrDataCatalogs.push({
          ID_CATALOG: element.NUMERO_CATALAGO?.toString(),
          CATALAGO: element.CATALAGO,
          DESCRIPCION: element.DESCRIPCION,
          URL_CATALAGO: element.URL_CATALAGO,
          ESTADO: element.ESTADO,
        });
      });
      this.dataSourceCatalog.data = arrDataCatalogs;
    } else {
      this.dataSourcePaymentMethod.data = this.arrPaymentMethod;
    }
  }
  
  private async getSubcontractById(idSubcontract:string) {
    const encIdSubcontract = await this._encService.encrypt(idSubcontract);
    const USER: string = this.resourcesService.getUser();
    const LINE: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._subcontratistService.getSubcontratistById(encIdSubcontract, USER, LINE)).then(
      async (responseData:ResponseDataSubcontratist) => {
        if (!responseData.error) {

          this.formGroupInformation.controls['RAZON_SOCIAL'].setValue(responseData.response.SOCIAL_REASON);
          this.formGroupInformation.controls['CORREO'].setValue(responseData.response.EMAIL);
          this.formGroupInformation.controls['LADA1'].setValue(responseData.response.LADA1);
          this.formGroupInformation.controls['TELEFONO1'].setValue(responseData.response.TELEPHONE1);
          this.formGroupInformation.controls['LADA2'].setValue(responseData.response.LADA2);
          this.formGroupInformation.controls['TELEFONO2'].setValue(responseData.response.TELEPHONE2);
          this.formGroupInformation.controls['TIPO'].setValue(responseData.response.FOREIGNER === 'Si' ? 'Extranjero' : 'Nacional');
          this.onchangeType();
          this.formGroupInformation.controls['TIPO_CONTRIBUYENTE'].setValue(responseData.response.CONTRACT_TYPE);
          this.formGroupInformation.controls['REGIMEN_FISCAL'].setValue(responseData.response.TAX_REFERENCE);          
          this.formGroupInformation.controls['RFC'].setValue(responseData.response.RFC);
          this.formGroupInformation.controls['TAXID'].setValue(responseData.response.TAX);          
          this.formGroupInformation.controls['CALLE'].setValue(responseData.response.STREET);
          this.formGroupInformation.controls['EXTERIOR'].setValue(responseData.response.EXTERIOR_NUMBER);
          this.formGroupInformation.controls['INTERIOR'].setValue(responseData.response.INTERIOR_NUMBER);
          this.formGroupInformation.controls['CODIGO_POSTAL'].setValue(responseData.response.POSTAL_CODE);
          if (responseData.response.FOREIGNER === 'No') {
            await this.searchZipCode();
          } else {
            this.formGroupInformation.controls['LOCALIDAD'].setValue(responseData.response.TOWN);
            this.formGroupInformation.controls['MUNICIPIO'].setValue(responseData.response.CITY);
            this.formGroupInformation.controls['ENTIDAD'].setValue(responseData.response.FEDERAL_ENTITY);
            this.formGroupInformation.controls['PAIS'].setValue(responseData.response.COUNTRY);
          }
          this.formGroupInformation.controls['CODIGO_POSTAL'].disable();

          this.formGroupInformation.controls['COLONIA'].setValue(responseData.response.SUBURB);          
          this.formGroupInformation.controls['ESTADO'].setValue(`Nuevo`);


          this.formGroupInformation.controls['RAZON_SOCIAL'].disable();
          this.formGroupInformation.controls['CORREO'].disable();
          this.formGroupInformation.controls['LADA1'].disable();
          this.formGroupInformation.controls['TELEFONO1'].disable();
          this.formGroupInformation.controls['LADA2'].disable();
          this.formGroupInformation.controls['TELEFONO2'].disable();
          this.formGroupInformation.controls['TIPO'].disable();
          this.formGroupInformation.controls['TIPO_CONTRIBUYENTE'].disable();
          this.formGroupInformation.controls['REGIMEN_FISCAL'].disable();
          this.formGroupInformation.controls['RFC'].disable();
          this.formGroupInformation.controls['TAXID'].disable();
          this.formGroupInformation.controls['CALLE'].disable();
          this.formGroupInformation.controls['EXTERIOR'].disable();
          this.formGroupInformation.controls['INTERIOR'].disable();
          this.formGroupInformation.controls['COLONIA'].disable();
          this.formGroupInformation.controls['ESTADO'].disable();

          this.formGroupInformation.controls['LOCALIDAD'].disable();
          this.formGroupInformation.controls['MUNICIPIO'].disable();
          this.formGroupInformation.controls['ENTIDAD'].disable();
          this.formGroupInformation.controls['PAIS'].disable();


        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
        
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getSubcontractById(idSubcontract);
        }
      }
    )
  }
  
  public onchangeType() {
    let contractType = this.formGroupInformation.controls['TIPO_CONTRIBUYENTE'].value;    
    if(contractType == "Persona moral"){
      let moralTaxRegime = this.arrTaxRegime.filter(item => item.APPLY_MORAL == 'Sí');
      
      this.taxLength = 12;
      this.taxRegimeStr = [];
      moralTaxRegime.forEach(item => { this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`); });

      this.formGroupInformation.controls['REGIMEN_FISCAL'].enable();
      
      if (this.formGroupInformation.controls['TIPO'].value === 'Nacional') {
        this.formGroupInformation.controls['RFC'].setValidators([Validators.required, Validators.pattern(new RegExp(/^([A-ZÑ&]{3}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/))]);
        this.formGroupInformation.controls['TAXID'].clearValidators();
      } else {
        this.formGroupInformation.controls['TAXID'].setValidators([Validators.required, Validators.pattern(new RegExp(/^([A-ZÑ&]{3}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/))]);
        this.formGroupInformation.controls['RFC'].clearValidators();
      }

    }else{
      
      let phisicTaxRegime = this.arrTaxRegime.filter(item => item.APPLY_PHISIC == 'Sí');
      
      this.taxLength = 13;
      this.taxRegimeStr = [];
      phisicTaxRegime.forEach(item => {
        this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`);
      });

      this.formGroupInformation.controls['REGIMEN_FISCAL'].enable();

      if (this.formGroupInformation.controls['TIPO'].value === 'Nacional') {
        this.formGroupInformation.controls['RFC'].setValidators([Validators.required, Validators.pattern(new RegExp(/^([A-ZÑ&]{4}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/))]);
        this.formGroupInformation.controls['TAXID'].clearValidators();
      } else {
        this.formGroupInformation.controls['TAXID'].setValidators([Validators.required, Validators.pattern(new RegExp(/^([A-ZÑ&]{4}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/))]);
        this.formGroupInformation.controls['RFC'].clearValidators();
      }
    }
    
    if (!this.isLoading) {
      this.formGroupInformation.controls['RFC'].setValue(null);
      this.formGroupInformation.controls['TAXID'].setValue(null);
      this.formGroupInformation.controls['REGIMEN_FISCAL'].setValue(null);
    }
  }

  public async searchZipCode() {
    let postalCode:string = this.formGroupInformation.controls['CODIGO_POSTAL'].value.toString();

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

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


      this.formGroupInformation.controls['CODIGO_POSTAL'].enable();
      this.formGroupInformation.controls['COLONIA'].enable();
      this.formGroupInformation.controls['MUNICIPIO'].enable();
      this.formGroupInformation.controls['ENTIDAD'].enable();
      this.formGroupInformation.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._systemAdminService.getAddressByZipCode(
      encPostalCode, idUser, lineNumber
    )).then(
      (responseData: AddressByZipCodeResponse) => {
        if (!responseData.error) {

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

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

          if (responseData.response.CODIGO_MUNICIPIO !== null) {
            this.formGroupInformation.controls['MUNICIPIO'].setValue(`${responseData.response.NOMBRE_MUNICIPIO} (${responseData.response.CODIGO_MUNICIPIO})`);
          } else {
            this.formGroupInformation.controls['MUNICIPIO'].setValue(`Sin municipio`);
          }
          
          if (responseData.response.CODIGO_ESTADO !== null) {
            this.formGroupInformation.controls['ENTIDAD'].setValue(`${responseData.response.NOMBRE_ESTADO} (${responseData.response.CODIGO_ESTADO})`);
          } else {
            this.formGroupInformation.controls['ENTIDAD'].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.formGroupInformation.controls['COLONIA'].setValue('Sin colonia');
            this.formGroupInformation.controls['LOCALIDAD'].setValue(`Sin localidad`);
            this.formGroupInformation.controls['MUNICIPIO'].setValue(`Sin municipio`);
            this.formGroupInformation.controls['ENTIDAD'].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);
        }
      }
    );
  }
  
  private verifyTown(value: string){
    let stateVal = this.formGroupInformation.controls['ENTIDAD'].value;
    let stateArr = stateVal.split('(').reverse();
    let stateCode = stateArr[0].replace(')', '');

    let cityVal = this.formGroupInformation.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._systemAdminService.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.formGroupInformation.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 toggleAllRows() {
    if (this.isAllSelected()) {
      this.selection.clear();
      return;
    }

    this.selection.select(...this.dataSourcePaymentMethod.data);
  }
  
  private isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSourcePaymentMethod.data.length;
    return numSelected === numRows;
  }
  
  public openDialogReference(typeDialog: string, dataElement?: ReferenceData) {
    this._dialog.open(ReferencesFormComponent, {
      disableClose: true,
      width: '500px',
      maxWidth: '500px',
      data: {
        typeDialog: typeDialog,
        dataElement: dataElement,
        dataSource: this.dataSourceReference.data,
      }
    }).afterClosed().subscribe((result:any) => {
      if (result) {
        this.dataSourceReference.data = result;
      }
    });
  }
  
  public async deleteReference(dataElement: ReferenceData):Promise<void> {
    this._dialog.open(AlertComponent, {
      disableClose: true,
      data: {
        icon: "warning",
        title: "Eliminar Referencia",
        description: "¿Está seguro de eliminar la referencia?"
      },
    }).afterClosed().subscribe((result) => {
      if (result) {
        this.dataSourceReference.data = this.dataSourceReference.data.map((element: ReferenceData) => {
          if (element.NUMERO_REFERENCIA === dataElement.NUMERO_REFERENCIA) {
            element.ESTADO = 'Eliminado';
          }
          return element;
        });
      }
    });
  }
  
  public openDialogContact(typeDialog: string, dataElement?: ContactForm) {
    this._dialog.open(ContactProviderFormComponent, {
      disableClose: true,
      width: '1300px',
      maxWidth: '1300px',
      data: {
        typeDialog: typeDialog,
        dataElement: dataElement,
        dataSource: this.dataSourceContact.data,
      }
    }).afterClosed().subscribe((result:any) => {
      if (result) {
        this.dataSourceContact.data = result;
      }
    });
  }
  
  public async deleteContact(dataElement: ContactForm):Promise<void> {
    this._dialog.open(AlertComponent, {
      disableClose: true,
      data: {
        icon: "warning",
        title: "Eliminar Contacto",
        description: "¿Está seguro de eliminar el contacto?"
      },
    }).afterClosed().subscribe((result) => {
      if (result) {
        this.dataSourceContact.data = this.dataSourceContact.data.map((element: ContactForm) => {
          if (element.ID_CONTACTO === dataElement.ID_CONTACTO) {
            element.ESTADO = 'Eliminado';
          }
          return element;
        });
      }
    });
  }
  
  public openDialogCondition(typeDialog: string, dataElement?: ConditionData) {
    this._dialog.open(ConditionProviderFormComponent, {
      disableClose: true,
      width: '800px',
      maxWidth: '800px',
      data: {
        typeDialog: typeDialog,
        dataElement: dataElement,
        dataSource: this.dataSourceCondition.data,
      }
    }).afterClosed().subscribe((result:any) => {
      if (result) {
        this.dataSourceCondition.data = result;
      }
    });
  }

  public async deleteCondition(dataElement: ConditionData):Promise<void> {
    this._dialog.open(AlertComponent, {
      disableClose: true,
      data: {
        icon: "warning",
        title: "Eliminar Condición",
        description: "¿Está seguro de eliminar el contacto?"
      },
    }).afterClosed().subscribe((result) => {
      if (result) {
        this.dataSourceCondition.data = this.dataSourceCondition.data.map((element: ConditionData) => {
          if (element.ID_CONDICION === dataElement.ID_CONDICION) {
            element.ESTADO = 'Eliminado';
          }
          return element;
        });
      }
    });
  }
  
  public openDialogCatalog(typeDialog: string, dataElement?: CatalogData) {
    this._dialog.open(CatalogsProviderFormComponent, {
      disableClose: true,
      width: '600px',
      maxWidth: '600px',
      data: {
        typeDialog: typeDialog,
        dataElement: dataElement,
        dataSource: this.dataSourceCatalog.data,
      }
    }).afterClosed().subscribe((result:any) => {
      if (result) {
        this.dataSourceCatalog.data = result;
      }
    });
  }
  
  public async deleteCatalog(dataElement: CatalogData):Promise<void> {
    this._dialog.open(AlertComponent, {
      disableClose: true,
      data: {
        icon: "warning",
        title: "Eliminar Condición",
        description: "¿Está seguro de eliminar el contacto?"
      },
    }).afterClosed().subscribe((result) => {
      if (result) {
        this.dataSourceCatalog.data = this.dataSourceCatalog.data.map((element: CatalogData) => {
          if (element.ID_CATALOG === dataElement.ID_CATALOG) {
            element.ESTADO = 'Eliminado';
          }
          return element;
        });
      }
    });
  }

  public changeType() {
    if (this.formGroupInformation.controls['TIPO'].value === 'Nacional') {
      this.formGroupInformation.controls['RFC'].enable();
      this.formGroupInformation.controls['RFC'].addValidators(Validators.required);
      this.formGroupInformation.controls['TAXID'].clearValidators();
      this.formGroupInformation.controls['TAXID'].setValue(null);
      this.formGroupInformation.controls['TAXID'].setErrors(null);
      this.formGroupInformation.controls['TAXID'].disable();
    }else if (this.formGroupInformation.controls['TIPO'].value === 'Extranjero') {
      this.formGroupInformation.controls['TAXID'].enable();
      this.formGroupInformation.controls['TAXID'].addValidators(Validators.required);
      this.formGroupInformation.controls['RFC'].clearValidators();
      this.formGroupInformation.controls['RFC'].setValue(null);
      this.formGroupInformation.controls['RFC'].setErrors(null);
      this.formGroupInformation.controls['RFC'].disable();
    }else{
      this.formGroupInformation.controls['RFC'].clearValidators();
      this.formGroupInformation.controls['RFC'].setErrors(null);
      this.formGroupInformation.controls['TAXID'].clearValidators();
      this.formGroupInformation.controls['TAXID'].setErrors(null);
    }

    this.formGroupInformation.controls['CODIGO_POSTAL'].setValue('');
    this.formGroupInformation.controls['COLONIA'].setValue('');
    this.formGroupInformation.controls['LOCALIDAD'].setValue('');
    this.formGroupInformation.controls['MUNICIPIO'].setValue('');
    this.formGroupInformation.controls['ENTIDAD'].setValue('');
    this.formGroupInformation.controls['PAIS'].setValue('');

    this.formGroupInformation.controls['RFC'].updateValueAndValidity();
    this.formGroupInformation.controls['TAXID'].updateValueAndValidity();
  }
  
  public changeLada() {
    if (
      this.formGroupInformation.controls['LADA2'].value !== undefined &&
      this.formGroupInformation.controls['LADA2'].value !== null &&
      this.formGroupInformation.controls['LADA2'].value !== ''
    ) {
      this.formGroupInformation.controls['LADA2'].addValidators(Validators.required);
      this.formGroupInformation.controls['TELEFONO2'].addValidators(Validators.required);
      this.formGroupInformation.controls['LADA2'].updateValueAndValidity()
      this.formGroupInformation.controls['TELEFONO2'].updateValueAndValidity();
    }else{
      this.formGroupInformation.controls['LADA2'].clearValidators();
      this.formGroupInformation.controls['LADA2'].setErrors(null);
      this.formGroupInformation.controls['TELEFONO2'].clearValidators();
      this.formGroupInformation.controls['TELEFONO2'].setErrors(null);
      this.formGroupInformation.controls['LADA2'].updateValueAndValidity()
      this.formGroupInformation.controls['TELEFONO2'].updateValueAndValidity();
    }
    

  }
  
  public checkColony() {
    if(!this.enableSearchByZipCode) {
      let colony:string = this.formGroupInformation.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.formGroupInformation.controls['CODIGO_POSTAL'].setValue(settingValid[0].CODIGOPOSTAL);
    }
  }
  
  public checkCity() {
    if(!this.enableSearchByZipCode) {
      let municipality: string = this.formGroupInformation.controls['MUNICIPIO'].value;    

      let countryVal = this.formGroupInformation.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.formGroupInformation.controls['LOCALIDAD'].setValue('');
          this.formGroupInformation.controls['LOCALIDAD'].disable();
          this.formGroupInformation.controls['COLONIA'].setValue('');
          this.formGroupInformation.controls['COLONIA'].disable();
        }
      }else{
        this.formGroupInformation.controls['LOCALIDAD'].enable();
      }
    }
  }
  
  private verifyCity(value: string){
    let stateVal = this.formGroupInformation.controls['ENTIDAD'].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._systemAdminService.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.formGroupInformation.controls['LOCALIDAD'].enable();
          }else if(responseData.response.length == 1 && responseData.response[0].CODIGOLOCALIDAD != null){
            this.formGroupInformation.controls['LOCALIDAD'].enable();
          }else{
            this.formGroupInformation.controls['LOCALIDAD'].disable();
            this.formGroupInformation.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;
  }
  
  public checkEntity() {
    let entity: string = this.formGroupInformation.controls['ENTIDAD'].value;
    if (entity === null || entity === undefined) {
      entity = '';
    }

    let countryVal = this.formGroupInformation.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.formGroupInformation.controls['MUNICIPIO'].setValue('');
        this.formGroupInformation.controls['MUNICIPIO'].disable();
        this.formGroupInformation.controls['LOCALIDAD'].setValue('');
        this.formGroupInformation.controls['LOCALIDAD'].disable();
        this.formGroupInformation.controls['COLONIA'].setValue('');
        this.formGroupInformation.controls['COLONIA'].disable();
      }
    }else{
      this.formGroupInformation.controls['MUNICIPIO'].enable();
    }
  }
  
  private verifyState(value: string){
    let countryVal = this.formGroupInformation.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.formGroupInformation.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._systemAdminService.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.formGroupInformation.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;
  }

  public checkIfAddress() {
    let country:string = this.formGroupInformation.controls['PAIS'].value;
    
    if(
      (this.formGroupInformation.controls['TIPO'].value == 'Extranjero' && country != 'México (MEX)') && 
      (this.formGroupInformation.controls['TIPO'].value == 'Extranjero' && country != 'Estados Unidos (los) (USA)') && 
      (this.formGroupInformation.controls['TIPO'].value == 'Extranjero' && country != 'Canadá (CAN)') 
    ){      
      return;
    }

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

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

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

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

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

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

    if(countryCode == 'CAN' || countryCode == 'MEX' || countryCode == 'USA'){
      this.searchCountryStates(countryCode);
    }else{
      this.formGroupInformation.controls['ENTIDAD'].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._systemAdminService.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.formGroupInformation.controls['ENTIDAD'].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;
    }
  }
}
