import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { validColorValidator } from 'ngx-colors';
import { CustomRepeatComponent } from '../../custom-repeat/custom-repeat.component';
import { MatSnackBar } from '@angular/material/snack-bar';
import { EncService } from 'src/app/services/enc/enc.service';
import { lastValueFrom } from 'rxjs';
import { CountersActivatorsService } from 'src/app/services/counters-activators.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-new-activator',
  templateUrl: './new-activator.component.html',
  styleUrls: ['./new-activator.component.css']
})
export class NewActivatorComponent implements OnInit {
  activatorType = new FormControl({value: '', disabled: true}, [Validators.required]);
  priority = new FormControl('BA', [Validators.required]);
  startHour = new FormControl('', [Validators.required]);
  repeat = new FormControl({value: 'NR', disabled: true}, [Validators.required]);
  eventColor = new FormControl("rgb(79, 195, 255)", validColorValidator());
  colorPicker = new FormControl("rgb(79, 195, 255)");
  startDateControl?: FormControl;
  signControl = new FormControl('', [Validators.required]);
  magnitudeControl = new FormControl('', Validators.required);
  unitControl = new FormControl('', Validators.required);
  minValueControl = new FormControl('', [Validators.required, Validators.pattern('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')]);
  maxValueControl = new FormControl('', [Validators.required, Validators.pattern('[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)')]);
  comparisonControl = new FormControl('', Validators.required);
  limitValueControl = new FormControl('', [Validators.required, Validators.pattern('^[0-9]*[1-9][0-9]*$')]);

  hours: string[];
  startDate: Date | null;

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

  magnitudes: Magnitudes[];
  customMagnitude: string;
  customUnit?: Units;

  constructor(
    @Inject(MAT_DIALOG_DATA) private data: any,
    private _dialog: MatDialog,
    private _snackBar: MatSnackBar,
    private _encService: EncService,
    private _countersActivators: CountersActivatorsService,
    private _dialogRef: MatDialogRef<NewActivatorComponent>,
  ) { 
    this.hours = [];
    this.startDate = null;
    this.startDateControl = new FormControl(this.startDate, [Validators.required]);
    this.customDisplayed = '';
    this.customValue = '';
    this.magnitudes = MAGNITUDES;
    this.customMagnitude = '';
  }

