import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { PriorityInterface } from '../../../system-admin/system-params/system-params.component';
import { CountersListItem, MagnitudesListItem, UnitsByMagnitudeListItem, UnitsByMagnitudeListResponse } from '../../../../interfaces/counters-activators.interface';
import { Activator } from '../../../../interfaces/activator.interface';
import { SymptomList } from '../../../../interfaces/failure-analysis/symptom.interface';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { lastValueFrom, map, Observable, startWith } from 'rxjs';
import { MatDialog } from '@angular/material/dialog';
import { EncService } from '../../../../services/enc.service';
import { ResourcesService } from '../../../../services/resources.service';
import { FailureAnalysisService } from '../../../../services/failure-analysis/failure-analysis.service';
import { SystemAdminService } from '../../../../services/system-admin.service';
import { FunctionsService } from '../../../../services/functions.service';
import { validColorValidator } from 'ngx-colors';
import { CustomRepeatComponent } from '../../../preventive-maintenance/work-orders/custom-repeat/custom-repeat.component';
import { CounterDetailsComponent } from '../../counters-management/counter-details/counter-details.component';

@Component({
    selector: 'app-activator-fields',
    templateUrl: './activator-fields.component.html',
    styleUrl: './activator-fields.component.css',
    standalone: false
})
export class ActivatorFieldsComponent implements OnInit {
  @Input() formType: string;
  @Input() orderPriorities: PriorityInterface[];
  @Input() counters: CountersListItem[];
  @Input() magnitudes: MagnitudesListItem[];
  @Input() activator: Activator | null;
  @Input() action: string;
  @Input() activatorType: string;
  @Output() returnFormValue = new EventEmitter<string>();
  @Output() closeFormDialog = new EventEmitter<string>();

  startDate: Date | null;
  selectedSymptom: SymptomList | null;
  customDisplayed: string;
  customValue: string;
  loadingSymptoms: boolean;
  loadingUnits: boolean;

  hoursArr: any[];
  symptoms: SymptomList[];
  symptomsStr: string[];
  units: UnitsByMagnitudeListItem[];

  activatorFieldsFormGroup: FormGroup;
  filteredSymptoms?: Observable<string[]>;

