import { Component, Inject, OnInit } from '@angular/core';
import { SpecialtiesListItem, SpecialtiesListResponse } from '../../../../interfaces/specialties.interface';
import { CountriesList, CountriesListResponse, LadaSelection } from '../../../../interfaces/countries-list.interface';
import { CountryState, CountryStatesResponse } from '../../../../interfaces/country-states.interface';
import { StateCitiesResponse, StateCity } from '../../../../interfaces/state-cities.interface';
import { CityTown, CityTownsResponse } from '../../../../interfaces/city-towns.interface';
import { CitySettings, CitySettingsResponse } from '../../../../interfaces/city-settings.interface';
import { TaxRegimeList, TaxRegimeListResponse } from '../../../../interfaces/tax-regime-list.interface';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { lastValueFrom, map, Observable, startWith } from 'rxjs';
import { ResponseDataSubcontratist, TypeFormSubcontract } from '../../../../interfaces/personal-managment/subcontractist.interface';
import { DOCUMENT } from '@angular/common';
import { ResourcesService } from '../../../../services/resources.service';
import { ActivatedRoute } from '@angular/router';
import { EncService } from '../../../../services/enc.service';
import { MatDialog } from '@angular/material/dialog';
import { SubcontratistService } from '../../../../services/personal-management/subcontratist.service';
import { SystemAdminService } from '../../../../services/system-admin.service';
import { ProviderService } from '../../../../services/acquisition-management/provider.service';
import { SocketService } from '../../../../services/socket.service';
import { InterventionService } from '../../../../services/personal-management/intervention.service';
import { HttpErrorResponse } from '@angular/common/http';
import { ResponseDataGetProvidersById } from '../../../../interfaces/acquisition-management/provider.interface';
import { AddressByZipCodeResponse } from '../../../../interfaces/address-by-zip-code.interface';
import { AlertComponent } from '../../../resources/dialogs/alert/alert.component';
import { ResponseData } from '../../../../interfaces/response-data';

@Component({
    selector: 'app-subcontratist-form',
    templateUrl: './subcontratist-form.component.html',
    styleUrl: './subcontratist-form.component.css',
    standalone: false
})
export class SubcontratistFormComponent implements OnInit {
  public isLoading: boolean;
  public hasError: boolean;
  public errorStr: string;
  public searchingAddress: boolean;
  public statesSelect: boolean;
  public searchingStates: boolean;
  public citiesInput: boolean;
  public searchingCities: boolean;
  public searchingTowns: boolean;
  public searchingSettings: boolean;
  public enableSearchByZipCode: boolean;

  public specialties: SpecialtiesListItem[];
  public countries: CountriesList[];
  public countriesStr: string[];
  public countryStates: CountryState[];
  public countryStatesStr: string[];
  public stateCities: StateCity[];
  public stateCitiesStr: string[];
  public cityTowns: CityTown[];
  public cityTownsStr: string[];
  public citySettings: CitySettings[];
  public citySettingsStr: string[];
  public taxRegime: TaxRegimeList[];
  public taxRegimeStr: string[];
  public ladas: LadaSelection[];
  public ladasStr: string[];
  public formGroup: FormGroup;
  public isLoadingForm: boolean;
  public taxLength: number;

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

  flags: Map<string, string>;

  public typeFormSubcontract: TypeFormSubcontract;

  public btnSmall: boolean;
  public screenSize: number;

  constructor(
    @Inject(DOCUMENT) private _document: Document,
    public resourcesService: ResourcesService,
    private _activatedRoute: ActivatedRoute,
    private _encService: EncService,
    private _dialog: MatDialog,
    private _subcontratistService: SubcontratistService,
    private _sysAdminService: SystemAdminService,
    private _providerService: ProviderService,
    private _socketService: SocketService,
    private _interventionService: InterventionService,
  ) {
    // this.action = "";
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = "";
    this.searchingAddress = false;
    this.statesSelect = true;
    this.searchingStates = false;
    this.citiesInput = false;
    this.searchingCities = false;
    this.searchingTowns = false;
    this.searchingSettings = false;
    this.enableSearchByZipCode = true;

    this.formGroup = this.createFormGroup();
    this.isLoadingForm = false;

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

    this.taxLength = 12;
    this.flags = new Map();

    this.typeFormSubcontract = {} as TypeFormSubcontract;
    this.btnSmall = window.innerWidth <= 1405;
    this.screenSize = window.innerWidth;
  }