  ngOnInit(): void {
    console.log(this.data);
    this.activatorType.setValue(this.data.activatorType);
    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}`);
    }

    this.startDateControl?.valueChanges.subscribe((_) => {
      this.repeat.enable();
    });

    this.eventColor.valueChanges.subscribe((color) => {
      if(this.eventColor.valid){
        this.colorPicker.setValue(color, {
          emitEvent: false,
        });
      }
    });

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

  repeatChanges(value: string){
    if(value == 'PE'){
      let dialogRef = this._dialog.open(CustomRepeatComponent, {
        data: this.startDateControl?.value,
        width: '540px',
        disableClose: true,
      });

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

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

  openSnackBar(msg: string){
    this._snackBar.open(msg, undefined, {
      duration: 2500,
    });
  }

  async saveActivator(){
    try{
      let idUser = localStorage.getItem('idusuario');

      if(this.activatorType.invalid || this.priority.invalid){
        this.openSnackBar('Antes de continuar debe completar los campos requeridos.');
        this.activatorType.markAsTouched();
        this.priority.markAsTouched();
      }else{
        switch(this.activatorType.value){
          case 'CA':
            if(this.startDateControl?.invalid || this.startHour.invalid || this.repeat.invalid || this.colorPicker.invalid){
              this.openSnackBar('Antes de continuar debe completar los campos requeridos.');
              this.startDateControl?.markAsTouched();
              this.startHour.markAsTouched();
              this.repeat.markAsTouched();
              this.colorPicker.markAsTouched();
            }else{
              let formData = new FormData();
              let confObj = {
                startDate: this.startDateControl?.value,
                startHour: this.startHour.value,
                repeat: this.repeat.value,
                customRepeat: this.customValue,
                color: this.colorPicker.value,
              }

              formData.append('id_user', idUser!);
              formData.append('linea', '1');
              formData.append('priority', this.priority.value!);
              formData.append('type', this.activatorType.value!);
              formData.append('condition', JSON.stringify(confObj));
              
              let res = await lastValueFrom(this._countersActivators.registerActivator(formData));
              this._dialogRef.close(res.response.IDCONT);
            }
          break;
          case 'SI':
            if(this.signControl.invalid || this.startDateControl?.invalid || this.startHour.invalid || this.repeat.invalid || this.colorPicker.invalid){
              this.openSnackBar('Antes de continuar debe completar los campos requeridos.');
              this.startDateControl?.markAsTouched();
              this.startHour.markAsTouched();
              this.repeat.markAsTouched();
              this.colorPicker.markAsTouched();
              this.signControl.markAsTouched();
            }else{
              let formData = new FormData();
              let confObj = {
                sign: this.signControl.value,
                startDate: this.startDateControl?.value,
                startHour: this.startHour.value,
                repeat: this.repeat.value,
                customRepeat: this.customValue,
                color: this.colorPicker.value,
              }

              formData.append('id_user', idUser!);
              formData.append('linea', '1');
              formData.append('priority', this.priority.value!);
              formData.append('type', this.activatorType.value!);
              formData.append('condition', JSON.stringify(confObj));
              
              let res = await lastValueFrom(this._countersActivators.registerActivator(formData));
              this._dialogRef.close(res.response.IDCONT);
            }
          break;
          case 'ME':
            if(this.minValueControl.invalid || this.maxValueControl.invalid || this.magnitudeControl.invalid || this.unitControl.invalid || this.colorPicker.invalid){
              this.openSnackBar('Antes de continuar debe completar los campos requeridos.');
              this.minValueControl.markAsTouched();
              this.maxValueControl.markAsTouched();
              this.magnitudeControl.markAsTouched();
              this.unitControl.markAsTouched();
              this.colorPicker.markAsTouched();
            }else{
              let formData = new FormData();
              let confObj = {
                minValue: this.minValueControl.value,
                maxValue: this.maxValueControl.value,
                magnitude: this.magnitudeControl.value,
                customMagnitude: this.magnitudeControl.value == 'OTR' ? this.customMagnitude : null,
                unit: this.unitControl.value,
                customUnit: this.unitControl.value == 'OTR' ? this.customUnit : null,
              }

              formData.append('id_user', idUser!);
              formData.append('linea', '1');
              formData.append('priority', this.priority.value!);
              formData.append('type', this.activatorType.value!);
              formData.append('condition', JSON.stringify(confObj));
              
              let res = await lastValueFrom(this._countersActivators.registerActivator(formData));
              this._dialogRef.close(res.response.IDCONT);
            }
          break;
          case 'VA':
            if(this.comparisonControl.invalid || this.limitValueControl.invalid || this.magnitudeControl.invalid || this.unitControl.invalid){
              this.openSnackBar('Antes de continuar debe completar los campos requeridos.');
              this.comparisonControl.markAsTouched();
              this.limitValueControl.markAllAsTouched();
              this.magnitudeControl.markAsTouched();
              this.unitControl.markAsTouched();
              this.colorPicker.markAsTouched();
            }else{
              let formData = new FormData();
              let confObj = {
                comparison: this.comparisonControl.value,
                limitValue: this.limitValueControl.value,
                magnitude: this.magnitudeControl.value,
                customMagnitude: this.magnitudeControl.value == 'OTR' ? this.customMagnitude : null,
                unit: this.unitControl.value,
                customUnit: this.unitControl.value == 'OTR' ? this.customUnit : null,
              }

              formData.append('id_user', idUser!);
              formData.append('linea', '1');
              formData.append('priority', this.priority.value!);
              formData.append('type', this.activatorType.value!);
              formData.append('condition', JSON.stringify(confObj));
              
              let res = await lastValueFrom(this._countersActivators.registerActivator(formData));
              this._dialogRef.close(res.response.IDCONT);
            }
          break;
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this.openSnackBar(error.error.msg);
      }
    }
  }

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

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

@Component({
  selector: 'app-magnitude-conf',
  templateUrl: './magnitude-conf.component.html'
})
export class MagnitudeConfDialog{}

@Component({
  selector: 'app-unit-conf',
  templateUrl: './unit-conf.component.html'
})
export class UnitConfDialog{}