  MONTHS = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
  DAYS = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];

  constructor(
    private _dialog: MatDialog,
    private _encService: EncService,
    private _resourcesService: ResourcesService,
    private _failureAnalysisService: FailureAnalysisService,
    private _sysAdminService: SystemAdminService,
    private _functionsService: FunctionsService,
  ) {
    this.formType = '';
    this.orderPriorities = [];
    this.counters = [];
    this.magnitudes = [];
    this.activator = null;
    this.action = '';
    this.activatorType = '';

    this.startDate = null;
    this.selectedSymptom = null;
    this.customDisplayed = '';
    this.customValue = '';
    this.loadingSymptoms = false;
    this.loadingUnits = false;

    this.hoursArr = [];
    this.symptoms = [];
    this.symptomsStr = [];
    this.units = [];
    
    this.activatorFieldsFormGroup = new FormGroup({
      //Configuración del activador
      activatorIDControl: new FormControl({value: '', disabled: true}, Validators.required),
      activatorTypeControl: new FormControl('', Validators.required),
      priorityControl: new FormControl('', Validators.required),
      eventColorControl: new FormControl("rgb(79, 195, 255)", [validColorValidator(), Validators.required]),
      colorPickerControl: new FormControl("rgb(79, 195, 255)"),
      counterControl: new FormControl('', Validators.required),
      //Configuración de las condiciones de activación
      startDateControl: new FormControl({value: this.startDate, disabled: true}, Validators.required),
      startHourControl: new FormControl({value: '', disabled: true}, Validators.required),
      repeatControl: new FormControl({value: '', disabled: true}, Validators.required),
      symptomControl: new FormControl({value: '', disabled: true}, Validators.required),
      magnitudeControl: new FormControl({value: '', disabled: true}, Validators.required),
      unitControl: new FormControl({value: '', disabled: true}, Validators.required),
      minValueControl: new FormControl({value: '', disabled: true}, Validators.required),
      maxValueControl: new FormControl({value: '', disabled: true}, Validators.required),
      comparisonControl: new FormControl({value: '', disabled: true}, Validators.required),
      limitValueControl: new FormControl({value: '', disabled: true}, Validators.required),
    });
  }

  ngOnInit(): void {
    this.fillHours();

    this.activatorFieldsFormGroup.controls['startDateControl'].valueChanges.subscribe((startDate: Date) => {
      if(startDate != null && startDate != undefined){
        this.startDate = startDate;
        this.activatorFieldsFormGroup.controls['repeatControl'].enable();
      }
    });

    this.activatorFieldsFormGroup.controls['repeatControl'].valueChanges.subscribe((repeat: string) => {
      if(repeat == 'PE'){
        let dialogRef = this._dialog.open(CustomRepeatComponent, {
          data: {
            date: this.startDate,
            repeat: null,
          },
          width: '540px',
          maxWidth: '540px',
          disableClose: true,
        });
  
        dialogRef.afterClosed().subscribe(res => {
          if(res != null && res != undefined && res != ""){
            this.customRepeat(res);
          }else{
            this.activatorFieldsFormGroup.controls['repeatControl'].setValue('NR');
          }
        })
      }
    });

    this.activatorFieldsFormGroup.controls['activatorTypeControl'].valueChanges.subscribe(activatorType => {
      this.clearFormFields();

      let counter = this.activatorFieldsFormGroup.controls['counterControl'].value;
      if(activatorType == 'CA'){
        let calendarFields = ['startDateControl', 'startHourControl', 'repeatControl'];
        calendarFields.forEach(field => this.activatorFieldsFormGroup.controls[field].enable());
      }else if(activatorType == 'SI'){
        let calendarFields = ['startDateControl', 'startHourControl', 'repeatControl'];
        calendarFields.forEach(field => this.activatorFieldsFormGroup.controls[field].enable());

        if(counter != null && counter != undefined && counter != ''){
          this.filtCounter(counter);
        }
      }else if(activatorType == 'ME'){
        let extentFields = ['magnitudeControl', 'minValueControl', 'maxValueControl'];
        extentFields.forEach(field => this.activatorFieldsFormGroup.controls[field].enable());
      }else if(activatorType == 'VA'){
        let valueFields = ['magnitudeControl', 'comparisonControl', 'limitValueControl'];
        valueFields.forEach(field => this.activatorFieldsFormGroup.controls[field].enable());
      }else{
        this._resourcesService.openSnackBar('El tipo de activador seleccionado es inválido.');
      }
    });

    this.activatorFieldsFormGroup.controls['counterControl'].valueChanges.subscribe(counter => {
      let activatorType = this.activatorFieldsFormGroup.controls['activatorTypeControl'].value;
      if(activatorType == 'SI' && activatorType != null && activatorType != undefined && activatorType != ''){
        this.filtCounter(counter);
      }
    });

    this.filteredSymptoms = this.activatorFieldsFormGroup.controls['symptomControl'].valueChanges.pipe(
      startWith(''),
      map((value: string) => this._filterSymptoms(value || '')),
    );
    
    this.activatorFieldsFormGroup.controls['eventColorControl'].valueChanges.subscribe((color) => {
      if(this.activatorFieldsFormGroup.controls['eventColorControl'].valid){
        this.activatorFieldsFormGroup.controls['colorPickerControl'].setValue(color, {
          emitEvent: false,
        });
      }
    });

    this.activatorFieldsFormGroup.controls['colorPickerControl'].valueChanges.subscribe((color) => {
      this.activatorFieldsFormGroup.controls['eventColorControl'].setValue(color, {
        emitEvent: false,
      })
    });

    if(this.activatorType != ''){
      this.activatorFieldsFormGroup.controls['activatorTypeControl'].setValue(this.activatorType);
      this.activatorFieldsFormGroup.controls['activatorTypeControl'].disable();
    }
    
    this.init();
  }

  fillHours(){
    for(let i = 0; i  < 24; i++){
      let period = i < 12 ? 'AM' : 'PM';
      let hourInt = i > 12 ? i - 12 : i;
      let hourStr = hourInt < 10 ? `0${hourInt}` : `${hourInt}`;
      let hour = i < 10 ? `0${i}` : `${i}`;

      this.hoursArr.push({ value: `${hour}:00:00`, label: `${hourStr}:00 ${period}` });
      this.hoursArr.push({ value: `${hour}:15:00`, label: `${hourStr}:15 ${period}` });
      this.hoursArr.push({ value: `${hour}:30:00`, label: `${hourStr}:30 ${period}` });
      this.hoursArr.push({ value: `${hour}:45:00`, label: `${hourStr}:45 ${period}` });
    }
  }

  customRepeat(value: string){
    let resObj = JSON.parse(value);
    let repeatEvery = resObj.repeatEvery.split('|');
    let customRepeat = 'Repetir cada ';

    if(repeatEvery[0] != "1"){
      customRepeat += repeatEvery[0];
    }

    switch(repeatEvery[1]){
      case "0": customRepeat += repeatEvery[0] != "1" ? ' días' : ' día'; break;
      case "1": customRepeat += repeatEvery[0] != "1" ? ' semanas' : ' semana'; break;
      case "2": customRepeat += repeatEvery[0] != "1" ? ' meses' : ' mes'; break;
      case "3": customRepeat += repeatEvery[0] != "1" ? ' años' : ' año'; break;
    }

    let days = 0;
    let daysValues = Object.values(resObj.repeatOn);
    let daysStr = '';
    let cont = 0;
    
    daysValues.forEach(val => {
      if(val){
        daysStr += `${this.DAYS[cont]}, `; 
        days++;
      }

      cont++;
    });

    daysStr = daysStr.substring(0, daysStr.length - 2);
    
    if(days > 1){
      customRepeat += ' los días: ';
    }else{
      customRepeat += ' el día: ';
    }

    customRepeat += daysStr;

    let endsAt = resObj.endsAt.split('|');
    if(endsAt[0] == 'O'){
      let dateArr = endsAt[1].split('-').reverse();
      customRepeat += '. Finaliza el ' + dateArr[0] + ' de ' + this.MONTHS[parseInt(dateArr[1])] + ' del ' + dateArr[2] + '.';
    }else if(endsAt[0] == 'A'){
      let after = endsAt[2];
      customRepeat += '. Finaliza después de ' + after + ' repeti';

      if(after == '1'){
        customRepeat += 'ción.';
      }else{
        customRepeat += 'ciones.';
      }
    }

    this.customDisplayed = customRepeat.replace('  ', ' ');
    this.customValue = value;
  }

  clearFormFields(){
    let fieldsArr = ['startDateControl', 'startHourControl', 'repeatControl', 'symptomControl', 'magnitudeControl', 
    'unitControl', 'minValueControl', 'maxValueControl', 'comparisonControl', 'limitValueControl'];

    fieldsArr.forEach(fieldStr => {
      let control = this.activatorFieldsFormGroup.controls[fieldStr];

      control.setValue(null);
      control.disable();
    });

    this.selectedSymptom = null;
  }

  filtCounter(idCounter: string){
    let counterFilt = this.counters.filter(item => item.ID_CONTADOR == idCounter);
    if(counterFilt.length <= 0){
      this._resourcesService.openSnackBar('El contador seleccionado es inválido');
    }else{
      this.searchSymptoms(counterFilt[0].CODIGO_EQUIPAMIENTO);
    }
  }

  async searchSymptoms(equipmentCode: string){
    try{
      this.loadingSymptoms = true;
      this.activatorFieldsFormGroup.controls['symptomControl'].disable();
      this.activatorFieldsFormGroup.controls['symptomControl'].setValue(null);

      const user: string = this._resourcesService.getUser();
      const line: number = this._resourcesService.getLineNumber();
      let symptoms = await lastValueFrom(this._failureAnalysisService.getSymptomsByEquipment(equipmentCode, user, line));

      if(symptoms.error){
        this._resourcesService.openSnackBar(symptoms.msg);
      }else{
        let symptomsArr: SymptomList[] = [];
        let symptomsStrArr: string[] = [];

        for(const symptom of symptoms.response){
          symptomsStrArr.push(`${symptom.NOMBRE_SINTOMA} (${symptom.ID_SINTOMA})`);

          let idEnc = await this._encService.encrypt(`${symptom.ID_SINTOMA}`);
          symptom.ID_SINTOMA = idEnc;
          
          symptomsArr.push(symptom);
        }

        this.symptoms = symptomsArr;
        this.symptomsStr = symptomsStrArr;
        this.activatorFieldsFormGroup.controls['symptomControl'].enable();
      }

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

  private _filterSymptoms(value: string): string[]{
    const filterValue = value.toLowerCase();
    return this.symptomsStr.filter(option => option.toLowerCase().includes(filterValue));
  }

  async init(){
    if(this.action == 'editar'){
      this.activatorFieldsFormGroup.controls['activatorIDControl'].setValue(this.activator!.IDACTIVADOR as string);
      this.activatorFieldsFormGroup.controls['priorityControl'].setValue(this.activator!.PRIORIDAD);

      for(const counter of this.counters){
        if(counter.ID_CONTADOR == this.activator!.CONTADOR){
          this.activatorFieldsFormGroup.controls['counterControl'].setValue(this.activator!.CONTADOR);
        }
      }

      let conditionsObj = JSON.parse(this.activator!.CONDICIONES);
      if(this.activator!.TIPOACTIVADOR == 'Calendario'){
        let startDate = new Date(conditionsObj.startDate);
        
        this.activatorFieldsFormGroup.controls['activatorTypeControl'].setValue('CA');
        this.activatorFieldsFormGroup.controls['eventColorControl'].setValue(conditionsObj.color);
        this.activatorFieldsFormGroup.controls['startDateControl'].setValue(startDate);
        this.activatorFieldsFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
        this.activatorFieldsFormGroup.controls['repeatControl'].setValue(conditionsObj.repeat, {
          emitEvent: false,
        });
      }else if(this.activator!.TIPOACTIVADOR == 'Sintoma'){
        let startDate = new Date(conditionsObj.startDate);

        this.activatorFieldsFormGroup.controls['activatorTypeControl'].setValue('SI');
        this.activatorFieldsFormGroup.controls['eventColorControl'].setValue(conditionsObj.color);
        this.activatorFieldsFormGroup.controls['symptomControl'].setValue(conditionsObj.sign);
        this.activatorFieldsFormGroup.controls['startDateControl'].setValue(startDate);
        this.activatorFieldsFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
        this.activatorFieldsFormGroup.controls['repeatControl'].setValue(conditionsObj.repeat, {
          emitEvent: false,
        });

        if(conditionsObj.repeat == 'PE'){
          let customRepeatStr = this._functionsService.activatorCustomRepeat(conditionsObj.customRepeat);
          let customRepeatArr = customRepeatStr.split('||');

          this.customDisplayed = customRepeatArr[0];
          this.customValue = customRepeatArr[1];
          console.log(customRepeatArr);
          
        }
      }else if(this.activator!.TIPOACTIVADOR == 'Medida'){
        this.activatorFieldsFormGroup.controls['activatorTypeControl'].setValue('ME');
        this.activatorFieldsFormGroup.controls['eventColorControl'].setValue(conditionsObj.color);
        this.activatorFieldsFormGroup.controls['minValueControl'].setValue(conditionsObj.minValue);
        this.activatorFieldsFormGroup.controls['maxValueControl'].setValue(conditionsObj.maxValue);

        let magnitudeArr = conditionsObj.magnitude.split('(').reverse();
        let magnitudeStr = magnitudeArr[0].replace(')', '');

        for(const magnitude of this.magnitudes){
          let idDec = await this._encService.decrypt(magnitude.ID_MAGNITUD);
          if(idDec == magnitudeStr){
            this.activatorFieldsFormGroup.controls['magnitudeControl'].setValue(magnitude.ID_MAGNITUD);
          }
        }

        let idMagnitudeEnc = await this._encService.encrypt(magnitudeStr);
        await this.searchMagnitudeUnits(idMagnitudeEnc);

        let unitArr = conditionsObj.unit.split('(').reverse();
        let unitStr = unitArr[0].replace(')', '');
        let unitArr0 = unitStr.split(' - ');
        let unitStr0 = unitArr0[0];

        for(const unit of this.units){
          let idDec = await this._encService.decrypt(unit.ID_UNIDAD);
          if(idDec == unitStr0){
            this.activatorFieldsFormGroup.controls['unitControl'].setValue(unit.ID_UNIDAD);
          }
        }
      }else if(this.activator!.TIPOACTIVADOR == 'Valor'){
        this.activatorFieldsFormGroup.controls['activatorTypeControl'].setValue('VA');
        this.activatorFieldsFormGroup.controls['eventColorControl'].setValue(conditionsObj.color);
        this.activatorFieldsFormGroup.controls['comparisonControl'].setValue(conditionsObj.comparison);
        this.activatorFieldsFormGroup.controls['limitValueControl'].setValue(conditionsObj.limitValue);

        let magnitudeArr = conditionsObj.magnitude.split('(').reverse();
        let magnitudeStr = magnitudeArr[0].replace(')', '');

        for(const magnitude of this.magnitudes){
          let idDec = await this._encService.decrypt(magnitude.ID_MAGNITUD);
          if(idDec == magnitudeStr){
            this.activatorFieldsFormGroup.controls['magnitudeControl'].setValue(magnitude.ID_MAGNITUD);
          }
        }

        let idMagnitudeEnc = await this._encService.encrypt(magnitudeStr);
        await this.searchMagnitudeUnits(idMagnitudeEnc);

        let unitArr = conditionsObj.unit.split('(').reverse();
        let unitStr = unitArr[0].replace(')', '');
        let unitArr0 = unitStr.split(' - ');
        let unitStr0 = unitArr0[0];

        for(const unit of this.units){
          let idDec = await this._encService.decrypt(unit.ID_UNIDAD);
          if(idDec == unitStr0){
            this.activatorFieldsFormGroup.controls['unitControl'].setValue(unit.ID_UNIDAD);
          }
        }
      }
    }
  }

  async searchMagnitudeUnits(idMagniude: string){
    try{
      this.loadingUnits = true;
      this.activatorFieldsFormGroup.controls['unitControl'].setValue(null);
      this.activatorFieldsFormGroup.controls['unitControl'].disable();

      let idUser = localStorage.getItem('idusuario')!;
      let units: UnitsByMagnitudeListResponse = await lastValueFrom(this._sysAdminService.getUnitsByMagnitude(idMagniude, idUser, 1));

      if(units.error){
        this._resourcesService.openSnackBar(units.msg);
      }else{
        let unitsArr: UnitsByMagnitudeListItem[] = [];
        for(const unit of units.response){
          let idDec = await this._encService.decrypt(unit.ID_UNIDAD);
          unit.NOMBRE_UNIDAD = `${unit.NOMBRE_UNIDAD} (${idDec})`;
          
          if(unit.ESTADO == 'Activo'){
            unitsArr.push(unit);
          }
        }

        this.units = unitsArr;
        if(this.units.length > 0){
          this.activatorFieldsFormGroup.controls['unitControl'].enable();
        }
      }

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

  async counterDetails(value: string){
    if(value != null && value != undefined && value != ''){
      let counterFilt = this.counters.filter(item => item.ID_CONTADOR == value);
      if(counterFilt.length > 0){
        let idCounterEnc = await this._encService.encrypt(value);
        this._dialog.open(CounterDetailsComponent, {
          width: '540px',
          maxWidth: '540px',
          data: {
            idCounter: idCounterEnc,
            includeActivator: false,
            idActivator: null,
          }
        });
        console.log(idCounterEnc);
      }else{
        this._resourcesService.openSnackBar('El contador seleccionado es inválido.');
      }
    }
  }

  async verifySymptom(value: string){
    let valueArr = value.split('(').reverse();
    let symptomID = valueArr[0].replace(')', '');

    if(symptomID != "" && symptomID != null && symptomID != undefined){
      let symptomFilt: SymptomList | null = null;
      for(const symptom of this.symptoms){
        let idDec = await this._encService.decrypt(symptom.ID_SINTOMA);
        if(idDec == symptomID){
          symptomFilt = symptom;
        }
      }

      if(symptomFilt == null){
        this._resourcesService.openSnackBar('El síntoma seleccionado es incorrecto.');
      }else{
        this.selectedSymptom = symptomFilt;
      }
    }
  }

  validateNumber(controlName: string, value: string, action: string){
    let validChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    let valueArr = value.split('');
    let validVal = '';
    let pointCont = 0;

    valueArr.forEach(char => {
      if(char == '.' && pointCont < 1){
        validVal += '.';
        pointCont++;
      }else if(validChars.includes(char)){
        validVal += char;
      }
    });

    let firstChar = validVal.charAt(0);
    if(firstChar == '.' && action == 'blur'){
      this.activatorFieldsFormGroup.controls[controlName].setValue(`0${validVal}`);
    }else{
      this.activatorFieldsFormGroup.controls[controlName].setValue(validVal);
    }
  }

  async returnActivatorData(){
    let formValue = this.activatorFieldsFormGroup.getRawValue();
    formValue.customValue = this.customValue;

    if(formValue.activatorTypeControl == 'SI'){
      let symptomArr = formValue.symptomControl.split('(').reverse();
      let symptomStr = symptomArr[0].replace(')', '');
      let symptomFilt: SymptomList | null = null;
      for(const symptom of this.symptoms){
        let idDec = await this._encService.decrypt(symptom.ID_SINTOMA);
        if(idDec == symptomStr){
          symptomFilt = symptom;
        }
      }
  
      if(symptomFilt == null){
        this._resourcesService.openSnackBar('El síntoma seleccionado es inválido.');
        return;
      }
    }

    let formStr = JSON.stringify(formValue);
    let formEnc = await this._encService.encrypt(formStr);

    this.returnFormValue.emit(formEnc);
  }

  closeDialog(){
    this.closeFormDialog.emit('');
  }
}
