import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { GetProvider, InformationsData, ResponseDataGetProvidersById } from '../../../../../interfaces/acquisition-management/provider.interface';
import { lastValueFrom, Observable } 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 } from '../../../../../interfaces/city-towns.interface';
import { CitySettings } from '../../../../../interfaces/city-settings.interface';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ResourcesService } from '../../../../../services/resources.service';
import { ProviderService } from '../../../../../services/acquisition-management/provider.service';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { EncService } from '../../../../../services/enc.service';
import { SystemAdminService } from '../../../../../services/system-admin.service';
import { AddressByZipCodeResponse } from '../../../../../interfaces/address-by-zip-code.interface';

@Component({
    selector: 'app-information-provider',
    templateUrl: './information-provider.component.html',
    styleUrl: './information-provider.component.css',
    standalone: false
})
export class InformationProviderComponent implements OnInit {
  public formGroupInformation: FormGroup;
  private providerInformation: GetProvider;

  public isLoading: boolean;
  public isLoadingForm: boolean;

  flags: Map<string, string>;

  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(
    @Inject(MAT_DIALOG_DATA) public providerNumber: InformationsData | string,
    public resourcesService: ResourcesService,
    private _providerService: ProviderService,
    private _httpClient: HttpClient,
    private _encService: EncService,
    private _sysAdminService: SystemAdminService,
  ) {    
    this.formGroupInformation = this.createFormGroupInformation();
    this.providerInformation = {} as GetProvider;
    this.isLoading = false;
    this.isLoadingForm = false;

    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 createFormGroupInformation(): FormGroup {
    return new FormGroup({
      NUMERO_PROVEEDOR: new FormControl(''),
      RAZON_SOCIAL: new FormControl(''),
      CORREO: new FormControl(''),
      NOMBRE: new FormControl(''),
      PRIMER_APELLIDO: new FormControl(''),
      SEGUNDO_APELLIDO: new FormControl(''),
      LADA1: new FormControl(''),
      TELEFONO1: new FormControl(''),
      LADA2: new FormControl(''),
      TELEFONO2: new FormControl(''),
      REGIMEN_FISCAL: new FormControl(''),
      TIPO: new FormControl(''),
      TIPO_CONTRIBUYENTE: new FormControl(''),
      RFC: new FormControl(''),
      TAXID: new FormControl(''),
      SITIOWEB: new FormControl(''),
      CALLE: new FormControl(''),
      EXTERIOR: new FormControl(''),
      INTERIOR: new FormControl(''),
      CODIGO_POSTAL: new FormControl(''),
      LOCALIDAD: new FormControl(''),
      COLONIA: new FormControl(''),
      MUNICIPIO: new FormControl(''),
      ENTIDAD: new FormControl(''),
      PAIS: new FormControl(''),
    })
  }

  async ngOnInit() {
    this.isLoading = true;
    this.isLoadingForm = true;
    if (typeof this.providerNumber === 'string') {
      await this.getCountries();
      await this.getProviderByNumber();
    } else {
      this.setDataValue();
    }
    this.isLoading = false;
    this.isLoadingForm = false;
  }

  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 ) => {
        console.log(responseData);
        
        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.formGroupInformation.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 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.formGroupInformation.controls['ENTIDAD'].enable();

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

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

      this.searchingStates = false;
    }
  }

  private async getProviderByNumber() {
    if (typeof this.providerNumber === 'string') {
      this.isLoading = true;
      const user: string = this.resourcesService.getUser();
      const line: number = this.resourcesService.getLineNumber();
      await lastValueFrom(this._providerService.getProviderByNumber(this.providerNumber, user, line)).then(
        async (responseData: ResponseDataGetProvidersById) => {
          if ( !responseData.error ) {
            this.providerInformation = responseData.response;

            this.formGroupInformation.controls['NUMERO_PROVEEDOR'].setValue(this.providerInformation.NUMERO_PROVEEDOR);
            this.formGroupInformation.controls['RAZON_SOCIAL'].setValue(this.providerInformation.RAZON_SOCIAL);
            this.formGroupInformation.controls['CORREO'].setValue(this.providerInformation.CORREO);
            this.formGroupInformation.controls['NOMBRE'].setValue(this.providerInformation.NOMBRE);
            this.formGroupInformation.controls['PRIMER_APELLIDO'].setValue(this.providerInformation.PRIMER_APELLIDO);
            this.formGroupInformation.controls['SEGUNDO_APELLIDO'].setValue(this.providerInformation.SEGUNDO_APELLIDO);
            this.formGroupInformation.controls['LADA1'].setValue(this.providerInformation.LADA1);
            this.formGroupInformation.controls['TELEFONO1'].setValue(this.providerInformation.TELEFONO1);
            this.formGroupInformation.controls['LADA2'].setValue(this.providerInformation.LADA2);
            this.formGroupInformation.controls['TELEFONO2'].setValue(this.providerInformation.TELEFONO2);
            this.formGroupInformation.controls['REGIMEN_FISCAL'].setValue(`(${this.providerInformation.NUMERO_REGIMEN_FISCAL}) ${this.providerInformation.REGIMEN_FISCAL}`);
            this.formGroupInformation.controls['TIPO'].setValue(this.providerInformation.TIPO);
            this.formGroupInformation.controls['TIPO_CONTRIBUYENTE'].setValue(this.providerInformation.TIPO_CONTRIBUYENTE);
            this.formGroupInformation.controls['RFC'].setValue(this.providerInformation.RFC);
            this.formGroupInformation.controls['TAXID'].setValue(this.providerInformation.TAXID);
            this.formGroupInformation.controls['SITIOWEB'].setValue(this.providerInformation.SITIOWEB);
            this.formGroupInformation.controls['CALLE'].setValue(this.providerInformation.CALLE);
            this.formGroupInformation.controls['EXTERIOR'].setValue(this.providerInformation.EXTERIOR);
            this.formGroupInformation.controls['INTERIOR'].setValue(this.providerInformation.INTERIOR);
            this.formGroupInformation.controls['CODIGO_POSTAL'].setValue(this.providerInformation.CODIGO_POSTAL);
            
            if (this.providerInformation.PAIS === 'MEX') {
              // Se obtiene la información de los campos País, Estado, Localidad y Municipio
              await this.searchZipCode();

              // Se guarda el código de la colonia
              const codigoColonia = this.providerInformation.COLONIA;

              // Se obtiene el objeto de la colonia
              let citySettings = this.citySettings.find((citySettings: CitySettings) => citySettings.CODIGOCOLONIA.toString() === codigoColonia.toString() );
              if (citySettings !== undefined) {
                this.formGroupInformation.controls['COLONIA'].setValue(`${citySettings.NOMBRECOLONIA} (${citySettings.CODIGOCOLONIA})`);
              } else {
                this.formGroupInformation.controls['COLONIA'].setValue(codigoColonia);
              }
            } else {
              this.formGroupInformation.controls['LOCALIDAD'].setValue(this.providerInformation.LOCALIDAD);
              this.formGroupInformation.controls['COLONIA'].setValue(this.providerInformation.COLONIA);
              this.formGroupInformation.controls['MUNICIPIO'].setValue(this.providerInformation.MUNICIPIO);
              this.formGroupInformation.controls['ENTIDAD'].setValue(this.providerInformation.ENTIDAD_FEDERATIVA);
              this.formGroupInformation.controls['PAIS'].setValue(this.providerInformation.PAIS);
            }

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

  public async searchZipCode() {
    let postalCode:string = this.formGroupInformation.controls['CODIGO_POSTAL'].value.toString();
    if (postalCode.length === 5 && this.enableSearchByZipCode) {
      
      this.formGroupInformation.controls['COLONIA'].setValue('');
      this.formGroupInformation.controls['MUNICIPIO'].setValue('');
      this.formGroupInformation.controls['ENTIDAD'].setValue('');
      this.formGroupInformation.controls['PAIS'].setValue('');
      
      this.formGroupInformation.controls['CODIGO_POSTAL'].disable();
      this.formGroupInformation.controls['COLONIA'].disable();
      this.formGroupInformation.controls['MUNICIPIO'].disable();
      this.formGroupInformation.controls['ENTIDAD'].disable();
      this.formGroupInformation.controls['PAIS'].disable();

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


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

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

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

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

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

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

        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchAddressByZipCode(postalCode);
        }
      }
    );
  }
  
  private 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.formGroupInformation.controls['MUNICIPIO'].enable();
        } else {
          this.resourcesService.openSnackBar(responseData.msg);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this.resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.searchStateCities(stateCode);
        }
      }
    );
    
    this.searchingCities = false;
  }

  private setDataValue() {
    if (typeof this.providerNumber !== 'string') {
      this.formGroupInformation.controls['NUMERO_PROVEEDOR'].setValue(this.providerNumber.PROV_NUPR)
      this.formGroupInformation.controls['RAZON_SOCIAL'].setValue(this.providerNumber.PROV_NOCO)
      this.formGroupInformation.controls['CORREO'].setValue(this.providerNumber.PROV_CORR)
      this.formGroupInformation.controls['NOMBRE'].setValue(this.providerNumber.PROV_NOMB)
      this.formGroupInformation.controls['PRIMER_APELLIDO'].setValue(this.providerNumber.PROV_APPA)
      this.formGroupInformation.controls['SEGUNDO_APELLIDO'].setValue(this.providerNumber.PROV_APMA)
      this.formGroupInformation.controls['LADA1'].setValue(this.providerNumber.PROV_LAD1)
      this.formGroupInformation.controls['TELEFONO1'].setValue(this.providerNumber.PROV_TEL1)
      this.formGroupInformation.controls['LADA2'].setValue(this.providerNumber.PROV_LAD2)
      this.formGroupInformation.controls['TELEFONO2'].setValue(this.providerNumber.PROV_TEL2)
      this.formGroupInformation.controls['REGIMEN_FISCAL'].setValue(`(${this.providerNumber.REFI_CRFI}) ${this.providerNumber.REFI_DRFI}`)
      this.formGroupInformation.controls['TIPO'].setValue(this.providerNumber.PROV_TIPO)
      this.formGroupInformation.controls['TIPO_CONTRIBUYENTE'].setValue(this.providerNumber.PROV_TICO)
      this.formGroupInformation.controls['RFC'].setValue(this.providerNumber.PROV_XRFC)
      this.formGroupInformation.controls['TAXID'].setValue(this.providerNumber.PROV_XTAX)
      this.formGroupInformation.controls['SITIOWEB'].setValue(this.providerNumber.PROV_SIWE)
      this.formGroupInformation.controls['CALLE'].setValue(this.providerNumber.PROV_CALL)
      this.formGroupInformation.controls['EXTERIOR'].setValue(this.providerNumber.PROV_NUEX)
      this.formGroupInformation.controls['INTERIOR'].setValue(this.providerNumber.PROV_NUIN)
      this.formGroupInformation.controls['CODIGO_POSTAL'].setValue(this.providerNumber.PROV_COPO)
      this.formGroupInformation.controls['LOCALIDAD'].setValue(this.providerNumber.PROV_LOCA)
      this.formGroupInformation.controls['COLONIA'].setValue(this.providerNumber.PROV_COLO)
      this.formGroupInformation.controls['MUNICIPIO'].setValue(this.providerNumber.PROV_MUNI)
      this.formGroupInformation.controls['ENTIDAD'].setValue(this.providerNumber.PROV_ENTI)
      this.formGroupInformation.controls['PAIS'].setValue(this.providerNumber.PROV_PAIS)

    }
  }
}
