import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { lastValueFrom, map, Observable, startWith } from 'rxjs';
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 { ResourcesService, ResponseData } from '../../../../services/resources.service';
import { SystemAdminService } from '../../../../services/system-admin.service';
import { ActivatedRoute, Router } from '@angular/router';
import { InventoryManagementService } from '../../../../services/inventory-management/inventory-management.service';
import { MatDialog } from '@angular/material/dialog';
import { EncService } from '../../../../services/enc.service';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { DataFormWarehouse } from '../warehouse-management.component';
import { GetWarehouse, ResponseDataWarehouse } from '../../../../interfaces/inventory-management/warehouse-management.interface';
import { AddressByZipCodeResponse } from '../../../../interfaces/address-by-zip-code.interface';
import { AlertComponent } from '../../../resources/dialogs/alert/alert.component';

@Component({
    selector: 'app-warehouse-form',
    templateUrl: './warehouse-form.component.html',
    styleUrl: './warehouse-form.component.css',
    standalone: false
})
export class WarehouseFormComponent implements OnInit {
  public isLoading: boolean;
  public isLoadingForm: boolean;
  public title: string;
  public typeForm: 'REG' | 'UPD';
  public formGroup: FormGroup;
  
  flags: Map<string, string>;
  public idWarehouse: string | null;

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

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

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