  private createFormGroup() {
    return new FormGroup({
      socialReason: new FormControl('', [Validators.required, Validators.maxLength(150)]),
      taxReference: new FormControl({value: '', disabled: true}, Validators.required),
      contractType: new FormControl('', Validators.required),
      foreigner: new FormControl('', Validators.required),
      RFC: new FormControl({value: '', disabled: true}, [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])$/))]),
      tax: new FormControl({value: '', disabled: true}, [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])$/))]),
      email: new FormControl('', [Validators.required, Validators.email, Validators.maxLength(150)]),
      country: new FormControl({value: '', disabled: true}, Validators.required),
      federalEntity: new FormControl({value: '', disabled: true}, Validators.required),
      city: new FormControl({value: '', disabled: true}, Validators.required),
      town: new FormControl({value: '', disabled: true}),
      suburb: new FormControl({value: '', disabled: true}, Validators.required),
      street: new FormControl('', [Validators.required, Validators.maxLength(150)]),
      exteriorNumber: new FormControl('', [Validators.required, Validators.maxLength(10)]),
      interiorNumber: new FormControl('', Validators.maxLength(10)),
      postalCode: new FormControl('', Validators.required),
      telephone1: new FormControl('', [Validators.required, Validators.minLength(7), Validators.maxLength(11)]),
      lada1: new FormControl('', Validators.required),
      telephone2: new FormControl(''),
      lada2: new FormControl(''),
      specialty: new FormControl([], Validators.required),
    })
  }

  async ngOnInit() {
    this.isLoading = true;
    const encTypeForm = this._activatedRoute.snapshot.paramMap.get('form');
    if (encTypeForm === null) {
      this.resourcesService.openSnackBar(`Ocurrió un error al obtener la información del proveedor.`);
      return;
    }

    const strTypeForm: string = await this._encService.decrypt(encTypeForm);
    this.typeFormSubcontract = JSON.parse(strTypeForm);

    await this.getSpecialties();

    await this.getCountries();

    await this.getTaxRegime();

    await this.getDataForm();
    
    this.isLoading = false;

    this.formGroup.controls['federalEntity'].valueChanges.subscribe(value => {
      let countryVal = this.formGroup.controls['country'].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 == value);
        if(validValue.length > 0){
          let valueArr = value.split('(').reverse();
          let stateCode = valueArr[0].replace(')', '');
  
          this.verifyState(stateCode);
        }else{
          this.formGroup.controls['city'].setValue('');
          this.formGroup.controls['city'].disable();
          this.formGroup.controls['town'].setValue('');
          this.formGroup.controls['town'].disable();
          this.formGroup.controls['suburb'].setValue('');
          this.formGroup.controls['suburb'].disable();
        }
      }else{
        this.formGroup.controls['city'].enable();
      }
    });

    this.formGroup.controls['city'].valueChanges.subscribe(value => {
      let countryVal = this.formGroup.controls['country'].value;
      let countryArr = countryVal.split('(').reverse();
      let countryCode = countryArr[0].replace(')', '');

      if(countryCode == 'MEX'){
        let validValue = this.stateCitiesStr.filter(item => item == value);
        if(validValue.length > 0){
          let valueArr = value.split('(').reverse();
          let cityCode = valueArr[0].replace(')', '');
  
          this.verifyCity(cityCode);
        }else{
          this.formGroup.controls['town'].setValue('');
          this.formGroup.controls['town'].disable();
          this.formGroup.controls['suburb'].setValue('');
          this.formGroup.controls['suburb'].disable();
        }
      }else{
        this.formGroup.controls['town'].enable();
      }
    });

    this.formGroup.controls['town'].valueChanges.subscribe(value => {
      let countryVal = this.formGroup.controls['country'].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.formGroup.controls['suburb'].setValue('');
          this.formGroup.controls['suburb'].disable();
        }
      }else{
        this.formGroup.controls['suburb'].enable();
      }
    });
    
    this.formGroup.controls['suburb'].valueChanges.subscribe(value => {
      let validValue = this.citySettingsStr.filter(item => item == value);
      if(validValue.length > 0){
        let valueArr = value.split('(').reverse();
        let settingCode = valueArr[0].replace(')', '');

        this.verifySetting(settingCode);
      }
    });

    this.filteredCountries = this.formGroup.controls['country'].valueChanges.pipe(
      startWith(''),
      map(value => this._filterCountries(value || ''))
    );

    this.filteredStates = this.formGroup.controls['federalEntity'].valueChanges.pipe(
      startWith(''),
      map(value => this._filterStates(value || ''))
    );

    this.filteredCities = this.formGroup.controls['city'].valueChanges.pipe(
      startWith(''),
      map(value => this._filterCities(value || ''))
    );

    this.filteredTowns = this.formGroup.controls['town'].valueChanges.pipe(
      startWith(''),
      map(value => this._filterTowns(value || ''))
    );

    this.filteredSettings = this.formGroup.controls['suburb'].valueChanges.pipe(
      startWith(''),
      map(value => this._filterSettings(value || ''))
    );

    this.filteredTaxRegime = this.formGroup.controls['taxReference'].valueChanges.pipe(
      startWith(''),
      map(value => this._filterTaxRegime(value || ''))
    );

    this.filteredLadas1 = this.formGroup.controls['lada1'].valueChanges.pipe(
      startWith(''),
      map(value => this._fiterLada1(value || ''))
    );

    this.filteredLadas2 = this.formGroup.controls['lada2'].valueChanges.pipe(
      startWith(''),
      map(value => this._fiterLada1(value || ''))
    );
  }

  private _filterCountries(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.countriesStr.filter(item => item.toLowerCase().includes(filterValue));
  }

  private _filterStates(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.countryStatesStr.filter(item => item.toLowerCase().includes(filterValue));
  }

  private _filterCities(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.stateCitiesStr.filter(item => item.toLowerCase().includes(filterValue));
  }

  private _filterTowns(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.cityTownsStr.filter(item => item.toLowerCase().includes(filterValue));
  }

  private _filterSettings(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.citySettingsStr.filter(item => item.toLowerCase().includes(filterValue));
  }

  private _filterTaxRegime(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.taxRegimeStr.filter(item => item.toLowerCase().includes(filterValue));
  }

  private _fiterLada1(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.ladasStr.filter(item => item.toLowerCase().includes(filterValue));
  }

  async getSpecialties(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let specialties: SpecialtiesListResponse = await lastValueFrom(this._interventionService.getSpecialties(idUser, 1));

      this.hasError = specialties.error;
      this.errorStr = specialties.msg;

      if(!this.hasError){
        let specialtiesArr: SpecialtiesListItem[] = [];
        for(const specialty  of specialties.response){
          let codeDec = await this._encService.decrypt(specialty.CODIGO_ESPECIALIDAD);
          specialty.NOMBRE_ESPECIALIDAD = `${codeDec} - ${specialty.NOMBRE_ESPECIALIDAD}`;

          if(specialty.ESTADO == 'Activo'){
            specialtiesArr.push(specialty);
          }
        }

        this.specialties = specialtiesArr;
      }
    }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;
    }
  }

  private async getCountries() {
    const idUser: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._sysAdminService.getCountriesList(idUser, line)).then(
      async ( responseData: CountriesListResponse ) => {
        if (!responseData.error) {
          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.resourcesService.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.getCountries();
        }
      }
    );
  }

  private async getTaxRegime(){
    
    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.taxRegime = responseData.response;
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getTaxRegime();
        }
      }
    );
  }

  private async getDataForm() {
    try{
      if (this.typeFormSubcontract.idSubcontract === null && this.typeFormSubcontract.type === 'UPD') {
        this.resourcesService.openSnackBar(`Ocurrió un error al obtener los datos del subcontratista`);
        return;
      } else if (this.typeFormSubcontract.idSubcontract !== null && this.typeFormSubcontract.type === 'UPD') {
        const ID_SUBCONTRACT: string = this.typeFormSubcontract.idSubcontract.toString();
        const USER: string = this.resourcesService.getUser();
        const LINE: number = this.resourcesService.getLineNumber();

        let responseData: ResponseDataSubcontratist = await lastValueFrom(this._subcontratistService.getSubcontratistById(
          ID_SUBCONTRACT, 
          USER, 
          LINE
        ));

        this.hasError = responseData.error;
        this.errorStr = responseData.msg;

        if(!this.hasError){
            
          this.formGroup.controls['socialReason'].setValue(responseData.response.SOCIAL_REASON);

          this.formGroup.controls['contractType'].setValue(responseData.response.CONTRACT_TYPE);
          if(responseData.response.CONTRACT_TYPE == 'Persona moral'){
            let moralTaxRegime = this.taxRegime.filter(item => item.APPLY_MORAL == 'Sí');
            moralTaxRegime.forEach(item => {
              this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`);
            });
          }else{
            let phisicTaxRegime = this.taxRegime.filter(item => item.APPLY_PHISIC == 'Sí');
            phisicTaxRegime.forEach(item => {
              this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`);
            });
          }
          this.formGroup.controls['taxReference'].enable();
          
          this.formGroup.controls['taxReference'].setValue(responseData.response.TAX_REFERENCE);
          this.formGroup.controls['foreigner'].setValue(responseData.response.FOREIGNER);

          if(responseData.response.FOREIGNER == 'Si'){
            this.formGroup.controls['tax'].enable();
            this.formGroup.controls['tax'].setValue(responseData.response.TAX);
          }else{
            this.formGroup.controls['RFC'].enable();
            this.formGroup.controls['RFC'].setValue(responseData.response.RFC);
          }

          this.formGroup.controls['email'].setValue(responseData.response.EMAIL);
          this.formGroup.controls['country'].enable();
          this.formGroup.controls['country'].setValue(responseData.response.COUNTRY);
          this.formGroup.controls['federalEntity'].setValue(responseData.response.FEDERAL_ENTITY);

          if(responseData.response.CITY != null){
            this.formGroup.controls['city'].setValue(responseData.response.CITY);
          }else{
            this.formGroup.controls['city'].setValue('Sin municipio');
          }

          if(responseData.response.TOWN != null){
            this.formGroup.controls['town'].setValue(responseData.response.TOWN);
          }else{
            this.formGroup.controls['town'].setValue('Sin localidad');
          }

          this.formGroup.controls['suburb'].setValue(responseData.response.SUBURB);
          this.formGroup.controls['postalCode'].setValue(responseData.response.POSTAL_CODE);
          this.formGroup.controls['street'].setValue(responseData.response.STREET);
          this.formGroup.controls['exteriorNumber'].setValue(responseData.response.EXTERIOR_NUMBER);
          this.formGroup.controls['interiorNumber'].setValue(responseData.response.INTERIOR_NUMBER);

          let countryArr = responseData.response.COUNTRY.split('(').reverse()!;
          let countryStr = countryArr[0].replace(')', '');
          let country = this.countries.filter(item => item.COUNTRY_ID == countryStr);
          let countryCode = country[0].NOMECLARUTA_ISO2;


          this.formGroup.controls['telephone1'].setValue(responseData.response.TELEPHONE1);
          let arrLada1 = this.countries.find((element) => element.LADA === responseData.response.LADA1)
          if (arrLada1 === undefined) {
            this.formGroup.controls['lada1'].setValue(responseData.response.LADA1);
          } else {
            this.formGroup.controls['lada1'].setValue(`${arrLada1.LADA}-${arrLada1.NOMECLARUTA_ISO2}`);
          }
          
          this.formGroup.controls['telephone2'].setValue(responseData.response.TELEPHONE2);
          if(responseData.response.LADA2 !== null){
            let arrLada2 = this.countries.find((element) => element.LADA === responseData.response.LADA2)
            if (arrLada2 === undefined) {
              this.formGroup.controls['lada2'].setValue(responseData.response.LADA1);
            } else {
              this.formGroup.controls['lada2'].setValue(`${arrLada2.LADA}-${arrLada2.NOMECLARUTA_ISO2}`);
          }
          }else{
            this.formGroup.controls['lada2'].setValue(null);
            this.formGroup.controls['telephone2'].setValue(null);
          }

          let specialtiesArr: string[] = JSON.parse(responseData.response.SPECIALTY);
          let selectedSpecialties: string[] = [];
          for(const specialty of specialtiesArr){
            let specialtyDec = await this._encService.decrypt(specialty);
            let specialtyArr = specialtyDec.split(' - ');

            selectedSpecialties.push(specialtyArr[0]);
          }

          for(const specialty of this.specialties){
            let codeDec = await this._encService.decrypt(specialty.CODIGO_ESPECIALIDAD);
            if(selectedSpecialties.includes(codeDec)){
              let specialtiesVal = this.formGroup.controls['specialty'].value;
              specialtiesVal.push(specialty.CODIGO_ESPECIALIDAD);
          
              this.formGroup.controls['specialty'].setValue(specialtiesVal);
            }
          }
        }
      } else if (this.typeFormSubcontract.idSubcontract === null && this.typeFormSubcontract.idProvider !== null && this.typeFormSubcontract.type === 'REG') {
        await this.setInformationProvider(this.typeFormSubcontract.idProvider);
      }
    }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;
    }
  }

  private async setInformationProvider(idProvider:string) {
    const user: string = this.resourcesService.getUser();
    const line: number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._providerService.getProviderByNumber(idProvider, user, line)).then(
      async (responseData: ResponseDataGetProvidersById) => {
        if (!responseData.error) {
          
          this.formGroup.controls['socialReason'].setValue(responseData.response.RAZON_SOCIAL);
          this.formGroup.controls['socialReason'].disable();
          this.formGroup.controls['contractType'].setValue(responseData.response.TIPO_CONTRIBUYENTE);
          this.formGroup.controls['contractType'].disable();
          this.onchangeType();

          let taxRegime:string = '';          
          this.taxRegime.forEach((element: TaxRegimeList)=> {
            if ( parseInt(element.TAX_REGIME_KEY) === parseInt(responseData.response.NUMERO_REGIMEN_FISCAL)) {              
              taxRegime = `${element.TAX_REGIME_DESC} (${element.TAX_REGIME_KEY})`
            }
          });
          
          this.formGroup.controls['taxReference'].setValue(taxRegime);
          this.formGroup.controls['taxReference'].disable();
          let tipo:string = responseData.response.TIPO === 'Nacional' ? 'No' : 'Si';
          this.formGroup.controls['foreigner'].setValue(tipo);
          this.formGroup.controls['foreigner'].disable();
          this.formGroup.controls['RFC'].setValue(responseData.response.RFC);
          this.formGroup.controls['RFC'].disable();
          this.formGroup.controls['tax'].setValue(responseData.response.TAXID);
          this.formGroup.controls['tax'].disable();
          this.formGroup.controls['email'].setValue(responseData.response.CORREO);
          this.formGroup.controls['email'].disable();
          
          this.formGroup.controls['street'].setValue(responseData.response.CALLE);
          this.formGroup.controls['street'].disable();
          this.formGroup.controls['exteriorNumber'].setValue(responseData.response.EXTERIOR);
          this.formGroup.controls['exteriorNumber'].disable();
          this.formGroup.controls['interiorNumber'].setValue(responseData.response.INTERIOR);
          this.formGroup.controls['interiorNumber'].disable();
          this.formGroup.controls['postalCode'].setValue(responseData.response.CODIGO_POSTAL);
          this.formGroup.controls['postalCode'].disable();

          if (tipo === 'No') {      
            await this.searchAddressByZipCode(this.formGroup.controls['postalCode'].value);
          } else {
            
            this.formGroup.controls['town'].setValue(responseData.response.LOCALIDAD);
            this.formGroup.controls['city'].setValue(responseData.response.MUNICIPIO);
            this.formGroup.controls['federalEntity'].setValue(responseData.response.ENTIDAD_FEDERATIVA);
            this.formGroup.controls['country'].setValue(responseData.response.PAIS);
          }

          let city = this.citySettingsStr.find((element) => element.split('(')[1].split(')')[0] === responseData.response.COLONIA );
          if (city === undefined) {
            city = responseData.response.COLONIA;
          }
          
          this.formGroup.controls['suburb'].setValue(city);
          this.formGroup.controls['suburb'].disable();
          this.formGroup.controls['country'].disable();          
          
          this.formGroup.controls['telephone1'].setValue(responseData.response.TELEFONO1);
          this.formGroup.controls['telephone1'].disable();
          
          let lada1 = this.countries.find((element) => element.LADA === responseData.response.LADA1);
          if (lada1 === undefined) {
            this.resourcesService.openSnackBar(`Ocurrió un error al obtener el campo Lada 1`);
            return;
          }
          this.formGroup.controls['lada1'].setValue( `${lada1.LADA}-${lada1.NOMECLARUTA_ISO2}` );
          this.formGroup.controls['lada1'].disable();
          this.formGroup.controls['telephone2'].setValue(responseData.response.TELEFONO2);
          this.formGroup.controls['telephone2'].disable();

          let lada2 = null;          
          if (responseData.response.LADA2 !== null) {
            lada2 = this.countries.find((element) => element.LADA === responseData.response.LADA2);
            if (lada2 === undefined) {
              this.resourcesService.openSnackBar(`Ocurrió un error al obtener el campo Lada 2`);
              return;
            }
            this.formGroup.controls['lada2'].setValue( `${lada2.LADA}-${lada2.NOMECLARUTA_ISO2}` );
          }
          

          this.formGroup.controls['lada2'].disable();
        } else {
          this.resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.setInformationProvider(idProvider);
        }
      }
    );
  }

  public onchangeType() {
    let contractType = this.formGroup.controls['contractType'].value;
    if(contractType == "Persona moral"){
      let moralTaxRegime = this.taxRegime.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.formGroup.controls['taxReference'].enable();
      this.formGroup.controls['RFC'].setValidators([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])$/)), Validators.maxLength(12), Validators.minLength(12)]);
      this.formGroup.controls['tax'].setValidators([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])$/)), Validators.maxLength(12), Validators.minLength(12)]);
    }else{
      let phisicTaxRegime = this.taxRegime.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.formGroup.controls['taxReference'].enable();
      this.formGroup.controls['RFC'].setValidators([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])$/)), Validators.maxLength(13), Validators.minLength(13)])
      this.formGroup.controls['tax'].setValidators([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])$/)), Validators.maxLength(13), Validators.minLength(13)])
    }
    
    this.formGroup.controls['RFC'].setValue(null);
    this.formGroup.controls['tax'].setValue(null);
    this.formGroup.controls['taxReference'].setValue(null);
    
  }

  async searchAddressByZipCode(zipCode: string){
    try{
      if(!this.enableSearchByZipCode) return;

      this.searchingAddress = true;

      let idUser = localStorage.getItem('idusuario')!;
      let zipCodeEnc = await this._encService.encrypt(zipCode);
      let address: AddressByZipCodeResponse = await lastValueFrom(this._sysAdminService.getAddressByZipCode(
        zipCodeEnc,
        idUser,
        1
      ))

      if(address.error){
        this.resourcesService.openSnackBar(address.msg);
      }else{
        let countryInput = this._document.getElementById('country') as HTMLInputElement;
        let countryVal = countryInput.value;
        
        if(countryVal == '' || countryVal == null || countryVal == undefined){
          countryInput.value = 'México (MEX)';
          this.formGroup.controls['country'].setValue('México (MEX)', {
            emitValue: false,
          });

          let stateInput = this._document.getElementById('state') as HTMLInputElement;
          stateInput.value = `${address.response.NOMBRE_ESTADO} (${address.response.CODIGO_ESTADO})`;

          let cityInput = this._document.getElementById('city') as HTMLInputElement;
          if(address.response.CODIGO_MUNICIPIO == null){
            cityInput.value = 'Sin municipio';
          }else{
            cityInput.value = `${address.response.NOMBRE_MUNICIPIO} (${address.response.CODIGO_MUNICIPIO})`;
          }
      
          let townInput = this._document.getElementById('town') as HTMLInputElement;
          if(address.response.CODIGO_LOCALIDAD == null){
            townInput.value = 'Sin localidad';
          }else{
            townInput.value = `${address.response.NOMBRE_LOCALIDAD} (${address.response.CODIGO_LOCALIDAD})`;
          }

          if(address.response.COLONIAS.length > 0){
            address.response.COLONIAS.forEach(item => {
              let setting: CitySettings = {
                CODIGOCOLONIA: item.CODIGO_COLONIA,
                CODIGOPOSTAL: zipCode,
                NOMBRECOLONIA: item.NOMBRE_COLONIA,
              };

              this.citySettings.push(setting);
              this.citySettingsStr.push(`${item.NOMBRE_COLONIA} (${item.CODIGO_COLONIA})`);

              this.formGroup.controls['suburb'].enable();
            });
          }else{
            let settingInput = this._document.getElementById('setting') as HTMLInputElement;
            settingInput.value = 'Sin colonia';
          }
        }
      }

      this.searchingAddress = 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.searchingAddress = false;
    }
  }

  verifyState(value: string){
    let countryVal = this.formGroup.controls['country'].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.formGroup.controls['city'].enable();
    }
  }

  async searchStateCities(stateCode: string){
    try{
      this.searchingCities = true;
      
      let idUser = localStorage.getItem('idusuario')!;
      let stateCodeEnc = await this._encService.encrypt(stateCode);
      let cities: StateCitiesResponse = await lastValueFrom(this._sysAdminService.getCitiesByStateCode(
        stateCodeEnc,
        idUser,
        1
      ));

      if(!cities.error){
        this.stateCities = cities.response;
        this.stateCitiesStr = [];

        this.stateCities.forEach(item => {
          this.stateCitiesStr.push(`${item.NOMBREMUNICIPIO} (${item.CODIGOMUNICIPIO})`);
        });

        this.formGroup.controls['city'].enable();
      }
      
      this.searchingCities = 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.searchingCities = false;
    }
  }

  verifyCity(value: string){
    let stateVal = this.formGroup.controls['federalEntity'].value;
    let stateArr = stateVal.split('(').reverse();
    let stateCode = stateArr[0].replace(')', '');
    
    this.cityTowns = [];
    this.cityTownsStr = [];
    this.citySettings = [];
    this.citySettingsStr = [];
    
    this.searchStateTowns(stateCode, value);
  }

  async searchStateTowns(stateCode: string, cityCode: string){
    try{
      this.searchingTowns = true;
      
      let idUser = localStorage.getItem('idusuario')!;
      let stateCodeEnc = await this._encService.encrypt(stateCode);
      let cityCodeEnc = await this._encService.encrypt(cityCode);
      let towns: CityTownsResponse = await lastValueFrom(this._sysAdminService.getTowns(
        stateCodeEnc,
        cityCodeEnc,
        idUser,
        1
      ));

      if(!towns.error){
        this.cityTownsStr = [];
        this.cityTowns = towns.response;

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

        if(towns.response.length > 1){
          this.formGroup.controls['town'].enable();
        }else if(towns.response.length == 1 && towns.response[0].CODIGOLOCALIDAD != null){
          this.formGroup.controls['town'].enable();
        }else{
          this.formGroup.controls['town'].disable();
          this.formGroup.controls['town'].setValue('Sin localidad');
        }
      }
      
      this.searchingTowns = 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.searchingTowns = false;
    }
  }

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

    let cityVal = this.formGroup.controls['city'].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);
  }

  async searchCitySettings(stateCode: string, cityCode: string, townCode: string){
    try{
      this.searchingSettings = true;

      let idUser = localStorage.getItem('idusuario')!;
      let stateCodeEnc = await this._encService.encrypt(stateCode);
      let cityCodeEnc = await this._encService.encrypt(cityCode);
      let townCodeEnc = await this._encService.encrypt(townCode);
      let settings: CitySettingsResponse = await lastValueFrom(this._sysAdminService.getCitySettings(
        stateCodeEnc,
        cityCodeEnc,
        townCodeEnc,
        idUser,
        1
      ));
      
      if(!settings.error){
        this.citySettings = settings.response;
        this.citySettingsStr = [];

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

        this.formGroup.controls['suburb'].enable();
      }

      this.searchingSettings = 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.searchingSettings = false;
    }
  }

  verifySetting(value: string){
    let settingValid = this.citySettings.filter(item => item.CODIGOCOLONIA == value);
    if(settingValid.length > 0){
      this.formGroup.controls['postalCode'].setValue(settingValid[0].CODIGOPOSTAL);
    }
  }

  // Método para reajustar los botones según sus dimensiones
  public onResize(): void {
    this.btnSmall = window.innerWidth <= 1405;
    this.screenSize = window.innerWidth;
  }

  public changeNationality() {
    let foreigner = this.formGroup.controls['foreigner'].value;
    this.formGroup.controls['country'].enable();
    if(foreigner == 'Si'){
      this.formGroup.controls['RFC'].disable();
      this.formGroup.controls['RFC'].setValue(null);
      this.formGroup.controls['tax'].enable();
    }else{
      this.formGroup.controls['tax'].disable();
      this.formGroup.controls['tax'].setValue(null);
      this.formGroup.controls['RFC'].enable();
    }
  }

  checkIfAddress(value: string){
    if(this.formGroup.controls['foreigner'].value == 'Si' && value == 'México (MEX)') return;
    if(this.formGroup.controls['foreigner'].value == 'No' && value != 'México (MEX)') return;

    let validValue = this.countriesStr.filter(item => item == value);
    this.formGroup.controls['postalCode'].setValue('', {
      emitEvent: false,
    });

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

      this.formGroup.controls['postalCode'].disable();
      this.enableSearchByZipCode = false;
      this.verifyCountry(countryCode);
    }else{
      this.formGroup.controls['federalEntity'].setValue('');
      this.formGroup.controls['federalEntity'].disable();
      this.formGroup.controls['city'].setValue('');
      this.formGroup.controls['city'].disable();
      this.formGroup.controls['town'].setValue('');
      this.formGroup.controls['town'].disable();
      this.formGroup.controls['suburb'].setValue('');
      this.formGroup.controls['suburb'].disable();

      this.formGroup.controls['postalCode'].enable();
      this.enableSearchByZipCode = true;
    }
  }

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

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

    if(countryCode == 'CAN' || countryCode == 'MEX' || countryCode == 'USA'){
      this.searchCountryStates(countryCode);
    }else{
      this.formGroup.controls['federalEntity'].enable();
    }
  }

  async searchCountryStates(contryCode: string){
    try{
      this.searchingStates = true;

      let idUser = localStorage.getItem('idusuario')!;
      let countryCodeEnc = await this._encService.encrypt(contryCode);
      let states: CountryStatesResponse = await lastValueFrom(this._sysAdminService.getStatesByCountryCode(
        countryCodeEnc,
        idUser,
        1
      ));
    
      if(!states.error){
        this.countryStatesStr = [];
        this.countryStates = states.response;

        this.countryStates.forEach(item => {
          this.countryStatesStr.push(`${item.NOMBREESTADO} (${item.CODIGOESTADO})`);
        });

        this.formGroup.controls['federalEntity'].enable();
      }

      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;
    }
  }

  searchZipCode(value: string){
    let valArr = value.split('');
    let validChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    let validVal = "";

    valArr.forEach(char => {
      if(validChars.includes(char)){
        validVal += char;
      }
    });

    let zipCodeInput = this._document.getElementById('zipCode') as HTMLInputElement;
    
    if(validVal.length < 5 && this.enableSearchByZipCode){
      zipCodeInput.value = validVal;
      
      let countryInput = this._document.getElementById('country') as HTMLInputElement;
      countryInput.value = '';
      
      let stateInput = this._document.getElementById('state') as HTMLInputElement;
      stateInput.value = '';
      
      let cityInput = this._document.getElementById('city') as HTMLInputElement;
      cityInput.value = '';
      
      let townInput = this._document.getElementById('town') as HTMLInputElement;
      townInput.value = '';

      let settingInput = this._document.getElementById('setting') as HTMLInputElement;
      settingInput.value = '';

      this.citySettings = [];
      this.citySettingsStr = [];
    }else{
      let finalVal = validVal.substring(0, 5);
      zipCodeInput.value = finalVal;

      this.searchAddressByZipCode(finalVal);
    }
  }

  public alert() {
    let invalidForm = this.formGroup.invalid;
    if(invalidForm){
      this.resourcesService.openSnackBar("Algunos datos del formulario son inválidos.");
      this.formGroup.markAllAsTouched();
    }else if (this.typeFormSubcontract.type === 'REG') {
      this._dialog.open(AlertComponent, {
        data: {
          title: 'Registrar Subcontratista',
          description: '¿Está seguro que desea registrar al subcontratista?',
          icon: 'warning',
        },
        disableClose: true,
      }).afterClosed().subscribe((result) => {
        if (result) {
          this.storeSubcontratist();
        }
      });
    } else if (this.typeFormSubcontract.type === 'UPD') {
      this._dialog.open(AlertComponent, {
        data: {
          title: 'Actualizar Subcontratista',
          description: '¿Está seguro que desea actualizar al subcontratista?',
          icon: 'warning',
        },
        disableClose: true,
      }).afterClosed().subscribe((result) => {
        if (result) {
          this.updateSubcontratist();
        }
      });
    }

  }

  private async storeSubcontratist() {
    try{
      let formValue = this.formGroup.getRawValue();
      let formData = new FormData();
      let idUser = localStorage.getItem('idusuario');
  
      formData.append('linea', '1');
      formData.append('id_user', idUser!);
      formData.append('SOCIAL_REASON', formValue.socialReason.trim());
  
      let foreigner = formValue.foreigner.trim();
      let taxRegime = formValue.taxReference;
      let taxRegimeArr = taxRegime.split("(").reverse();
      let taxRegimeCode = taxRegimeArr[0].replace(')', '').trim();
      let validTaxRegime = this.taxRegimeStr.filter(item => item == taxRegime);
  
      if(validTaxRegime.length == 0){
        this.resourcesService.openSnackBar(`El régimen fiscal ${taxRegime} no se encuentra registrado en el catálogo de Régimen Fiscal del SAT.`);
        this.formGroup.controls['taxReference'].setValue(null);
        return;
      }
  
      formData.append('TAX_REFERENCE', taxRegimeCode);
      formData.append('CONTRACT_TYPE', formValue.contractType.trim());
      formData.append('FOREIGNER', foreigner);
  
      let rfcEnc = formValue.RFC == null ? '' : await this._encService.encrypt(formValue.RFC);
      let taxEnc = formValue.tax == null ? '' : await this._encService.encrypt(formValue.tax);
      let emailEnc = await this._encService.encrypt(formValue.email);
  
      formData.append('RFC', rfcEnc);
      formData.append('TAX', taxEnc);
      formData.append('EMAIL', emailEnc);
  
      let country = formValue.country;      
      let countryArr = country.split('(').reverse();
      let countryCode = countryArr[0].replace(')', '').trim();
      let validCountry = this.countriesStr.filter(item => item == country);
  
      if(validCountry.length == 0){
        this.resourcesService.openSnackBar(`El país ${country} no se encuentra registrado en el catálogo de Paises del SAT.`);
        this.formGroup.controls['country'].setValue(null);
        return;
      }
  
      formData.append('COUNTRY', countryCode);
      if(countryCode == 'MEX' || countryCode == 'USA' || countryCode == 'CAN'){
        let stateCode = "";
  
        if(this.enableSearchByZipCode){
          let stateInput = this._document.getElementById('state') as HTMLInputElement;
          let state = stateInput.value;
          let stateArr = state.split('(').reverse();
          stateCode = stateArr[0].replace(')', '').trim();
        }else{
          let state = formValue.federalEntity;
          let stateArr = state.split('(').reverse();
          stateCode = stateArr[0].replace(')', '').trim();
  
          let validState = this.countryStatesStr.filter(item => item == state);
  
          if(validState.length == 0){
            this.resourcesService.openSnackBar(`El estado ${state} no está asociado al país ${country}.`);
            this.formGroup.controls['federalEntity'].setValue(null);
            return;
          }
        }
  
        formData.append('FEDERAL_ENTITY', stateCode);
        if(countryCode == 'MEX'){
          let cityCode = "";
  
          if(this.enableSearchByZipCode){
            let cityInput = this._document.getElementById('city') as HTMLInputElement;
  
            if(cityInput.value == 'Sin municipio'){
              cityCode = '-';
            }else{
              let city = cityInput.value;
              let cityArr = city.split('(').reverse();
              cityCode = cityArr[0].replace(')', '').trim();
            }
          }else{
            let city = formValue.city;
  
            if(city == 'Sin municipio'){
              cityCode = '-';
            }else{
              let cityArr = city.split('(').reverse();
              cityCode = cityArr[0].replace(')', '').trim();
              let validCity = this.stateCitiesStr.filter(item => item == city);
  
              if(validCity.length == 0){
                this.resourcesService.openSnackBar(`La ciudad ${city} no se encuentra asociada al estado ${stateCode}.`);
                this.formGroup.controls['city'].setValue(null);
                return;
              }
            }
          }
  
          formData.append('CITY', cityCode);
          let townCode = "";
  
          if(this.enableSearchByZipCode){
            let townInput = this._document.getElementById('town') as HTMLInputElement;
  
            if(townInput.value == 'Sin localidad'){
              townCode = '-';
            }else{
              let town = townInput.value;
              let townArr = town.split('(').reverse();
              townCode = townArr[0].replace(')', '').trim();
            }
          }else{
            let town = formValue.town;
  
            if(town == 'Sin localidad'){
              townCode = '-';
            }else{
              let townArr = town.split('(').reverse();
              townCode = townArr[0].replace(')', '').trim();
              let validTown = this.cityTownsStr.filter(item => item == town);
  
              if(validTown.length == 0){
                this.resourcesService.openSnackBar(`La localidad ${town} no se encuentra asociada a la ciudad ${cityCode}.`);
                this.formGroup.controls['town'].setValue(null);
                return;
              }
            }
          }
  
          formData.append('TOWN', townCode);
          let setting = formValue.suburb;          
          let settingCode = '';
          if (formValue.foreigner === 'No') {
            let settingArr = setting.split('(').reverse();
            settingCode = settingArr[0].replace(')', '').trim();
            let validSetting = this.citySettingsStr.filter(item => item == setting);
            if(validSetting.length == 0){
              this.resourcesService.openSnackBar(`###: La colonia ${setting} no se encuentra relacionada a la ciudad ${cityCode}.`);
              this.formGroup.controls['suburb'].setValue(null);
              return;
            }
          } else {
            settingCode = setting;
          }

          formData.append('SUBURB', settingCode);
        }else{
          let townExt = '-';
          if(formValue.town != '' && formValue.town != null && formValue.town != undefined){
            townExt = formValue.town;
          }

          formData.append('CITY', formValue.city);
          formData.append('TOWN', townExt);
          formData.append('SUBURB', formValue.suburb);
        }
  
        formData.append('POSTAL_CODE', formValue.postalCode);
      }else{
        let townExt = '-';
        if(formValue.town != '' && formValue.town != null && formValue.town != undefined){
          townExt = formValue.town;
        }

        formData.append('FEDERAL_ENTITY', formValue.federalEntity);
        formData.append('CITY', formValue.city);
        formData.append('TOWN', townExt);
        formData.append('SUBURB', formValue.suburb);
        formData.append('POSTAL_CODE', formValue.postalCode);
      }
  
      let intNum = '0';
      if(formValue.interiorNumber != '' && formValue.interiorNumber != null && formValue.interiorNumber != undefined){
        intNum = formValue.interiorNumber;
      }

      formData.append('STREET', formValue.street);
      formData.append('EXTERIOR_NUMBER', formValue.exteriorNumber);
      formData.append('INTERIOR_NUMBER', intNum);
  

      let lada1 = formValue.lada1;
      let lada1Arr = lada1.split('-');
      lada1Arr.pop();

      let lada1Val = lada1Arr.join('-');
      let validLada1 = this.ladasStr.filter(item => lada1 == item);
      let phone1 = await this._encService.encrypt(`${formValue.telephone1}`);
  
      if(validLada1.length == 0){
        this.resourcesService.openSnackBar(`La lada ${lada1} no se encuentra asociada a ningún país.`);
        this.formGroup.controls['lada1'].setValue(null);
        return;
      }
  
      formData.append('LADA1', lada1Val);
      formData.append('TELEPHONE1', phone1);
  
      if(formValue.lada2 != '' && formValue.lada2 != null && formValue.lada2 != undefined){
        let lada2 = formValue.lada2;
        let lada2Arr = lada2.split('-');
        lada2Arr.pop();

        let lada2Val = lada2Arr.join('-');
        let validLada2 = this.ladasStr.filter(item => lada2 == item);
        let phone2 = await this._encService.encrypt(`${formValue.telephone2}`);
  
        if(validLada2.length == 0){
          this.resourcesService.openSnackBar(`La lada ${lada2} no se encuentra asociada a ningún país.`);
          this.formGroup.controls['lada2'].setValue(null);
          return;
        }
        
        formData.append('LADA2', lada2Val);
        formData.append('TELEPHONE2', phone2);
      }else{
        formData.append('LADA2', '-');
        formData.append('TELEPHONE2', '-');
      }
      
      let specialtiesStr = JSON.stringify(formValue.specialty);
      formData.append('SPECIALTY', specialtiesStr);

      if (this.typeFormSubcontract.idProvider !== null) {
        formData.append('PROVIDER', this.typeFormSubcontract.idProvider);
      }
      
      this.isLoadingForm = true;
      await lastValueFrom(this._subcontratistService.storeSubcontratist(formData)).then(
        (responseData: ResponseData) => {
          if (!responseData.error) {
            if (this.typeFormSubcontract.idProvider === null && this.typeFormSubcontract.idSubcontract === null) {
              this._socketService.registerSubcontract(responseData.response.idSubcontract);
            }
            this.resourcesService.openSnackBar("El subcontratista se registró correctamente.");
            this.goBack(1);
          } else {
            this.resourcesService.openSnackBar(`${responseData.msg}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.storeSubcontratist();
          }
        }
      );
      
      this.isLoadingForm = 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.isLoadingForm = false;
    }
  }

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

  private async updateSubcontratist() {
    try{
      let formValue = this.formGroup.getRawValue();
      let formData = new FormData();
      let idUser = localStorage.getItem('idusuario');
      let idSubEnc = `${this.typeFormSubcontract.idSubcontract}`;
  
      formData.append('linea', '1');
      formData.append('id_user', idUser!);
      formData.append('id_subcontratist', idSubEnc);
      formData.append('SOCIAL_REASON', formValue.socialReason.trim());
  
      let foreigner = formValue.foreigner.trim();
      let taxRegime = formValue.taxReference;
      let taxRegimeArr = taxRegime.split("(").reverse();
      let taxRegimeCode = taxRegimeArr[0].replace(')', '').trim();
      let validTaxRegime = this.taxRegimeStr.filter(item => item == taxRegime);
  
      if(validTaxRegime.length == 0){
        this.resourcesService.openSnackBar(`El régimen fiscal ${taxRegime} no se encuentra registrado en el catálogo de Régimen Fiscal del SAT.`);
        this.formGroup.controls['taxReference'].setValue(null);
        return;
      }
  
      formData.append('TAX_REFERENCE', taxRegimeCode);
      formData.append('CONTRACT_TYPE', formValue.contractType.trim());
      formData.append('FOREIGNER', foreigner);
  
      let rfcEnc = formValue.RFC == null ? '' : await this._encService.encrypt(formValue.RFC);
      let taxEnc = formValue.tax == null ? '' : await this._encService.encrypt(formValue.tax);
      let emailEnc = await this._encService.encrypt(formValue.email);
  
      formData.append('RFC', rfcEnc);
      formData.append('TAX', taxEnc);
      formData.append('EMAIL', emailEnc);
  
      let country = formValue.country;
      let countryArr = country.split('(').reverse();
      let countryCode = countryArr[0].replace(')', '').trim();
      let validCountry = this.countriesStr.filter(item => item == country);
  
      if(validCountry.length == 0){
        this.resourcesService.openSnackBar(`El país ${country} no se encuentra registrado en el catálogo de Paises del SAT.`);
        this.formGroup.controls['country'].setValue(null);
        return;
      }
  
      formData.append('COUNTRY', countryCode);
      if(countryCode == 'MEX' || countryCode == 'USA' || countryCode == 'CAN'){
        let stateCode = "";
  
        if(this.enableSearchByZipCode){
          let stateInput = this._document.getElementById('state') as HTMLInputElement;
          let state = stateInput.value;
          let stateArr = state.split('(').reverse();
          stateCode = stateArr[0].replace(')', '').trim();
        }else{
          let state = formValue.federalEntity;
          let stateArr = state.split('(').reverse();
          stateCode = stateArr[0].replace(')', '').trim();
  
          let validState = this.countryStatesStr.filter(item => item == state);
  
          if(validState.length == 0){
            this.resourcesService.openSnackBar(`El estado ${state} no está asociado al país ${country}.`);
            this.formGroup.controls['federalEntity'].setValue(null);
            return;
          }
        }
  
        formData.append('FEDERAL_ENTITY', stateCode);
        if(countryCode == 'MEX'){
          let cityCode = "";
  
          if(this.enableSearchByZipCode){
            let cityInput = this._document.getElementById('city') as HTMLInputElement;
  
            if(cityInput.value == 'Sin municipio'){
              cityCode = '-';
            }else{
              let city = cityInput.value;
              let cityArr = city.split('(').reverse();
              cityCode = cityArr[0].replace(')', '').trim();
            }
          }else{
            let city = formValue.city;
  
            if(city == 'Sin municipio'){
              cityCode = '-';
            }else{
              let cityArr = city.split('(').reverse();
              cityCode = cityArr[0].replace(')', '').trim();
              let validCity = this.stateCitiesStr.filter(item => item == city);
  
              if(validCity.length == 0){
                this.resourcesService.openSnackBar(`La ciudad ${city} no se encuentra asociada al estado ${stateCode}.`);
                this.formGroup.controls['city'].setValue(null);
                return;
              }
            }
          }
  
          formData.append('CITY', cityCode);
          let townCode = "";
  
          if(this.enableSearchByZipCode){
            let townInput = this._document.getElementById('town') as HTMLInputElement;
  
            if(townInput.value == 'Sin localidad'){
              townCode = '-';
            }else{
              let town = townInput.value;
              let townArr = town.split('(').reverse();
              townCode = townArr[0].replace(')', '').trim();
            }
          }else{
            let town = formValue.town;
  
            if(town == 'Sin localidad'){
              townCode = '-';
            }else{
              let townArr = town.split('(').reverse();
              townCode = townArr[0].replace(')', '').trim();
              let validTown = this.cityTownsStr.filter(item => item == town);
  
              if(validTown.length == 0){
                this.resourcesService.openSnackBar(`La localidad ${town} no se encuentra asociada a la ciudad ${cityCode}.`);
                this.formGroup.controls['town'].setValue(null);
                return;
              }
            }
          }
  
          formData.append('TOWN', townCode);
          let setting = formValue.suburb;
          let settingArr = setting.split('(').reverse();
          let settingCode = settingArr[0].replace(')', '').trim();
          let validSetting = this.citySettingsStr.filter(item => item == setting);
  
          if(validSetting.length == 0 && this.formGroup.controls['suburb'].enabled){
            this.resourcesService.openSnackBar(`La colonia ${setting} no se encuentra relacionada a la ciudad ${cityCode}.`);
            this.formGroup.controls['suburb'].setValue(null);
            return;
          }
  
          formData.append('SUBURB', settingCode);
        }else{
          let townExt = '-';
          if(formValue.town != '' && formValue.town != null && formValue.town != undefined){
            townExt = formValue.town;
          }

          formData.append('CITY', formValue.city);
          formData.append('TOWN', townExt);
          formData.append('SUBURB', formValue.suburb);
        }
  
        formData.append('POSTAL_CODE', formValue.postalCode);
      }else{
        let townExt = '-';
        if(formValue.town != '' && formValue.town != null && formValue.town != undefined){
          townExt = formValue.town;
        }

        formData.append('FEDERAL_ENTITY', formValue.federalEntity);
        formData.append('CITY', formValue.city);
        formData.append('TOWN', townExt);
        formData.append('SUBURB', formValue.suburb);
        formData.append('POSTAL_CODE', formValue.postalCode);
      }
  
      let intNum = '0';
      if(formValue.interiorNumber != '' && formValue.interiorNumber != null && formValue.interiorNumber != undefined){
        intNum = formValue.interiorNumber;
      }

      formData.append('STREET', formValue.street);
      formData.append('EXTERIOR_NUMBER', formValue.exteriorNumber);
      formData.append('INTERIOR_NUMBER', intNum);
  
      
      let lada1 = formValue.lada1;
      let lada1Arr = lada1.split('-');
      lada1Arr.pop();
      
      let lada1Val = lada1Arr.join('-');
      let validLada1 = this.ladasStr.filter(item => lada1 == item);
  
      if(validLada1.length == 0){
        this.resourcesService.openSnackBar(`La lada ${lada1} no se encuentra asociada a ningún país. 1`);
        this.formGroup.controls['lada1'].setValue(null);
        return;
      }

      let phone1 = await this._encService.encrypt(`${formValue.telephone1}`);
      formData.append('LADA1', lada1Val);
      formData.append('TELEPHONE1', phone1);
  
      if(formValue.lada2 != '' && formValue.lada2 != null && formValue.lada2 != undefined){
        let lada2 = formValue.lada2;
        let lada2Arr = lada1.split('-');
        lada2Arr.pop();
        
        let lada2Val = lada2Arr.join('-');
        
        let validLada2 = this.ladasStr.filter(item => lada2 == item);
        let phone2 = await this._encService.encrypt(`${formValue.telephone2}`);
  
        if(validLada2.length == 0){
          this.resourcesService.openSnackBar(`La lada ${lada2} no se encuentra asociada a ningún país. 2`);
          this.formGroup.controls['lada2'].setValue(null);
          return;
        }
        
        formData.append('LADA2', lada2Val);
        formData.append('TELEPHONE2', phone2);
      }else{
        formData.append('LADA2', '-');
        formData.append('TELEPHONE2', '-');
      }
      
      let specialtiesStr = JSON.stringify(formValue.specialty);
      formData.append('SPECIALTY', specialtiesStr);
  
      if (this.typeFormSubcontract.idProvider !== null) {
        formData.append('PROVIDER', this.typeFormSubcontract.idProvider);
      }

      this.isLoadingForm = true;
      await lastValueFrom(this._subcontratistService.updateSubcontratist(formData)).then(
        (responseData: ResponseData) => {
          if (!responseData.error) {
            this.resourcesService.openSnackBar("La información del subcontratista se actualizó correctamente.");
            if ( 'provider' in responseData.response ) {
              this._socketService.sendNotice(`El proveedor #${responseData.response.provider.PROV_NUPR} fue modificado desde el Módulo de Gestión de personal, recursos y subcontratistas.`);
            }
            this.goBack(1);
          } else {
            this.resourcesService.openSnackBar(`${responseData.msg}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.updateSubcontratist();
          }
        }
      );
      
      this.isLoadingForm = 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.isLoadingForm = false;
    }
  }
}
