import { Component, Inject, OnInit } from '@angular/core';
import { ActivatorByType, ActivatorsByTypeResponse } from '../../../../../interfaces/activators-by-type.interface';
import { FormControl, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { EncService } from '../../../../../services/enc.service';
import { CountersActivatorsService } from '../../../../../services/counters-activators.service';
import { validColorValidator } from 'ngx-colors';
import { lastValueFrom } from 'rxjs';
import { CustomRepeatComponent } from '../../../work-orders/custom-repeat/custom-repeat.component';
import { ResourcesService } from '../../../../../services/resources.service';

interface Magnitudes{
  MAGNITUDE: string;
  LABEL: string;
  UNITS: Units[];
}
interface Units{
  UNIT: string,
  LABEL: string,
}
const MAGNITUDES: Magnitudes[] = [
  {MAGNITUDE: 'TEM', LABEL: 'Temperatura', UNITS: [
    {UNIT: 'K', LABEL: '°K - Kelvin'},
    {UNIT: 'C', LABEL: '°C - Celsius'},
    {UNIT: 'F', LABEL: '°F - Fahrenheit'},
  ]},
  {MAGNITUDE: 'TEN', LABEL: 'Tensión', UNITS: [
    {UNIT: 'V', LABEL: 'V - Volts'},
  ]},
  {MAGNITUDE: 'COR', LABEL: 'Corriente', UNITS: [
    {UNIT: 'A', LABEL: 'A - Amperios'},
  ]},
  {MAGNITUDE: 'POT', LABEL: 'Potencia', UNITS: [
    {UNIT: 'W', LABEL: 'W - Watts'},
    {UNIT: 'HP', LABEL: 'HP - Caballos de fuerza'}
  ]},
  {MAGNITUDE: 'FRE', LABEL: 'Frecuencia', UNITS: [
    {UNIT: 'Hz', LABEL: 'Hz - Hertz'},
    {UNIT: 'RPM', LABEL: 'RPM - Revoluciones por minuto'},
  ]},
  {MAGNITUDE: 'VEL', LABEL: 'Velocidad', UNITS: [
    {UNIT: 'm/s', LABEL: 'm/s - Metros por segundo'},
    {UNIT: 'm/h', LABEL: 'm/h - Metros por hora'},
    {UNIT: 'km/h', LABEL: 'km/h - Kilometros por hora'},
  ]},
  {MAGNITUDE: 'DIS', LABEL: 'Distancia', UNITS: [
    {UNIT: 'cm', LABEL: 'cm - Centímetros'},
    {UNIT: 'm', LABEL: 'm - Metros'},
    {UNIT: 'km', LABEL: 'km - Kilometros'},
    {UNIT: 'in', LABEL: 'in - Pulgada'},
    {UNIT: 'ft', LABEL: 'ft - Pies'},
    {UNIT: 'yd', LABEL: 'yd - Yarda'},
  ]}
];
@Component({
    selector: 'app-update-characteristic',
    templateUrl: './update-characteristic.component.html',
    styleUrl: './update-characteristic.component.css',
    standalone: false
})
export class UpdateCharacteristicComponent implements OnInit {
  title: string;
  characteristic: string;
  hours: string[];
  activators: ActivatorByType[];
  customDisplayed: string;
  customValue: string;
  displaySign: boolean;
  displayRepeat: boolean;
  displayMagnitude: boolean;
  displayValues: boolean;
  displayComparison: boolean;
  magnitudes: Magnitudes[];
  customMagnitude: string;
  customUnit?: Units;

  date: Date | null;
  dateControl: FormControl;
  hourControl: FormControl;
  activatorControl: FormControl;
  activatorTypeControl: FormControl;
  priorityControl: FormControl;
  colorControl: FormControl;
  colorPickerControl: FormControl;
  repeatControl: FormControl;
  signControl: FormControl;
  magnitudeControl: FormControl;
  unitControl: FormControl;
  minValueControl: FormControl;
  maxValueControl: FormControl;
  comparisonControl: FormControl;
  limitValueControl: FormControl;
  value: any;

  isLoading: boolean;
  hasError: boolean;
  errorStr: string;

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

  constructor(
    @Inject(MAT_DIALOG_DATA) private _data: any,
    private _encService: EncService,
    private _countersActivatorsService: CountersActivatorsService,
    private _dialogRef: MatDialogRef<UpdateCharacteristicComponent>,
    private _dialog: MatDialog,
    private _resourcesServices: ResourcesService,
  ) {
    this.title = '';
    this.characteristic = '';
    this.hours = [];
    this.activators = [];
    this.customDisplayed = '';
    this.customValue = '';
    this.displaySign = false;
    this.displayRepeat = false;
    this.displayMagnitude = false;
    this.displayValues = false;
    this.displayComparison = false;
    this.magnitudes = MAGNITUDES;
    this.customMagnitude = '';

    this.date = null;
    this.dateControl = new FormControl(this.date, Validators.required);
    this.hourControl = new FormControl('', Validators.required);
    this.activatorControl = new FormControl('', Validators.required);
    this.activatorTypeControl = new FormControl('', Validators.required);
    this.priorityControl = new FormControl('', Validators.required);
    this.colorControl = new FormControl("rgb(79, 195, 255)", validColorValidator());
    this.colorPickerControl = new FormControl("rgb(79, 195, 255)");
    this.repeatControl = new FormControl('', Validators.required);
    this.signControl = new FormControl('', Validators.required);
    this.magnitudeControl = new FormControl('', Validators.required);
    this.unitControl = new FormControl('', Validators.required);
    this.minValueControl = new FormControl('', [Validators.required, Validators.pattern('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')]);
    this.maxValueControl = new FormControl('', [Validators.required, Validators.pattern('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')]);
    this.comparisonControl = new FormControl('', Validators.required);
    this.limitValueControl = new FormControl('', [Validators.required, Validators.pattern('^[0-9]*[1-9][0-9]*$')]);
    this.value = {};

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

  ngOnInit(): void {
    for(let i = 0; i < 24; i++){
      let period = i < 12 ? 'AM' : 'PM';
      let hour = i > 12 ? i - 12 : i;

      this.hours.push(`${hour}:00 ${period}`);
      this.hours.push(`${hour}:15 ${period}`);
      this.hours.push(`${hour}:30 ${period}`);
      this.hours.push(`${hour}:45 ${period}`);
    }

    if(this._data.characteristic == 'date'){
      let dateTimeArr = this._data.value.split(' ');
      let dateArr = dateTimeArr[0].split('-');

      this.title = "Editar fecha";
      if(this._data.type == 'start'){
        this.title += " inicial";
        this.date = new Date(parseInt(dateArr[0]), parseInt(dateArr[1]) - 1, parseInt(dateArr[2]));
      }else{
        this.title += " final";
      }

      this.dateControl.setValue(this.date);
      this.hasError = false;
      this.errorStr = '';

      this.isLoading = false;
    }else if(this._data.characteristic == 'hour'){
      this.title = "Editar hora";
      if(this._data.type == 'start'){
        this.title += " inicial";
      }else{
        this.title += " final";
      }

      let dateTimeArr = this._data.value.split(' ');
      let timeArr = dateTimeArr[1].split(':');
      let hour = parseInt(timeArr[0]);
      let period = hour < 12 ? 'AM' : 'PM';

      this.hourControl.setValue(`${hour}:${timeArr[1]} ${period}`);
      this.hasError = false;
      this.errorStr = '';

      this.isLoading = false;
    }else if(this._data.characteristic == 'activator'){
      this.title = "Editar activador";
      this.getActivatorsByType(this._data.type, this._data.value);
    }else if(this._data.characteristic == 'activatorType'){
      this.title = "Editar tipo de activador";
      this.activatorTypeControl.setValue(this._data.value);

      this.hasError = false;
      this.errorStr = '';
      this.isLoading = false;
    }else if(this._data.characteristic == 'priority'){
      this.title = "Editar prioridad";
      this.priorityControl.setValue(this._data.value);

      this.hasError = false;
      this.errorStr = '';
      this.isLoading = false;
    }else if(this._data.characteristic == 'color'){
      this.title = "Editar color";
      this.colorControl.setValue(this._data.value, {
        emitEvent: false,
      });

      this.colorPickerControl.setValue(this._data.value, {
        emitEvent: false,
      });

      this.hasError = false;
      this.errorStr = '';
      this.isLoading = false;
    }else if(this._data.characteristic == 'config'){
      this.title = "Editar configuración";
      this.value = this._data.value;
      this.displaySign = this._data.value.sign != undefined;
      this.displayRepeat = this._data.value.repeat != undefined;
      this.displayMagnitude = this._data.value.magnitude != undefined;
      this.displayValues = this._data.value.minValue != undefined;
      this.displayComparison = this._data.value.comparison != undefined;

      if(this.displayRepeat){
        let dateTimeArr = this.value.startDate.split('T');
        let dateArr = dateTimeArr[0].split('-');
        this.date = new Date(parseInt(dateArr[0]), parseInt(dateArr[1]) - 1, parseInt(dateArr[2]));
        this.customRepeat(this.value.customRepeat);
        this.repeatControl.setValue(this.value.repeat, {
          emitEvent: false,
        });

        if(this.displaySign){
          this.signControl.setValue(this.value.sign);
        }
      }
      
      if(this.displayMagnitude){
        if(this.value.customMagnitude != null && this.value.customUnit != null){
          this.magnitudeControl.setValue('OTR');
          this.customMagnitude = this.value.customMagnitude;
  
          this.unitControl.setValue(this.value.customUnit);
        }else if(this.value.customMagnitude == null && this.value.customUnit != null){
          this.magnitudeControl.setValue(this.value.magnitude);
  
          this.unitControl.setValue('OTR');
          this.customUnit = this.value.customUnit;
        }else{
          this.magnitudeControl.setValue(this.value.magnitude);
          this.unitControl.setValue(this.value.unit);
        }

        if(this.displayValues){
          this.minValueControl.setValue(this.value.minValue);
          this.maxValueControl.setValue(this.value.maxValue);
        }

        if(this.displayComparison){
          this.comparisonControl.setValue(this.value.comparison);
          this.limitValueControl.setValue(this.value.limitValue);
        }
      }

      this.hasError = false;
      this.errorStr = '';
      this.isLoading = false;
    }

    this.characteristic = this._data.characteristic;
    
    this.colorControl.valueChanges.subscribe((color) => {
      if(this.colorControl.valid){
        this.colorPickerControl.setValue(color, {
          emitEvent: false,
        })
      }
    });

    this.colorPickerControl.valueChanges.subscribe((color) => {
      this.colorControl.setValue(color, {
        emitEvent: false,
      })
    });
  }

  async getActivatorsByType(type: string, activator: number){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let activators: ActivatorsByTypeResponse = await lastValueFrom(this._countersActivatorsService.getActivatorsByType(type, idUser, 1));
      
      this.hasError = activators.error;
      this.errorStr = activators.msg;

      if(!this.hasError){
        this.activators = activators.response;
        this.activatorControl.setValue(activator);
      }

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

  customRepeat(value: string){
    if(value == '') return;
    
    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.dayNames[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;
  }

  changeRepeat(value: string){
    if(value == 'PE'){
      let repeat = this.value.repeat == 'PE' ? this.value.customRepeat : null;
      let dialogRef = this._dialog.open(CustomRepeatComponent, {
        data: {
          date: this.date,
          repeat: repeat,
        },
        width: '540px',
        maxWidth: '540px',
        disableClose: true,
      });

      dialogRef.afterClosed().subscribe(res => {
        if(res != null && res != undefined && res != ""){
          this.customRepeat(res);
        }else{
          this.repeatControl.setValue('NR');
        }
      });
    }
  }

  checkMagnitude(magnitude: string){
    this.customMagnitude = '';
    this.unitControl.setValue('');

    /*if(magnitude == 'OTR'){
      let dialogRef = this._dialog.open(MagnitudeConfDialog, {
        width: '384px'
      });

      dialogRef.afterClosed().subscribe(res => {
        if(res == undefined || res == null || res == ''){
          this.magnitudeControl.setValue('');
        }else{
          this.customMagnitude = res;
        }
      });
    }*/
  }

  checkUnit(unit: string){
    if(unit == 'OTR'){
      /*let dialogRef = this._dialog.open(UnitConfDialog, {
        width: '384px'
      });

      dialogRef.afterClosed().subscribe(res => {
        if(res == undefined || res == null || res == ''){
          this.unitControl.setValue('');
        }else{
          let unitArr = res.split('|');
          let newUnit: Units = {
            UNIT: unitArr[1],
            LABEL: `${unitArr[1]} - ${unitArr[0]}`
          };

          this.customUnit = newUnit;
        }
      });*/
    }
  }

  getUnits(magnitude: string): Units[]{
    let selected = this.magnitudes.filter(item => item.MAGNITUDE == magnitude);
    if(selected.length > 0){
      return selected[0].UNITS;
    }else{
      return [];
    }
  }

  updateCharacteristic(){
    let resObj = {
      characteristic: this._data.characteristic,
      value: '',
      type: this._data.type,
    };

    if(this._data.characteristic == 'date' && this.dateControl.valid){
      resObj.value = `${this.dateControl.value.getFullYear()}-${this.dateControl.value.getMonth() + 1}-${this.dateControl.value.getDate()}`;
    }else if(this._data.characteristic == 'hour' && this.hourControl.valid){
      resObj.value = this.hourControl.value;
    }else if(this._data.characteristic == 'activator' && this.activatorControl.valid){
      resObj.value = this.activatorControl.value;
    }else if(this._data.characteristic == 'activatorType' && this.activatorTypeControl.valid){
      resObj.value = this.activatorTypeControl.value;
    }else if(this._data.characteristic == 'priority' && this.priorityControl.valid){
      resObj.value = this.priorityControl.value;
    }else if(this._data.characteristic == 'color' && this.colorControl.valid){
      resObj.value = this.colorControl.value;
    }else if(this._data.characteristic == 'config'){
      if(this.displayRepeat){
        let repeat = this.repeatControl.value;
        this.value.repeat = repeat;
  
        if(repeat == 'PE'){
          this.value.customRepeat = this.customValue;
        }else{
          this.value.customRepeat = "";
        }

        if(this.displaySign){
          let sign = this.signControl.value;
          this.value.sign = sign;
        }
      }

      if(this.displayMagnitude){
        let magnitude = this.magnitudeControl.value;

        if(magnitude == 'OTR'){
          this.value.unit = null;
          this.value.magnitude = magnitude;
          this.value.customMagnitude = this.customMagnitude;
          this.value.customUnit = this.unitControl.value;
        }else{
          let unit = this.unitControl.value;

          if(unit == 'OTR'){
            this.value.unit = unit;
            this.value.magnitude = magnitude;
            this.value.customMagnitude = null;
            this.value.customUnit = this.customUnit;
          }else{
            this.value.unit = unit;
            this.value.magnitude = magnitude;
            this.value.customMagnitude = null;
            this.value.customUnit = null;
          }
        }

        if(this.displayValues){
          this.value.minValue = this.minValueControl.value;
          this.value.maxValue = this.maxValueControl.value;
        }

        if(this.displayComparison){
          this.value.comparison = this.comparisonControl.value;
          this.value.limitValue = this.limitValueControl.value;
        }
      }
      
      resObj.value = this.value;
    }

    if(resObj.characteristic == '' || resObj.value == '' || resObj.type == ''){
      this._resourcesServices.openSnackBar('Aún no se ha seleccionado un valor válido.');
    }else{
      let resStr = JSON.stringify(resObj);
      this._dialogRef.close(resStr);
    }
  }
}