import { SelectData } from 'src/app/core/model/select-data.model';
import { ChartAxis } from './../model/ChartAxis.model';
import { ValidatorFn } from '@angular/forms';
import { ChartData } from './../model/ChartData.model';
import { RoleUtil } from './../../core/role.util';
import { ChartsFeatureState, ChartsState } from './../store/charts.reducers';
import { Store } from '@ngrx/store';
import { ChartFormData } from './../model/ChartFormData.model';
import { ChartsService } from './../charts.service';
import { Validators } from '@angular/forms';
import { FormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { Chart } from './../model/Chart.model';
import { FormGroup } from '@angular/forms';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { User } from 'src/app/core/model/user.model';
import { AuthState } from 'src/app/auth/store/auth.reducers';
import * as moment from 'moment';

@Component({
  selector: 'app-edit-chart',
  templateUrl: './edit-chart.component.html',
  styleUrls: ['./edit-chart.component.scss']
})
export class EditChartComponent implements OnInit, OnDestroy {

  chartMetaForm: FormGroup;
  chartDataForm: FormGroup;
  formData: ChartFormData;

  editMode: boolean = false;
  editChart: Chart;
  
  user: User;

  formDataSubscription: Subscription;
  
  authStoreSubscription: Subscription;
  chartStoreSubscription: Subscription;

  constructor(private route: ActivatedRoute, private chartsService: ChartsService, private store: Store<ChartsFeatureState>, private roleUtil: RoleUtil, private router: Router) {
    this.formDataSubscription = this.chartsService.chartFormData.subscribe(
      (chartFormData: ChartFormData) => {
        this.formData = chartFormData;
        this.chartMetaForm = this.initMetaForm(this.editChart ? this.editChart : undefined);
      }
    );

    this.authStoreSubscription = this.store.select('authState').subscribe(
      (state: AuthState) => {
        this.user = state.user;
      }
    );

    let id: string = this.route.snapshot.params['id']
    if(id){
      this.editMode = true; 
      this.chartStoreSubscription = this.store.select('charts').subscribe(
        (state: ChartsState) => {
          if (state.privateCharts !== null){
            let usersCharts: Chart[] = state.privateCharts.usersCharts;
            let chartToEdit: Chart = usersCharts.find((chart: Chart) => chart.id === +id)
            if (chartToEdit){
              this.editChart = chartToEdit;
              this.chartMetaForm = this.initMetaForm(this.editChart);
              this.chartDataForm = this.initDataForm(this.editChart);
            }
            else
              this.router.navigate(['/charts']);
          }
        }
      );
    }
    else
      this.chartDataForm = this.initDataForm();

    this.chartsService.requestPrivateCharts();
  }

  ngOnInit() {
  }

  ngOnDestroy() {
    this.formDataSubscription.unsubscribe();
  }

  private initMetaForm(chart?: Chart): FormGroup{
    return new FormGroup({
      'id': new FormControl(chart ? chart.id : null),
      'title': new FormControl(chart ? chart.title : null, [Validators.required, Validators.maxLength(100)]),
      'fromDate': new FormControl(chart ? moment(chart.fromDate, 'D.M.YYYY').locale('cs') : moment(this.formData.fromDate, 'D.M.YYYY').locale('cs'), Validators.required),
      'toDate': new FormControl(chart ? moment(chart.toDate, 'D.M.YYYY').locale('cs') : moment(this.formData.toDate, 'D.M.YYYY').locale('cs'), Validators.required),
      'publicChart': new FormControl(chart ? chart.publicChart : false, Validators.required),
      'type': new FormControl(chart ? chart.type : null, Validators.required)
    });
  }

  private hasIntervalField(chart: Chart): boolean{
    return chart && (chart.type && (chart.type.name === 'PIE' && (chart.chartData.x && chart.chartData.x.type === 'NUMERIC_VALUE')));
  }

  private initDataForm(chart?: Chart): FormGroup{
    let controls = {
      'id': new FormControl(chart ? chart.chartData.id : null, this.editMode ? Validators.required : []),
      'x': new FormControl(chart ? chart.chartData.x : null, chart && chart.type ? Validators.required : [] ),
      'y': new FormControl(chart ? chart.chartData.y : null, chart && chart.type ? Validators.required : []),
      'z': new FormControl(chart ? chart.chartData.z : null, chart && chart.type.name === 'BUBBLE' ? Validators.required : []),
      'xInterval': new FormControl(chart ? chart.chartData.xInterval : null, this.hasIntervalField(chart) ? [Validators.required, Validators.pattern("^[0-9]*$"), Validators.min(1)] : [])
    }
    return new FormGroup(controls);
  }

  private reInitDataForm(clearAxes: boolean){
    let chart: Chart = this.chartMetaForm.value;
    chart.chartData = this.chartDataForm.value;
    if (clearAxes){
      chart.chartData.x = null;
      chart.chartData.y = null;
      chart.chartData.z = null;
    }
    chart.chartData.xInterval = this.hasIntervalField(chart) ? 1 : null;
    this.chartDataForm = this.initDataForm(chart);
  }

  private onSaveClick(){
    let chart = this.chartMetaForm.value;
    if (chart.type)
      chart.type = chart.type.name;
    chart.chartData = this.chartDataForm.value;
    if (chart.chartData.x)
      chart.chartData.x = chart.chartData.x.name;
    if (chart.chartData.y)
      chart.chartData.y = chart.chartData.y.name;
    if (chart.chartData.z)
      chart.chartData.z = chart.chartData.z.name;
    this.chartsService.requestSaveChart(chart);
  }

  private chartTypeMatcher(type1: SelectData, type2: SelectData){
    return (!type1 && !type2) || (type1 && type2 && type1.name === type2.name);
  }

  private chartAxisMatcher(axis1: ChartAxis, axis2: ChartAxis){
    return (!axis1 && !axis2) || (axis1 && axis2 && axis1.name === axis2.name);
  }

}
