import { Component, Inject, OnInit } from '@angular/core';
import { SecurityManagementDetailsResponse, SecurityManagementListItem } from '../../../../interfaces/corrective-maintenance.interface';
import { CountriesList, CountriesListResponse } from '../../../../interfaces/countries-list.interface';
import { UserResponse, UsersResponse } from '../../../../interfaces/users.interface';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { lastValueFrom, map, Observable, startWith } from 'rxjs';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { SystemAdminService } from '../../../../services/system-admin.service';
import { ResourcesService } from '../../../../services/resources.service';
import { UsersProfilesService } from '../../../../services/users-profiles.service';
import { FunctionsService } from '../../../../services/functions.service';
import { EncService } from '../../../../services/enc.service';
import { CorrectiveMaintenanceService } from '../../../../services/corrective-maintenance.service';

@Component({
    selector: 'app-security-management-form',
    templateUrl: './security-management-form.component.html',
    styleUrl: './security-management-form.component.css',
    standalone: false
})
export class SecurityManagementFormComponent implements OnInit {
  action: string;
  isNew: boolean;
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;
  idSecurityManagement: string;
  securityManagement: SecurityManagementListItem | null;

  countries: CountriesList[];
  ladasStr: string[];
  users: UserResponse[];
  usersStr: string[];
  
  flags: Map<string, string>;
  formGroup: FormGroup;

  filteredLadas1?: Observable<string[]>;
  filteredLadas2?: Observable<string[]>;
  filteredUsers?: Observable<string[]>;

  constructor(
    @Inject(MAT_DIALOG_DATA) private _data: any,
    private _sysAdminService: SystemAdminService,
    private _resourcesService: ResourcesService,
    private _usersProfilesService: UsersProfilesService,
    private _functionsService: FunctionsService,
    private _dialogRef: MatDialogRef<SecurityManagementFormComponent>,
    private _encService: EncService,
    private _correctiveMaintenanceService: CorrectiveMaintenanceService,
  ) {
    this.action = '';
    this.isNew = true;
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = '';
    this.idSecurityManagement = '';
    this.securityManagement = null;

    this.countries = [];
    this.ladasStr = [];
    this.users = [];
    this.usersStr = [];

    this.flags = new Map();
    this.formGroup = new FormGroup({
      idSecurityManagementControl: new FormControl({value: '', disabled: true}),
      phoneLada1Control: new FormControl('', [Validators.required, Validators.maxLength(8)]),
      phone1Control: new FormControl('', [Validators.required, Validators.minLength(10), Validators.maxLength(11)]),
      phone1ExtensionControl: new FormControl('', Validators.maxLength(5)),
      phoneLada2Control: new FormControl('', Validators.maxLength(8)),
      phone2Control: new FormControl('', [Validators.minLength(10), Validators.maxLength(11)]),
      phone2ExtensionControl: new FormControl('', Validators.maxLength(5)),
      managementEmailControl: new FormControl('', [Validators.required, Validators.email]),
      managerControl: new FormControl('', Validators.required),
      managerEmailControl: new FormControl({value: '', disabled: true}),
    });
  }

  ngOnInit(): void {
    this.action = this._data.type;
    this.isNew = this._data.type == 'Registrar';
    this.idSecurityManagement = this._data.idSecManage;

    if(this.isNew){
      this.getLadas();
    }else{
      this.getSecurityManagement();
    }

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

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

    this.filteredUsers = this.formGroup.controls['managerControl'].valueChanges.pipe(
      startWith(''),
      map(value => this._filterUsers(value || '')),
    )
  }

  private _filterUsers(value: string): string[]{
    let filterValue = value.toLowerCase();
    return this.usersStr.filter(item => item.toLowerCase().includes(filterValue));
  }

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