  constructor(
    public resourcesService: ResourcesService,
    private _sysAdminService: SystemAdminService,
    private _activatedRouter: ActivatedRoute,
    private _inventoryManagementService: InventoryManagementService,
    private _dialog: MatDialog,
    private _encService: EncService,
    private _httpClient: HttpClient,
    private _router: Router,
  ) {
    this.isLoading = false;
    this.isLoadingForm = false;
    this.title = '';
    this.typeForm = 'REG';
    this.formGroup = this.createFormGroup();

    this.idWarehouse = null;

    this.flags = new Map();

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

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

  private createFormGroup() {
    return new FormGroup({
      CODIGO_ALMACEN: new FormControl('', [Validators.required]),
      NOMBRE_ALMACEN: new FormControl('', Validators.required),
      NOMBRE_RESPONSABLE: new FormControl('', Validators.required),
      APELLIDO_PATERNO_RESPONSABLE: new FormControl('', Validators.required),
      APELLIDO_MATERNO_RESPONSABLE: new FormControl(''),
      CORREO1: new FormControl('', [Validators.required, Validators.email]),
      CORREO2: new FormControl('', Validators.email),
      LADA1: new FormControl('', Validators.required),
      LADA2: new FormControl(''),
      TELEFONO1: new FormControl('', Validators.required),
      TELEFONO2: new FormControl(''),
      CALLE: new FormControl('', Validators.required),
      NUMERO_EXTERIOR: new FormControl('', Validators.required),
      NUMERO_INTERIOR: new FormControl(''),
      CODIGO_POSTAL: new FormControl('', Validators.required),
      COLONIA: new FormControl('', Validators.required),
      LOCALIDAD: new FormControl(''),
      MUNICIPIO: new FormControl('', Validators.required),
      ENTIDAD_FEDERATIVA: new FormControl('', Validators.required),
      PAIS: new FormControl('', Validators.required),
    });
  }

  async ngOnInit() {
    this.isLoading = true;
    await this.getCountries();
    await this.getDataForm();
    this.isLoading = false;

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

    this.filteredLadas1 = this.formGroup.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.formGroup.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.filteredSettings = this.formGroup.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.formGroup.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.formGroup.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.formGroup.controls['ENTIDAD_FEDERATIVA'].valueChanges.pipe(
      startWith(''),
      map(value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.countryStatesStr.filter(item => item.toLowerCase().includes(filterValue));
      })
    );

    this.filteredCountries = this.formGroup.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;
      })
    );
  }

  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.fileExists(flagURI);

                if(fileExists){
                  this.flags.set(`${country.LADA!}-${country.NOMECLARUTA_ISO2!}`, country.NOMECLARUTA_ISO2!);
                  this.ladasStr.push(`${country.LADA!}-${country.NOMECLARUTA_ISO2!}`);
                }
              }
            }
          }

          let country = this.formGroup.controls['PAIS'].value;
          if (country !== null && country !== undefined && country !== '' && country.includes('(') && country.includes(')')) {
            let idCountry = country.split('(')[1].split(')')[0];
            this.searchCountryStates(idCountry);
          }
        } 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 getDataForm() {
    let encForm = this._activatedRouter.snapshot.paramMap.get('form');
    if (encForm !== null) {
      const strForm: string = await this._encService.decrypt(encForm);
      const dataFormWarehouse : DataFormWarehouse = JSON.parse(strForm);
      this.typeForm = dataFormWarehouse.typeForm;
      this.idWarehouse = dataFormWarehouse.idWarehouse;

      if(this.typeForm === 'REG') {
        this.title = 'Registro de Almacén';
      } else if (this.typeForm === 'UPD' && this.idWarehouse !== null) {
        this.title = 'Modificación de Almacén';
        await this.getWarehouseById();
      } else {
        this.resourcesService.openSnackBar('Opción no disponible');
        this._router.navigate(['/sam/GIST/GEAL']);
      }
    } else {
      this.resourcesService.openSnackBar('Ocurrió un error al obtener los datos del formulario.');
      this._router.navigate(['/sam/GIST/GEAL']);
    }
  }
  
  private verifyTown(value: string){
    let stateVal = this.formGroup.controls['ENTIDAD_FEDERATIVA'].value;
    let stateArr = stateVal.split('(').reverse();
    let stateCode = stateArr[0].replace(')', '');

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

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

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

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

          this.formGroup.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;
  }
  
  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 searchCountryStates(contryCode: string){
    try{
      this.searchingStates = true;

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

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

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

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

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

      this.searchingStates = false;
    }
  }

  private async getWarehouseById() {
    if (this.idWarehouse !== null) {
      const encWarehouse: string = await this._encService.encrypt(this.idWarehouse.toString());
      const user: string = this.resourcesService.getUser();
      const line: number = this.resourcesService.getLineNumber();
      await lastValueFrom(this._inventoryManagementService.getWarehouseById(encWarehouse, user, line)).then(
        (responseData: ResponseDataWarehouse) => {
          if ( !responseData.error && Object.keys(responseData.response).length > 0 ) {
            
            let codigoAlmacen = responseData.response.CODIGO_ALMACEN;
            let nombreAlmacen = responseData.response.NOMBRE_ALMACEN;
            let nombreResponsable = responseData.response.NOMBRE_RESPONSABLE;
            let apellidoPaternoResponsable = responseData.response.APELLIDO_PATERNO_RESPONSABLE;
            let apellidoMaternoResponsable = responseData.response.APELLIDO_MATERNO_RESPONSABLE;
            let correo1 = responseData.response.CORREO1;
            let correo2 = responseData.response.CORREO2;
            let lada1 = responseData.response.LADA1;
            let responseFindLada1 = this.countries.find( (countriesList:CountriesList) => countriesList.LADA === lada1);
            if (responseFindLada1 !== undefined) {
              lada1 = `${responseFindLada1.LADA}-${responseFindLada1.NOMECLARUTA_ISO2}`
            } else {
              this.resourcesService.openSnackBar(`No se pudo encontrar el país de la Lada Principal.`);
            }
            
            let lada2 = responseData.response.LADA2;
            if (lada2 !== null && lada2 !== undefined && lada2 !== '') {
              let responseFindLada2 = this.countries.find( (countriesList:CountriesList) => countriesList.LADA === lada2);
              if (responseFindLada2 !== undefined) {
                lada2 = `${responseFindLada2.LADA}-${responseFindLada2.NOMECLARUTA_ISO2}`
              } else {
                this.resourcesService.openSnackBar(`No se pudo encontrar el país de la Lada Secundaria.`);
              }
            }
            let telefono1 = responseData.response.TELEFONO1;
            let telefono2 = responseData.response.TELEFONO2;
            let calle = responseData.response.CALLE;
            let numeroExterior = responseData.response.NUMERO_EXTERIOR;
            let numeroInterior = responseData.response.NUMERO_INTERIOR;
            let codigoPostal = responseData.response.CODIGO_POSTAL;
            
            let colonia = responseData.response.COLONIA;
            let localidad = responseData.response.LOCALIDAD;
            if (localidad === null) {
              localidad = 'Sin localidad';
            }
            let municipio = responseData.response.MUNICIPIO;
            let entidadFederativa = responseData.response.ENTIDAD_FEDERATIVA;
            let pais = responseData.response.PAIS;


            this.formGroup.controls['CODIGO_ALMACEN'].setValue(codigoAlmacen);
            this.formGroup.controls['NOMBRE_ALMACEN'].setValue(nombreAlmacen);
            this.formGroup.controls['NOMBRE_RESPONSABLE'].setValue(nombreResponsable);
            this.formGroup.controls['APELLIDO_PATERNO_RESPONSABLE'].setValue(apellidoPaternoResponsable);
            this.formGroup.controls['APELLIDO_MATERNO_RESPONSABLE'].setValue(apellidoMaternoResponsable);
            this.formGroup.controls['CORREO1'].setValue(correo1);
            this.formGroup.controls['CORREO2'].setValue(correo2);
            this.formGroup.controls['LADA1'].setValue(lada1);
            this.formGroup.controls['LADA2'].setValue(lada2);
            this.formGroup.controls['TELEFONO1'].setValue(telefono1);
            this.formGroup.controls['TELEFONO2'].setValue(telefono2);
            this.formGroup.controls['CALLE'].setValue(calle);
            this.formGroup.controls['NUMERO_EXTERIOR'].setValue(numeroExterior);
            this.formGroup.controls['NUMERO_INTERIOR'].setValue(numeroInterior);
            this.formGroup.controls['CODIGO_POSTAL'].setValue(codigoPostal);

            if (responseData.response.PAIS === 'México (MEX)') {
              this.searchZipCode();
              this.formGroup.controls['COLONIA'].setValue(colonia);
            } else {
              this.formGroup.controls['COLONIA'].setValue(colonia);
              this.formGroup.controls['LOCALIDAD'].setValue(localidad);
              this.formGroup.controls['MUNICIPIO'].setValue(municipio);
              this.formGroup.controls['ENTIDAD_FEDERATIVA'].setValue(entidadFederativa);
              this.formGroup.controls['PAIS'].setValue(pais);
            }
            this.formGroup.updateValueAndValidity();

          } else {
            this.resourcesService.openSnackBar(`${responseData.msg}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.getWarehouseById();
          }
        }
      )
      
    }
  }
  
  public async searchZipCode() {
    let postalCode:string = this.formGroup.controls['CODIGO_POSTAL'].value.toString();
    if (postalCode.length === 5 && this.enableSearchByZipCode) {
      
      this.formGroup.controls['COLONIA'].setValue('');
      this.formGroup.controls['MUNICIPIO'].setValue('');
      this.formGroup.controls['ENTIDAD_FEDERATIVA'].setValue('');
      this.formGroup.controls['PAIS'].setValue('');
      
      this.formGroup.controls['CODIGO_POSTAL'].disable();
      this.formGroup.controls['COLONIA'].disable();
      this.formGroup.controls['MUNICIPIO'].disable();
      this.formGroup.controls['ENTIDAD_FEDERATIVA'].disable();
      this.formGroup.controls['PAIS'].disable();

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


      this.formGroup.controls['CODIGO_POSTAL'].enable();
      this.formGroup.controls['COLONIA'].enable();
      this.formGroup.controls['MUNICIPIO'].enable();
      this.formGroup.controls['ENTIDAD_FEDERATIVA'].enable();
      this.formGroup.controls['PAIS'].enable();

      this.checkCity();
    }
  }
  
  private async searchAddressByZipCode(postalCode:string) {
    const encPostalCode: string = await this._encService.encrypt(postalCode);
    const idUser: string = this.resourcesService.getUser();
    const lineNumber:number = this.resourcesService.getLineNumber();
    await lastValueFrom(this._sysAdminService.getAddressByZipCode(
      encPostalCode, idUser, lineNumber
    )).then(
      (responseData: AddressByZipCodeResponse) => {
        if (!responseData.error) {

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

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

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

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

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

        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchAddressByZipCode(postalCode);
        }
      }
    );
  }
  
  public checkCity() {
    if(!this.enableSearchByZipCode) {
      let municipality: string = this.formGroup.controls['MUNICIPIO'].value;    

      let countryVal = this.formGroup.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.formGroup.controls['LOCALIDAD'].setValue('');
          this.formGroup.controls['LOCALIDAD'].disable();
          this.formGroup.controls['COLONIA'].setValue('');
          this.formGroup.controls['COLONIA'].disable();
        }
      }else{
        this.formGroup.controls['LOCALIDAD'].enable();
      }
    }
  }
  
  private async searchStateCities(stateCode: string){
    this.searchingCities = true;
    
    const idUser:string = this.resourcesService.getUser();
    const stateCodeEnc: string = await this._encService.encrypt(stateCode);
    const line: number = this.resourcesService.getLineNumber();

    await lastValueFrom(this._sysAdminService.getCitiesByStateCode(stateCodeEnc, idUser, line)).then(
      (responseData: StateCitiesResponse) => {
        if (!responseData.error) {
          this.stateCities = responseData.response;
          this.stateCitiesStr = [];
          this.stateCities.forEach(item => {
            this.stateCitiesStr.push(`${item.NOMBREMUNICIPIO} (${item.CODIGOMUNICIPIO})`);
          });
          this.formGroup.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;
  }
  
  private verifyCity(value: string){
    let stateVal = this.formGroup.controls['ENTIDAD_FEDERATIVA'].value;
    let stateArr = stateVal.split('(').reverse();
    let stateCode = stateArr[0].replace(')', '');
    
    this.cityTowns = [];
    this.cityTownsStr = [];
    this.citySettings = [];
    this.citySettingsStr = [];
    this.searchStateTowns(stateCode, value);
  }
  
  private async searchStateTowns(stateCode: string, cityCode: string){
    
    this.searchingTowns = true;
    
    const idUser: string = this.resourcesService.getUser();
    const stateCodeEnc: string = await this._encService.encrypt(stateCode);
    const cityCodeEnc: string = await this._encService.encrypt(cityCode);
    const line: number = this.resourcesService.getLineNumber();

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

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

          if(responseData.response.length > 1){
            this.formGroup.controls['LOCALIDAD'].enable();
          }else if(responseData.response.length == 1 && responseData.response[0].CODIGOLOCALIDAD != null){
            this.formGroup.controls['LOCALIDAD'].enable();
          }else{
            this.formGroup.controls['LOCALIDAD'].disable();
            this.formGroup.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 validateLada2() {
    let lada2 = this.formGroup.controls['LADA2'].value;
    if (lada2 !== null && lada2 !== undefined && lada2.includes('+') && lada2.includes('-')) {
      let arrLadaParam = lada2.split('-');

      if (arrLadaParam[0].length > 1 && arrLadaParam[1].length > 1) {
        let lada = arrLadaParam[0];
        let isoCountry = arrLadaParam[1];
        let validateExists = this.countries.some(( countriesList: CountriesList ) => countriesList.LADA === lada && countriesList.NOMECLARUTA_ISO2 === isoCountry);
        
        if (validateExists) {
          this.formGroup.controls['LADA2'].setValidators(Validators.required);
          this.formGroup.controls['TELEFONO2'].setValidators(Validators.required);
          this.formGroup.controls['LADA2'].updateValueAndValidity();
          this.formGroup.controls['TELEFONO2'].updateValueAndValidity();
        } else {
          this.formGroup.controls['LADA2'].clearValidators();
          this.formGroup.controls['TELEFONO2'].clearValidators();
          this.formGroup.controls['LADA2'].updateValueAndValidity();
          this.formGroup.controls['TELEFONO2'].updateValueAndValidity();
        }
      } else {
        this.formGroup.controls['LADA2'].clearValidators();
        this.formGroup.controls['TELEFONO2'].clearValidators();
        this.formGroup.controls['LADA2'].updateValueAndValidity();
          this.formGroup.controls['TELEFONO2'].updateValueAndValidity();
      }
    } else {
      this.formGroup.controls['LADA2'].clearValidators();
      this.formGroup.controls['TELEFONO2'].clearValidators();
      this.formGroup.controls['LADA2'].updateValueAndValidity();
      this.formGroup.controls['TELEFONO2'].updateValueAndValidity();
    }
  }
  
  public validateTelefono2() {
    let telefono2 = this.formGroup.controls['TELEFONO2'].value;
    if (telefono2 !== null && telefono2 !== undefined && telefono2.toString().length > 0) {
      this.formGroup.controls['LADA2'].setValidators(Validators.required);
      this.formGroup.controls['TELEFONO2'].setValidators(Validators.required);
      this.formGroup.controls['LADA2'].updateValueAndValidity();
      this.formGroup.controls['TELEFONO2'].updateValueAndValidity();
    } else {
      this.formGroup.controls['LADA2'].clearValidators();
      this.formGroup.controls['TELEFONO2'].clearValidators();
      this.formGroup.controls['LADA2'].updateValueAndValidity();
      this.formGroup.controls['TELEFONO2'].updateValueAndValidity();
    }
  }

  public checkColony() {
    if(!this.enableSearchByZipCode) {
      let colony:string = this.formGroup.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.formGroup.controls['CODIGO_POSTAL'].setValue(settingValid[0].CODIGOPOSTAL);
    }
  }
  
  public checkEntity() {
    let entity: string = this.formGroup.controls['ENTIDAD_FEDERATIVA'].value;
    if (entity === null || entity === undefined) {
      entity = '';
    }

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

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

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

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

      this.formGroup.controls['CODIGO_POSTAL'].enable();
      this.enableSearchByZipCode = true;
    }
  }
  
  private verifyCountry(countryCode: string){
    
    this.formGroup.controls['ENTIDAD_FEDERATIVA'].disable();
    this.countryStates = [];
    this.countryStatesStr = [];
    this.stateCities = [];
    this.stateCitiesStr = [];
    this.cityTowns = [];
    this.cityTownsStr = [];
    this.citySettings = [];
    this.citySettingsStr = [];

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

    if(countryCode == 'CAN' || countryCode == 'MEX' || countryCode == 'USA'){
      this.searchCountryStates(countryCode);
    }else{
      this.formGroup.controls['ENTIDAD_FEDERATIVA'].enable();
    }
  }
  
  public alert() {    
    if (this.typeForm === 'REG') {
      this._dialog.open(AlertComponent, {
        disableClose: true,
        data: {
          title: `Confirmación del Registro`,
          description: `¿Está seguro de registrar el almacén?`,
          icon: `warning`
        }
      }).afterClosed().subscribe(async (result) => {
        if (result) {
          await this.registerWarehouse();
        }
      });
    } else if (this.typeForm === 'UPD') {
      this._dialog.open(AlertComponent, {
        disableClose: true,
        data: {
          title: `Confirmación de la Modificación`,
          description: `¿Está seguro de modificar el almacén?`,
          icon: `warning`
        }
      }).afterClosed().subscribe(async (result) => {
        if (result) {
          await this.updateWarehouse();
        }
      });
    }    
  }

  private async registerWarehouse() {
    let responseRequestData: GetWarehouse | false = this.createRequestData();
    if (responseRequestData !== false) {
      await lastValueFrom(this._inventoryManagementService.createWarehouse(responseRequestData)).then(
        (responseData: ResponseData) => {
          if (!responseData.error) {
            this.resourcesService.openSnackBar(`¡Registro exitoso!`);
            this._router.navigate(['/sam/GIST/GEAL']);
          } else {
            this.resourcesService.openSnackBar(`${responseData.msg}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.registerWarehouse();
          }
        }
      );
    }
  }

  private async updateWarehouse() {
    let responseRequestData: GetWarehouse | false = this.createRequestData();
    if (responseRequestData !== false && this.idWarehouse !== null) {
      const encWarehouse = await this._encService.encrypt(this.idWarehouse.toString());
      await lastValueFrom(this._inventoryManagementService.updateWarehouse(responseRequestData, encWarehouse)).then(
        (responseData: ResponseData) => {          
          if (!responseData.error) {
            this.resourcesService.openSnackBar(`¡Modificación exitosa!`);
            this._router.navigate(['/sam/GIST/GEAL']);
          } else {
            this.resourcesService.openSnackBar(`${responseData.msg}`);
          }
        }, async (httpErrorResponse: HttpErrorResponse) => {
          let response = this.resourcesService.checkErrors(httpErrorResponse)
          if (response !== null && response.reload) {
            await this.updateWarehouse();
          }
        }
      );
    }
  }

  private createRequestData(): GetWarehouse | false {

    let codigoAlmacen = this.formGroup.controls['CODIGO_ALMACEN'].value;
    codigoAlmacen = codigoAlmacen.toString().trim();

    let nombreAlmacen = this.formGroup.controls['NOMBRE_ALMACEN'].value;
    nombreAlmacen = nombreAlmacen.toString().trim();

    let nombreResponsable = this.formGroup.controls['NOMBRE_RESPONSABLE'].value;
    nombreResponsable = nombreResponsable.toString().trim();

    let apellidoPaternoResponsable = this.formGroup.controls['APELLIDO_PATERNO_RESPONSABLE'].value;
    apellidoPaternoResponsable = apellidoPaternoResponsable.toString().trim();

    let apellidoMaternoResponsable = this.formGroup.controls['APELLIDO_MATERNO_RESPONSABLE'].value;
    if ( apellidoMaternoResponsable !== null && apellidoMaternoResponsable !== undefined && apellidoMaternoResponsable !== '') {
      apellidoMaternoResponsable = apellidoMaternoResponsable.toString().trim();
    } else {
      apellidoMaternoResponsable = null;
    }

    let correo1 = this.formGroup.controls['CORREO1'].value;
    correo1 = correo1.toString().trim();

    let correo2 = this.formGroup.controls['CORREO2'].value;
    if ( correo2 !== null && correo2 !== undefined && correo2 !== '') {
      correo2 = correo2.toString().trim();
      if (correo1 === correo2) {
        this.resourcesService.openSnackBar(`El correo principal no debe ser igual al correo secundario.`);
        return false;
      }
    } else {
      correo2 = null;
    }

    let lada1 = this.formGroup.controls['LADA1'].value;
    lada1 = lada1.toString().trim();
    if(lada1.includes('+') && lada1.includes('-')) {
      let arrLada1 = lada1.split('-');
      lada1 = arrLada1[0];
    } else {
      this.resourcesService.openSnackBar(`El formato de la lada debe ser igual al de la lista desplegable.`)
      return false;
    }
    
    let telefono1 = this.formGroup.controls['TELEFONO1'].value;
    telefono1 = telefono1.toString().trim();

    let lada2 = this.formGroup.controls['LADA2'].value;
    if (lada2 !== null && lada2 !== undefined && lada2 !== '') {
      lada2 = lada2.toString().trim();
      if(lada2.includes('+') && lada2.includes('-')) {
        let arrLada1 = lada2.split('-');
        lada2 = arrLada1[0];
      } else {
        this.resourcesService.openSnackBar(`El formato de la lada debe ser igual al de la lista desplegable.`)
        return false;
      }
    } else {
      lada2 = null;
    }

    let telefono2 = this.formGroup.controls['TELEFONO2'].value;
    if (telefono2 !== null && telefono2 !== undefined && telefono2 !== '') {
      telefono2 = telefono2.toString().trim();
      if (lada1 === lada2 && telefono1 === telefono2) {
        this.resourcesService.openSnackBar(`El teléfono principal no debe ser igual al teléfono secundario.`);
        return false;
      }
    } else {
      telefono2 = null;
    }
    
    let calle = this.formGroup.controls['CALLE'].value;
    calle = calle.toString().trim();

    let numeroExterior = this.formGroup.controls['NUMERO_EXTERIOR'].value;
    numeroExterior = numeroExterior.toString().trim();

    let numeroInterior = this.formGroup.controls['NUMERO_INTERIOR'].value;
    if (numeroInterior !== null && numeroInterior !== undefined && numeroInterior !== '') {
      numeroInterior = numeroInterior.toString().trim();
    } else {
      numeroInterior = null;
    }

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

    let colonia = this.formGroup.controls['COLONIA'].value;
    colonia = colonia.toString().trim();
    if (colonia.includes('(') && colonia.includes(')')) {
      let idColonia: string = colonia.split('(')[1].split(')')[0];

      let validate = this.citySettings.some((citySettings: CitySettings) => citySettings.CODIGOCOLONIA === idColonia );
      if (validate) {
        colonia = idColonia;
      } else {
        this.resourcesService.openSnackBar(`No se encontró el número de la colonia en la lista.`);
        return false;
      }
    }

    let localidad = this.formGroup.controls['LOCALIDAD'].value;
    if (localidad !== null && localidad !== undefined && localidad !== '' && !this.enableSearchByZipCode) {
      localidad = localidad.toString().trim();
      if (localidad === 'Sin localidad') {
        localidad = null;
      } else if (localidad.includes('(') && localidad.includes(')')) {
        let idLocalidad: string = localidad.split('(')[1].split(')')[0];

        let validate = this.cityTowns.some((cityTown: CityTown) => cityTown.CODIGOLOCALIDAD === idLocalidad)
        if (validate) {
          localidad = idLocalidad;
        } else {
          this.resourcesService.openSnackBar(`No se encontró el número de la localidad en la lista.`);
          return false;
        }
      } else {
        this.resourcesService.openSnackBar(`El formato del campo Localidad debe ser igual al de la lista desplegable.`);
        return false;
      }
    } else {
      localidad = null;
    }


    let municipio = this.formGroup.controls['MUNICIPIO'].value;
    municipio = municipio.toString().trim();
    if (municipio.includes('(') && municipio.includes(')')) {
      let idMunicipio: string = municipio.split('(')[1].split(')')[0];

      let validate = this.stateCities.some((stateCity: StateCity) => stateCity.CODIGOMUNICIPIO === idMunicipio);
      if (validate) {
        municipio = idMunicipio;
      } else {
        this.resourcesService.openSnackBar(`No se encontró el número del municipio en la lista.`);
        return false;
      }

    } else {
      this.resourcesService.openSnackBar(`El formato del campo Municipio debe ser igual al de la lista desplegable.`);
      return false;
    }
    
    let entidadFederativa = this.formGroup.controls['ENTIDAD_FEDERATIVA'].value;
    entidadFederativa = entidadFederativa.toString().trim();
    if (entidadFederativa.includes('(') && entidadFederativa.includes(')')) {
      let idEntidadFederativa: string = entidadFederativa.split('(')[1].split(')')[0];
      
      let validate = this.countryStates.some((countryState: CountryState) => countryState.CODIGOESTADO === idEntidadFederativa);
      if (validate) {
        entidadFederativa = idEntidadFederativa;
      } else {
        this.resourcesService.openSnackBar(`No se encontró el número de la entidad federativa en la lista.`);
        return false;
      }
    } else {
      this.resourcesService.openSnackBar(`El formato del campo Entidad Federativa debe ser igual al de la lista desplegable.`);
      return false;
    }
    
    let pais = this.formGroup.controls['PAIS'].value;
    pais = pais.toString().trim();
    if (pais.includes('(') === pais.includes(')')) {
      let idPais: string = pais.split('(')[1].split(')')[0];

      let validate = this.countries.some((countriesList: CountriesList) => countriesList.COUNTRY_ID === idPais);
      if (validate) {
        pais = idPais;
      } else {
        this.resourcesService.openSnackBar(`No se encontró el número del país en la lista.`);
        return false;
      }
    } else {
      this.resourcesService.openSnackBar(`El formato del campo País debe ser igual al de la lista desplegable.`);
      return false;
    }


    const requestDataWarehouse: GetWarehouse = {
      CODIGO_ALMACEN: codigoAlmacen,
      NOMBRE_ALMACEN: nombreAlmacen,
      NOMBRE_RESPONSABLE: nombreResponsable,
      APELLIDO_PATERNO_RESPONSABLE: apellidoPaternoResponsable,
      APELLIDO_MATERNO_RESPONSABLE: apellidoMaternoResponsable,
      CORREO1: correo1,
      CORREO2: correo2,
      LADA1: lada1,
      TELEFONO1: telefono1,
      LADA2: lada2,
      TELEFONO2: telefono2,
      CALLE: calle,
      NUMERO_EXTERIOR: numeroExterior,
      NUMERO_INTERIOR: numeroInterior,
      CODIGO_POSTAL: codigoPostal,
      COLONIA: colonia,
      LOCALIDAD: localidad,
      MUNICIPIO: municipio,
      ENTIDAD_FEDERATIVA: entidadFederativa,
      PAIS: pais,
      USUARIO: this.resourcesService.getUser(),
      NUMERO_LINEA: this.resourcesService.getLineNumber()
    }    

    return requestDataWarehouse;
  }
}
