import { Component, Inject, OnInit } from '@angular/core';
import { DownoloadEmployeeInfo, EmployeeInfo, EmployeesListItem, EmployeesListResponse, FilesDocuments, ResponseDataEmployee } from '../../../../interfaces/personal-managment/employee.interface';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { GetWorkteams, ResponseDataGetWorkteams } from '../../../../interfaces/personal-managment/workteam.interface';
import { SubcontratistItem, SubcontratistsResponse } from '../../../../interfaces/personal-managment/subcontratists.interface';
import { CountriesList, CountriesListResponse, LadaSelection } from '../../../../interfaces/countries-list.interface';
import { MatTableDataSource } from '@angular/material/table';
import { TempFileInfo } from '../../../../interfaces/temp-file-info.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 { lastValueFrom, map, Observable, startWith } from 'rxjs';
import { SpecialtiesListItem, SpecialtiesListResponse } from '../../../../interfaces/specialties.interface';
import { UserResponse, UsersResponse } from '../../../../interfaces/users.interface';
import { DOCUMENT } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
import { EmployeeService } from '../../../../services/personal-management/employee.service';
import { ResourcesService } from '../../../../services/resources.service';
import { WorkTeamService } from '../../../../services/personal-management/work-team.service';
import { SubcontratistService } from '../../../../services/personal-management/subcontratist.service';
import { EncService } from '../../../../services/enc.service';
import { SystemAdminService } from '../../../../services/system-admin.service';
import { MatDialog } from '@angular/material/dialog';
import { UsersProfilesService } from '../../../../services/users-profiles.service';
import { FunctionsService } from '../../../../services/functions.service';
import { GdelService } from '../../../../services/gdel.service';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { InterventionService } from '../../../../services/personal-management/intervention.service';
import { AddressByZipCodeResponse } from '../../../../interfaces/address-by-zip-code.interface';
import { availableFiles } from '../../../../../environments/environment.prod';
import { AlertComponent } from '../../../resources/dialogs/alert/alert.component';

@Component({
    selector: 'app-employee-form',
    templateUrl: './employee-form.component.html',
    styleUrl: './employee-form.component.css',
    standalone: false
})
export class EmployeeFormComponent implements OnInit {
  public action: string;
  public idEmployee: string;
  private infoEmployee!: DownoloadEmployeeInfo;
  public enable: string;
  public btnSmall: boolean;
  public formGroup: FormGroup;
  public isLoadingForm: boolean;
  public workteams: Array<GetWorkteams>;
  public subcontratists: Array<SubcontratistItem>;
  public countries: Array<CountriesList>;

  public officeDoc!: Array<any>;
  public certDoc!: Array<any>;
  public authoDoc!: Array<any>;
  public officeDoc2!: Array<any>;
  public certDoc2!: Array<any>;
  public authoDoc2!: Array<any>;
  public authoButton!: boolean;
  public officeButton!: boolean;
  public certButton!: boolean;

  public nameUpdateDocument!: string;
  public documentTipe!: number;

  public formData: FormData = new FormData();
  public documentsEmployee!: Array<any>;

  public dataSource: MatTableDataSource<TempFileInfo>;
  public displayedColumns: string[] =  ['ID', 'NOMBRE', 'PESO', 'TIPO', 'ACCIONES'];
  public documents!: Array<FilesDocuments>;

  public isLoading: boolean;
  public hasError: boolean;
  public errorStr: string;
  public isUploading: boolean;
  public disableDelete: boolean;
  public users: UserResponse[];
  public enableSearchByZipCode: boolean;
  public countryStates: CountryState[];
  public stateCities: StateCity[];
  public cityTowns: CityTown[];
  public citySettings: CitySettings[];
  public ladas: LadaSelection[];

  public countriesStr: string[];
  public countryStatesStr: string[];
  public stateCitiesStr: string[];
  public cityTownsStr: string[];
  public citySettingsStr: string[];
  public ladasStr: string[];

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

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

  flags: Map<string, string>;
  attached: TempFileInfo[];
  fileTypes: Map<string, string>;
  screenSize: number;
  employee: EmployeeInfo | null;
  specialties: SpecialtiesListItem[];

  public arrEmployee: Array<EmployeesListItem>;
  public employeeStr: Array<string>;
  public filteredEmployee?: Observable<string[]>;