  async getSecurityManagement(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let idSecurityManagementEnc = await this._encService.encrypt(this._data.idSecManage);
      let securityManagement: SecurityManagementDetailsResponse = await lastValueFrom(this._correctiveMaintenanceService.getSecurityManagement(
        idSecurityManagementEnc,
        idUser,
        1
      ));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        this.formGroup.controls['idSecurityManagementControl'].setValue(this._data.idSecManage);
        this.formGroup.controls['phone1Control'].setValue(securityManagement.response.TELEFONO_PRINCIPAL);
        this.formGroup.controls['phone1ExtensionControl'].setValue(securityManagement.response.EXTENSION_TELEFONO_PRINCIPAL);
        this.formGroup.controls['phone2Control'].setValue(securityManagement.response.TELEFONO_SECUNDARIO);
        this.formGroup.controls['phone2ExtensionControl'].setValue(securityManagement.response.EXTENSION_TELEFONO_SECUNDARIO);
        this.formGroup.controls['managementEmailControl'].setValue(securityManagement.response.CORREO_GERENCIA);

        this.securityManagement = securityManagement.response;
        this.getLadas();
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getLadas(){
    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.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.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.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);

            if(country.LADA != '' && country.NOMECLARUTA_ISO2 != '' && country.NOMECLARUTA_ISO2 != '0'){
              let currentURI = window.location.href;
              let currentURIArr = currentURI.split('#');
              let flagURI = `${currentURIArr[0]}assets/img/flags/${country.NOMECLARUTA_ISO2!}.png`;
              let fileExists = await this._resourcesService.fileExists(flagURI);

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

        if(this.securityManagement != null){
          for(const lada of this.ladasStr){
            let ladaArr = lada.split('-');
            ladaArr.pop();

            let ladaStr = ladaArr.join('-');
            if(ladaStr == this.securityManagement.LADA_TELEFONO_PRINCIPAL){
              this.formGroup.controls['phoneLada1Control'].setValue(lada);
            }
            
            if(ladaStr == this.securityManagement.LADA_TELEFONO_SECUNDARIO){
              this.formGroup.controls['phoneLada2Control'].setValue(lada);
            }
          }
        }

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

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

  async getUsers(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let users: UsersResponse = await lastValueFrom(this._usersProfilesService.getUsers(idUser, 1));
      
      this.hasError = users.error;
      this.errorStr = users.msg;

      if(!this.hasError){
        console.log(users.response);
        for(const user of users.response){
          user.IDUSUARIO = await this._encService.decrypt(user.IDUSUARIO);
          let userName = this._functionsService.buildName(user.NOMBRE, user.APEPAT, user.APEMAT);
          user.NOMBRE = `${userName} (${user.IDUSUARIO})`;

          if(user.ESTATUS == 'Activo'){
            this.users.push(user);
            this.usersStr.push(user.NOMBRE);
          }

          if(this.securityManagement != null){
            let managerArr = this.securityManagement.GERENTE.split('(').reverse();
            let managerStr = managerArr[0].replace(')', '');

            if(managerStr == user.IDUSUARIO){
              this.formGroup.controls['managerControl'].setValue(`${userName} (${user.IDUSUARIO})`);
              this.formGroup.controls['managerEmailControl'].setValue(user.EMAIL);
            }
          }
        }
      }

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

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

  validateNumber(control: string, value: string, type: string){
    let validChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    let maxLength = 0;

    switch(type){
      case 'phone': maxLength = 11; break;
      case 'ext': maxLength = 5; break;
    }

    let valueArr = value.split('');
    let validVal = '';
    
    valueArr.forEach(char => {
      if(validChars.includes(char)){
        validVal += char;
      }
    });

    validVal = validVal.substring(0, maxLength);
    this.formGroup.controls[control].markAsTouched();
    this.formGroup.controls[control].setValue(validVal);
  }

  verifyUser(value: string){
    if(value != null && value != undefined && value != ''){
      let idUserArr = value.split('(').reverse();
      let idUserStr = idUserArr[0].replace(')', '');
      let userFilt = this.users.filter(user => user.IDUSUARIO == idUserStr);

      if(userFilt.length == 0){
        this.formGroup.controls['managerEmailControl'].setValue(null);
        this._resourcesService.openSnackBar('El usuario encargado seleccionado es inválido.');
      }else{
        this.formGroup.controls['managerEmailControl'].setValue(userFilt[0].EMAIL);
      }
    }else{
      this.formGroup.controls['managerEmailControl'].setValue(null);
    }
  }

  async saveSecurityManagement(){
    let formValue = this.formGroup.getRawValue();
    let lada1Arr = formValue.phoneLada1Control.split('-');
    let lada1Str = lada1Arr[0];
    let validLada1 = this.countries.filter(item => item.LADA == lada1Str);

    if(validLada1.length == 0){
      this._resourcesService.openSnackBar('La lada del teléfono principal es inválida.');
      return;
    }

    if(formValue.phoneLada2Control != '' && formValue.phoneLada2Control != null && formValue.phoneLada2Control != undefined){
      let lada2Arr = formValue.phoneLada2Control.split('-');
      let lada2Str = lada2Arr[0];
      let validLada2 = this.countries.filter(item => item.LADA == lada2Str);

      if(validLada2.length == 0){
        this._resourcesService.openSnackBar('La lada del teléfono secundario es inválida.');
        return;
      }
    }

    let userArr = formValue.managerControl.split('(').reverse();
    let userStr = userArr[0].replace(')', '');
    let userFilt = this.users.filter(user => user.IDUSUARIO == userStr);
    if(userFilt.length == 0){
      this._resourcesService.openSnackBar('El usuario encargado seleccionado es inválido');
      return;
    }

    let formEnc = await this._encService.encrypt(JSON.stringify(formValue));
    this._dialogRef.close(formEnc);
  }
}