  constructor(
    @Inject(DOCUMENT) private _document: Document,
    private _activatedRoute: ActivatedRoute,
    private _employeeService: EmployeeService,
    private _resourcesService: ResourcesService,
    private _workteamService: WorkTeamService,
    private _subcontratistsService: SubcontratistService,
    private _encService: EncService,
    private _sysAdminService: SystemAdminService,
    private _dialog: MatDialog,
    private _usersProfilesService: UsersProfilesService,
    private _functionsService: FunctionsService,
    private _gdelService: GdelService,
    private _httpClient: HttpClient,
    private _interventionService: InterventionService,
  ) {
    this.action = "";
    this.idEmployee = this._activatedRoute.snapshot.paramMap.get('id')!;
    this.enable = this._activatedRoute.snapshot.paramMap.get('enable')!;
    this.btnSmall = false;
    this.formGroup = this.createFormGroup();
    this.isLoadingForm = false;
    this.officeDoc = [];
    this.certDoc = [];
    this.authoDoc = [];
    this.officeDoc2 = [];
    this.certDoc2 = [];
    this.authoDoc2 = [];
    this.authoButton = false;
    this.officeButton = false;
    this.certButton = false;
    this.nameUpdateDocument = "";
    this.documents = [];
    this.documentsEmployee = [];
    this.documentTipe = 0;
    this.dataSource = new MatTableDataSource<any>();

    this.workteams = [];
    this.subcontratists = [];
    this.countries = [];
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = "";
    this.isUploading = false;
    this.disableDelete = false;
    this.users = [];
    this.enableSearchByZipCode = true;
    this.countryStates = [];
    this.stateCities = [];
    this.cityTowns = [];
    this.citySettings = [];
    this.ladas = [];

    this.countriesStr = [];
    this.countryStatesStr = [];
    this.stateCitiesStr = [];
    this.cityTownsStr = [];
    this.citySettingsStr = [];
    this.ladasStr = [];
    
    this.searchingStates = false;
    this.citiesInput = false;
    this.searchingCities = false;
    this.searchingTowns = false;
    this.searchingSettings = false;
    this.searchingAddress = false;

    this.flags = new Map();
    this.attached = [];
    this.fileTypes = new Map();
    this.screenSize = window.innerWidth;
    this.employee = null;
    this.specialties = [];

    this.arrEmployee = [];
    this.employeeStr = [];
  }

  private createFormGroup() {
    return new FormGroup({
      userId: new FormControl({ value: '', disabled: false }, Validators.required),
      workteamId: new FormControl('', Validators.required),
      contractType: new FormControl('', Validators.required),
      subcontratistId: new FormControl({value: '', disabled: true}, Validators.required),
      speciality: new FormControl([], Validators.required),
      foreigner: new FormControl('', Validators.required),
      RFC: new FormControl({value: '', disabled: true}, [Validators.required, Validators.minLength(13), Validators.maxLength(13), 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.minLength(13), Validators.maxLength(13), 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])$/))]),
      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),
      contactName: new FormControl('', Validators.required),
      contactLada: new FormControl('', Validators.required),
      contactTelephone: new FormControl('', [Validators.required, Validators.minLength(7), Validators.maxLength(11)]),
      contactAddress: new FormControl('', Validators.required),
      employeeBossId: new FormControl(''),
    })
  }

  async ngOnInit() {
    await this.getAvaibleUsers();
    this.init();

    this.fileTypes.set('AU', 'Autorización');
    this.fileTypes.set('OF', 'Oficio');
    this.fileTypes.set('CE', 'Certificación');

    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.filteredLadas1 = this.formGroup.controls['contactLada'].valueChanges.pipe(
      startWith(''),
      map(value => this._fiterLada1(value || ''))
    );

    this.filteredEmployee = this.formGroup.controls['employeeBossId'].valueChanges.pipe(
      startWith(''),
      map( value => {
        value = value === null || value === undefined ? '' : value;
        const filterValue = value.toLowerCase();
        return this.employeeStr.filter(item => item.toLowerCase().includes(filterValue));
      } )
    );
  }

  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 _fiterLada1(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.ladasStr.filter(item => item.toLowerCase().includes(filterValue));
  }

  private async getAvaibleUsers() {
    
    const encEmployee: string = this.idEmployee;
    const encUser: string = this._resourcesService.getUser();    
    const LINE: number = this._resourcesService.getLineNumber();    

    await lastValueFrom(this._employeeService.getConsultOfEmployeesForLeader(encEmployee,encUser, LINE)).then(
      ( responseData: EmployeesListResponse ) => {
        if (!responseData.error) {
          this.arrEmployee = responseData.response;
          this.employeeStr = responseData.response.map((employeesListItem: EmployeesListItem) => `${employeesListItem.NAME} (${employeesListItem.ID_EMPLOYEE})`);          
        } else {
          this._resourcesService.openSnackBar(`${responseData.msg}`);
        }
      }, async (httpErrorResponse: HttpErrorResponse) => {
        let response = this._resourcesService.checkErrors(httpErrorResponse)
        if (response !== null && response.reload) {
          await this.getAvaibleUsers();
        }
      }
    );
  }

  async init(){
    try{
      let idDec = await this._encService.decrypt(this.idEmployee);
      let idEnc = this.idEmployee;
      this.idEmployee = idDec;
      if(idDec == "0"){
        this.action = "Registrar";
        this.getUsers();
      }else if(idDec != '0' && this.enable == '1'){
        this.action = "Editar";
        this.getData(idEnc);
      }else{
        this.action = "Detalle de";
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (11).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (12).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getUsers(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let users: UsersResponse = await lastValueFrom(this._usersProfilesService.getUsers(idUser, 1));
      let idUserDec = await this._encService.decrypt(idUser);

      if(users.error){
        this.hasError = users.error;
        this.errorStr = users.msg;
        this.isLoading = false;
      }else{
        let employeeID = '';
        if(this.employee != null){
          employeeID = await this._encService.decrypt(this.employee.USER_ID);
        }

        for(const user of users.response){
          let userIDDec = await this._encService.decrypt(user.IDUSUARIO);
          if(user.APEMAT == null){
            user.APEPAT = `${user.APEPAT} (${userIDDec})`;
          }else{
            user.APEMAT = `${user.APEMAT} (${userIDDec})`;
          }

          if(employeeID == userIDDec){
            this.formGroup.controls['userId'].setValue(user.IDUSUARIO);
            this.formGroup.controls['userId'].disable();
          }

          if(idUserDec != userIDDec){
            this.users.push(user);
          }
        }
        
        this.getWorkteams();
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = "Ocurrió un error inesperado (13).";
      }else if(error.error.msg == undefined){
        this.errorStr = "Ocurrió un error inesperado (14).";
      }else{
        this.errorStr = error.error.msg;
      }

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

  private async getData(idEmployee: string) {
    try{
      let idUser = localStorage.getItem('idusuario')!;
      const line: number = 1;
      let employee: ResponseDataEmployee = await lastValueFrom(this._employeeService.getEmployeeById(idEmployee, idUser, line));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        this.employee = employee.response;

        this.formGroup.controls['contractType'].setValue(this.employee.CONTRACT_TYPE);
        this.formGroup.controls['foreigner'].setValue(this.employee.FOREIGNER);
        
        if(this.employee.FOREIGNER == 'Si'){
          this.formGroup.controls['tax'].setValue(this.employee.TAX_ID);
          this.formGroup.controls['tax'].enable();
        }else{
          let rfcDec = await this._encService.decrypt(this.employee.RFC!);
          this.formGroup.controls['RFC'].setValue(rfcDec);
          this.formGroup.controls['RFC'].enable();
        }

        this.formGroup.controls['country'].enable();
        this.formGroup.controls['country'].setValue(this.employee.COUNTRY);
        this.formGroup.controls['federalEntity'].setValue(this.employee.STATE);
    
        if(this.employee.CITY != null){
          this.formGroup.controls['city'].setValue(this.employee.CITY);
        }else{
          this.formGroup.controls['city'].setValue('Sin municipio');
        }
    
        if(this.employee.TOWN != null){
          this.formGroup.controls['town'].setValue(this.employee.TOWN);
        }else{
          this.formGroup.controls['town'].setValue('Sin localidad');
        }

        let zipCodeDec = await this._encService.decrypt(this.employee.ZIP_CODE);
        this.formGroup.controls['postalCode'].setValue(zipCodeDec);

        let contactPhoneDec = await this._encService.decrypt(this.employee.CONTACT_TELEPHONE);
        this.formGroup.controls['contactTelephone'].setValue(contactPhoneDec);

        this.formGroup.controls['suburb'].setValue(this.employee.SETTING);
        this.formGroup.controls['street'].setValue(this.employee.STREET);
        this.formGroup.controls['exteriorNumber'].setValue(this.employee.EXTERIOR_NUMBER);
        this.formGroup.controls['interiorNumber'].setValue(this.employee.INTERIOR_NUMBER);
        this.formGroup.controls['contactName'].setValue(this.employee.CONTACT_NAME);
        this.formGroup.controls['contactAddress'].setValue(this.employee.CONTACT_ADDRESS);

        let attached = JSON.parse(this.employee.DOCUMENTS);
        for(const doc of attached){
          let idDec = await this._encService.decrypt(doc.FILE_ID);
          let file: TempFileInfo = {
            id: doc.FILE_ID,
            name: idDec,
            size: this.formatBytes(doc.FILE_SIZE),
            type: doc.FILE_TYPE,
            isFinalFile: true,
          };

          this.attached.push(file);
        }

        this.dataSource = new MatTableDataSource(this.attached);
        this.getUsers();
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (23).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (24).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  private async getWorkteams() {
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let workTeams: ResponseDataGetWorkteams = await lastValueFrom(this._workteamService.getConsultOfWorkteams(idUser, 1));

      if(workTeams.error){
        this.hasError = workTeams.error;
        this.errorStr = workTeams.msg;
        this.isLoading = false;
      }else{
        let workTeamDec = '';
        if(this.employee != null && this.employee.WORKTEAM_ID != null){
          workTeamDec = await this._encService.decrypt(this.employee.WORKTEAM_ID);
        }

        let workTeamsArr: GetWorkteams[] = [];
        for(const workteam of workTeams.response){
          if(workteam.STATUS == 'Activo'){
            let specialtiesArr: string[] = JSON.parse(workteam.SPECIALITY);
            let specialtiesStr = "";
            for(const specialtyCode of specialtiesArr){
              let codeDec = await this._encService.decrypt(specialtyCode);
              specialtiesStr += `${codeDec}, `;
            }

            specialtiesStr = specialtiesStr.substring(0, specialtiesStr.length - 2);
            workteam.SPECIALITY = specialtiesStr;
            workteam.SPECIALTY_ARR = specialtiesArr;
            
            let idWorkTeamDec = await this._encService.decrypt(workteam.WORKTEAM_ID);
            if(workTeamDec == idWorkTeamDec){
              this.formGroup.controls['workteamId'].setValue(workteam.WORKTEAM_ID);
            }

            workteam.NAME = `${workteam.NAME} (${idWorkTeamDec})`;
            workTeamsArr.push(workteam);
          }
        }

        if(this.employee != null && this.employee.WORKTEAM_ID == null){
          this.formGroup.controls['workteamId'].setValue('-');
          this.formGroup.controls['speciality'].enable();
        }

        this.workteams = workTeamsArr;
        this.getSubcontratists();
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = "Ocurrió un error inesperado (15).";
      }else if(error.error.msg == undefined){
        this.errorStr = "Ocurrió un error inesperado (16).";
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = 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 (3).");
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado (4).");
      }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 (5).");
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado (6).");
      }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 (7).");
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado (8).");
      }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);
    }
  }

  formatBytes(bytes: number, decimals = 2) {
    if (bytes === 0) return '0 Bytes';

    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
  }

  private async getSubcontratists() {
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let subcontratists: SubcontratistsResponse = await lastValueFrom(this._subcontratistsService.getConsultOfSubcontratists(idUser, 1));

      if(subcontratists.error){
        this.hasError = subcontratists.error;
        this.errorStr = subcontratists.msg;
        this.hasError = false;
      }else{
        for(const subcontratist of subcontratists.response){
          if(subcontratist.STATUS == 'Activo'){
            let idDec = await this._encService.decrypt(subcontratist.ID_SUBCONTRATIST);
            subcontratist.NAME = `${subcontratist.NAME} (${idDec})`;

            if(this.employee != null && this.employee.CONTRACT_TYPE == 'Subcontratista' && this.employee.SUBCONTRATIST_ID == idDec){
              this.formGroup.controls['subcontratistId'].setValue(subcontratist.ID_SUBCONTRATIST);
              this.formGroup.controls['subcontratistId'].enable();
            }

            this.subcontratists.push(subcontratist);
          }
        }
        
        this.getCountries();
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado (17).");
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado (18).");
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  private async getCountries() {
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let countries: CountriesListResponse = await lastValueFrom(this._sysAdminService.getCountriesList(idUser, 1));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        let mex = countries.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 = countries.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 = countries.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 countries.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!}`);
              }
            }
          }
        }

        if(this.employee != null){
          let ladaFilt = this.countries.filter(item => item.LADA == this.employee?.CONTACT_LADA);
          if(ladaFilt.length > 0){
            let ladaObj = ladaFilt[0];
            this.formGroup.controls['contactLada'].setValue(`${ladaObj.LADA!}-${ladaObj.NOMECLARUTA_ISO2!}`);
          }
        }

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

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

  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 selectedSpecialties: string[] = [];
        if(this.employee != null){
          let employeeSpecialtiesArr: string[] = JSON.parse(this.employee.SPECIALITY);
          for(const specialtyCode of employeeSpecialtiesArr){
            let specialtyDec = await this._encService.decrypt(specialtyCode);
            let specialtyArr = specialtyDec.split(' - ');

            selectedSpecialties.push(specialtyArr[0]);
          }
        }

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

            if(selectedSpecialties.includes(codeDec)){
              let specialtyVal = this.formGroup.controls['speciality'].value;
              specialtyVal.push(specialty.CODIGO_ESPECIALIDAD);

              this.formGroup.controls['speciality'].setValue(specialtyVal);
            }
          }
        }

        this.specialties = specialtiesArr;
      }

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

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

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

  public changeContractType() {
    let contractType = this.formGroup.controls['contractType'].value;

    if (contractType == "Subcontratista") {
      this.formGroup.controls['subcontratistId'].enable();
    } else {
      this.formGroup.controls['subcontratistId'].disable();
      this.formGroup.controls['subcontratistId'].setValue(null);
    }
  }

  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 (1).");
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado (2).");
      }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);
    }
  }

  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 (9).");
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar("Ocurrió un error inesperado (10).");
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.searchingAddress = false;
    }
  }

  checkNumber(type: string, value: string){
    let validChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    let valueArr = value.split('');
    let validStr = "";

    valueArr.forEach(char => {
      if(validChars.includes(char)){
        validStr += char;
      }
    });

    if(validStr.length > 5){
      validStr = validStr.substring(0, 5);
    }

    if(type == 'exterior'){
      this.formGroup.controls['exteriorNumber'].setValue(validStr);
      this.formGroup.controls['exteriorNumber'].markAsTouched();
    }else{
      this.formGroup.controls['interiorNumber'].setValue(validStr);
      this.formGroup.controls['interiorNumber'].markAsTouched();
    }
  }

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

    valueArr.forEach(char => {
      if(validChars.includes(char)){
        validStr += char;
      }
    });

    if(validStr.length > 11){
      validStr = validStr.substring(0, 11);
    }

    this.formGroup.controls['contactTelephone'].setValue(validStr);
    this.formGroup.controls['contactTelephone'].markAsTouched();
  }

  checkAttached(type: string){
    if(type == 'AU' || type == 'OF' || type == 'CE'){
      let filesByType = this.attached.filter(item => item.type == type);
      let fileInput = this._document.getElementById('file') as HTMLInputElement;
      
      if(type == 'AU' && filesByType.length < 2){
        fileInput.click();
      }else if(type == 'AU' && filesByType.length >= 2){
        this._resourcesService.openSnackBar("El límite de archivos de autorización es de 2 documentos.");
      }
      
      if(type == 'OF' && filesByType.length < 1){
        fileInput.click();
      }else if(type == 'OF' && filesByType.length >= 1){
        this._resourcesService.openSnackBar("El límite de archivos de oficio es de 1 documento.");
      }
      
      if(type == 'CE' && filesByType.length < 2){
        fileInput.click();
      }else if(type == 'CE' && filesByType.length >= 2){
        this._resourcesService.openSnackBar("El límite de archivos de certificación es de 2 documentos.");
      }
    }
  }

  public checkFile(event: any, type: string) {
    if(type != 'AU' && type != 'OF' && type != 'CE'){
      this._resourcesService.openSnackBar(`El tipo de archivo ${type} no está soportado.`);
    }else{
      let extArr = event.target.files[0].name.split(".").reverse();
      let extStr = extArr[0];

      if(type == 'AU'){
        let supportedFilesAU = ['pdf', 'doc', 'docx', 'xls', 'xlsx'];

        if(!supportedFilesAU.includes(extStr)){
          this._resourcesService.openSnackBar(`La extensión ${extStr} no está soportado para autorizaciones.`);
          return;
        }
      }

      if(type == 'OF'){
        let supportedFilesOF = ['pdf', 'xlsx', 'pptx', 'doc', 'docx'];

        if(!supportedFilesOF.includes(extStr)){
          this._resourcesService.openSnackBar(`La extensión ${extStr} no está soportado para oficios.`);
          return;
        }
      }

      if(type == 'CE'){
        let supportedFilesCE = ['doc', 'docx', 'pdf', 'jpg', 'png'];

        if(!supportedFilesCE.includes(extStr)){
          this._resourcesService.openSnackBar(`La extensión ${extStr} no está soportado para certificaciones.`);
          return;
        }
      }
      
      let fileTypes = availableFiles;
      let sizes = Object.keys(fileTypes);
      let extensions = Object.values(fileTypes);
      let maxSizeMB = 0;

      let i = 0;
      extensions.forEach(ext => {
        let size = parseInt(sizes[i]);
  
        if(ext.includes(extStr)) maxSizeMB = size;
        i++;
      });

      if(maxSizeMB == 0){
        this._resourcesService.openSnackBar(`Los archivos ${extStr} no están soportados`);
      }else{
        let maxFileSize = 1048576 * maxSizeMB;
        let fileSize = event.target.files[0].size;

        if(fileSize > maxFileSize){
          this._resourcesService.openSnackBar(`El tamaño del archivo supera el límite de ${maxSizeMB} MB`);
        }else{
          let alreadyAttached = this.attached.filter(file => file.name == event.target.files[0].name && file.size == this.formatBytes(event.target.files[0].size));

          if(alreadyAttached.length > 0){
            this._resourcesService.openSnackBar("El archivo seleccionado ya fue adjuntado.");
          }else{
            this.isUploading = true;
            this.uploadTmp(event.target.files[0], type);
          }
        }
      }
    }
  }

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

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

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

      if(response.error){
        this._resourcesService.openSnackBar(response.msg);
      }else{
        let uploadedFile: TempFileInfo = {
          id: response.response.idArchivo,
          name: fileData.name,
          size: this.formatBytes(fileData.size),
          type: type,
          isFinalFile: false,
        };

        this.attached.push(uploadedFile);
        this.dataSource = new MatTableDataSource(this.attached);
      }

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

  async downloadFile(idFile: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let downloadToken = await lastValueFrom(this._gdelService.getDownloadToken(idFile, idUser, 1));
      let download = this._document.getElementById('download') as HTMLAnchorElement;
      
      download.href = `http://git.ittec.mx/sam/public/api/download-file/${downloadToken.response.TOKEN}/${idUser}/1`;
      download.download = "";
      download.click();
    }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);
      }
    }
  }

  public deleteFiles(element: any) {
    if (element.type === "Autorización") {
      if (element.index == 0) {
        this.authoDoc = this.authoDoc = [];
      } else {
        this.authoDoc2 = this.authoDoc2 = [];
      }
    } else if (element.type === "Certificación") {
      if (element.index == 3) {
        this.certDoc = this.certDoc = [];
      } else {
        this.certDoc2 = this.certDoc2 = [];
      }
    } else {
      this.officeDoc = [];
    }
    this.refactorTable(element.index);
    this.documentsEmployee.push(element.update);
  }

  private refactorTable(index: number) {
    let arrayTemp = [];
    for (let i = 0; i < this.documents.length; i++) {
      if (this.documents[i].index !== index) {
        arrayTemp.push(this.documents[i])
      }
    }
    this.documents = arrayTemp;
    //this.dataSource = new MatTableDataSource(this.documents);
  }

  async deleteFile(id: string){
    try{
      this.disableDelete = true;
      this._resourcesService.openSnackBar('Eliminando archivo...');

      let file = this.attached.filter(item => item.id == id);
      if(file.length == 0){
        this._resourcesService.openSnackBar('El archivo que desea eliminar no existe.');
        this.disableDelete = false;
      }else{
        let isFinalFile = file[0].isFinalFile;
        let idUser = localStorage.getItem('idusuario')!;
        let response: any;

        if(isFinalFile){
          response = await lastValueFrom(this._gdelService.deleteFile({
            'id_user': idUser,
            'id_file': id,
            'linea': 1,
          }));
        }else{
          response = await lastValueFrom(this._gdelService.deleteTempFile({
            'id_user': idUser,
            'id_file': id,
            'linea': 1,
          }));
        }

        if(response.error){
          this._resourcesService.openSnackBar(response.msg);
        }else{
          let attachedAux: TempFileInfo[] = [];
          this.attached.forEach(file => {
            if(file.id != id) attachedAux.push(file);
          });
  
          this.attached = attachedAux;
          this.dataSource = new MatTableDataSource(this.attached);
          this._resourcesService.openSnackBar('El archivo se eliminó correctamente.');
        }
  
        this.disableDelete = false;
      }
    }catch(error: any){
      this.isUploading = false;
      let msg = "";
      if(error.error == undefined){
        msg = 'Ocurrió un error insperado.';
      }else if(error.error.msg == undefined){
        msg = 'Ocurrió un error insperado.';
      }else{
        msg = error.error.msg;
      }

      this._resourcesService.openSnackBar(msg);
      this.disableDelete = false;
    }
  }

  public alert() {
    if (this.idEmployee == "0") {
      let docsAU = this.attached.filter(item => item.type == 'AU');
      if(docsAU.length < 1){
        this._resourcesService.openSnackBar("Para registrar al empleado se requiere adjuntar al menos un documento de autorización.");
        return;
      }

      this._dialog.open(AlertComponent, {
        data: {
          title: 'Registrar Empleado',
          description: '¿Está seguro que desea registrar al empleado?',
          icon: 'warning',
        },
        disableClose: true,
      }).afterClosed().subscribe((result) => {
        if (result) {
          this.storeEmployee();
        }
      });
    } else {
      let docsAU = this.attached.filter(item => item.type == 'AU');
      if(docsAU.length < 1){
        this._resourcesService.openSnackBar("Para registrar al empleado se requiere adjuntar al menos un documento de autorización.");
        return;
      }

      this._dialog.open(AlertComponent, {
        data: {
          title: 'Actualizar Empleado',
          description: '¿Está seguro que desea actualizar al empleado?',
          icon: 'warning',
        },
        disableClose: true,
      }).afterClosed().subscribe((result) => {
        if (result) {
          this.updateEmployee();
        }
      });
    }

  }

  private async storeEmployee() {
    try{
      this.isLoadingForm = true;

      if(this.formGroup.invalid){
        this._resourcesService.openSnackBar("Por favor complete todos los campos requeridos del formulario.");
        this.formGroup.markAllAsTouched();
      }else{
        let formValue = this.formGroup.getRawValue();
        let formData = new FormData();
        let subcontratist = formValue.subcontratistId == null ? '-' : formValue.subcontratistId;
        let idUser = localStorage.getItem('idusuario')!;

        formData.append('id_user', idUser);
        formData.append('linea', '1');
        formData.append('USER_ID', formValue.userId);
        formData.append('WORKTEAM_ID', formValue.workteamId);
        formData.append('CONTRACT_TYPE', formValue.contractType);
        formData.append('SUBCONTRATIST_ID', subcontratist);
        formData.append('FOREIGNER', formValue.foreigner);

        let specialtyStr = JSON.stringify(formValue.speciality);
        formData.append('SPECIALITY', specialtyStr);

        let rfc = formValue.RFC == null ? '-' : await this._encService.encrypt(formValue.RFC);
        let tax = formValue.tax == null ? '-' : await this._encService.encrypt(formValue.tax);

        formData.append('RFC', rfc);
        formData.append('TAX', tax);
  
        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._resourcesService.openSnackBar(`La colonia ${country} 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 contactName = await this._encService.encrypt(formValue.contactName);
        formData.append('CONTACT_NAME', contactName);
  
        let lada = formValue.contactLada;
        let ladaArr = lada.split('-');
        ladaArr.pop();
        
        let ladaStr = await this._encService.encrypt(ladaArr.join('-'));
        let phone = await this._encService.encrypt(formValue.contactTelephone);
        let address = await this._encService.encrypt(formValue.contactAddress);
        
        formData.append('CONTACT_LADA', ladaStr);
        formData.append('CONTACT_TELEPHONE', phone);
        formData.append('CONTACT_ADDRESS', address);

        let attachedStr = JSON.stringify(this.attached);
        formData.append('ATTACHED', attachedStr);

        let employeeBoss = formValue.employeeBossId;
        if (employeeBoss !== '' && employeeBoss !== null && employeeBoss !== undefined) {
          employeeBoss = employeeBoss.toString().trim();
          if (!employeeBoss.includes('(') || !employeeBoss.includes(')')) {
            this._resourcesService.openSnackBar('Debe seleccionar un encargado válido o no seleccionar ninguno.');
            return;
          }
          try {
            employeeBoss = employeeBoss.split('(')[1].split(')')[0];
          } catch (error) {
            this._resourcesService.openSnackBar(`Ocurrió un error al obtener el ID del empleado`);
            return;
          }

          let validateEmployee = this.arrEmployee.some((employeesListItem: EmployeesListItem) => employeesListItem.ID_EMPLOYEE.toString() === employeeBoss.toString());
          if (!validateEmployee) {
            this._resourcesService.openSnackBar(`El empleado ingresado no existe.`);
            return;
          }
        } else {
          employeeBoss = null;
        }
        
        formData.append('EMPLOYEE_BOSS', employeeBoss);

        await lastValueFrom(this._employeeService.storeEmployee(formData));

        this._resourcesService.openSnackBar("El empleado se registró correctamente.");
        this.isLoadingForm = false;
        this.goBack(1);
      }
    }catch(error: any){
      let msg = "";
      if(error.error == undefined){
        msg = 'Ocurrió un error insperado.';
      }else if(error.error.msg == undefined){
        msg = 'Ocurrió un error insperado.';
      }else{
        msg = error.error.msg;
      }

      this._resourcesService.openSnackBar(msg);
      this.isLoadingForm = false;
    }
  }

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

  private async updateEmployee() {
    try{
      this.isLoadingForm = true;

      if(this.formGroup.invalid){
        this._resourcesService.openSnackBar("Por favor complete todos los campos requeridos del formulario.");
        this.formGroup.markAllAsTouched();
      }else{
        let formValue = this.formGroup.getRawValue();
        let formData = new FormData();
        let subcontratist = formValue.subcontratistId == null || formValue.subcontratistId == '' ? '-' : formValue.subcontratistId;
        let idUser = localStorage.getItem('idusuario')!;
        let idEmployee = await this._encService.encrypt(this.idEmployee);

        formData.append('id_user', idUser);
        formData.append('linea', '1');
        formData.append('id_employee', idEmployee);
        formData.append('USER_ID', formValue.userId);
        formData.append('WORKTEAM_ID', formValue.workteamId);
        formData.append('CONTRACT_TYPE', formValue.contractType);
        formData.append('SUBCONTRATIST_ID', subcontratist);
        formData.append('FOREIGNER', formValue.foreigner);

        let specialtyStr = JSON.stringify(formValue.speciality);
        formData.append('SPECIALITY', specialtyStr);

        let rfc = formValue.RFC == null ? '-' : await this._encService.encrypt(formValue.RFC);
        let tax = formValue.tax == null ? '-' : await this._encService.encrypt(formValue.tax);

        formData.append('RFC', rfc);
        formData.append('TAX', tax);
  
        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 ${country} 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 contactName = await this._encService.encrypt(formValue.contactName);
        formData.append('CONTACT_NAME', contactName);
  
        let lada = formValue.contactLada;
        let ladaArr = lada.split('-');
        ladaArr.pop();
        
        let ladaStr = await this._encService.encrypt(ladaArr.join('-'));
        let phone = await this._encService.encrypt(formValue.contactTelephone);
        let address = await this._encService.encrypt(formValue.contactAddress);
        
        formData.append('CONTACT_LADA', ladaStr);
        formData.append('CONTACT_TELEPHONE', phone);
        formData.append('CONTACT_ADDRESS', address);

        let attachedStr = JSON.stringify(this.attached);
        formData.append('ATTACHED', attachedStr);

        let employeeBoss = formValue.employeeBossId;
        if (employeeBoss !== '' && employeeBoss !== null && employeeBoss !== undefined) {
          employeeBoss = employeeBoss.toString().trim();
          if (!employeeBoss.includes('(') || !employeeBoss.includes(')')) {
            this._resourcesService.openSnackBar('Debe seleccionar un encargado válido o no seleccionar ninguno.');
            return;
          }
          try {
            employeeBoss = employeeBoss.split('(')[1].split(')')[0];
          } catch (error) {
            this._resourcesService.openSnackBar(`Ocurrió un error al obtener el ID del empleado`);
            return;
          }
          
          let validateEmployee = this.arrEmployee.some((employeesListItem: EmployeesListItem) => employeesListItem.ID_EMPLOYEE.toString() === employeeBoss.toString());
          if (!validateEmployee) {
            this._resourcesService.openSnackBar(`El empleado ingresado no existe.`);
            return;
          }
        } else {
          employeeBoss = null;
        }

        formData.append('EMPLOYEE_BOSS', employeeBoss);

        await lastValueFrom(this._employeeService.updateEmployee(formData));

        this._resourcesService.openSnackBar("El empleado se actualizó correctamente.");
        this.isLoadingForm = false;
        this.goBack(1);
      }
    }catch(error: any){
      let msg = "";
      if(error.error == undefined){
        msg = 'Ocurrió un error insperado.';
      }else if(error.error.msg == undefined){
        msg = 'Ocurrió un error insperado.';
      }else{
        msg = error.error.msg;
      }

      this._resourcesService.openSnackBar(msg);
      this.isLoadingForm = false;
    }
  }
}
