import { ChartDataPoint } from './model/ChartDataPoint.model';
import { UserChart } from './model/UserChart.model';
import { ChartFormData } from './model/ChartFormData.model';
import { Store } from '@ngrx/store';
import { PrivateCharts } from './model/PrivateCharts.model';
import { LoadingService } from 'src/app/core/loading.service';
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { finalize } from 'rxjs/operators';
import { ChartsFeatureState } from './store/charts.reducers';
import { SetPrivateChartsAction, SetPublicChartsAction, PutUserChartAction, RemoveAddedChart, AddAddedChart, RemoveChartAction, AddChartDataAction } from './store/charts.actions';
import { Chart } from './model/Chart.model';
import { BehaviorSubject } from 'rxjs';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class ChartsService {

  public chartFormData: BehaviorSubject<ChartFormData> = new BehaviorSubject(new ChartFormData());

  constructor(private http: HttpClient, private loadingService: LoadingService, private store: Store<ChartsFeatureState>, private snackBar: MatSnackBar, private router: Router) {
    this.requestFormData();
  }

  requestPrivateCharts(){
    this.loadingService.enableLoading();
    this.http.get('/tadis/charts/private').pipe(
      finalize(() => { this.loadingService.disableLoading(); })
    ).subscribe(
      (privateCharts: PrivateCharts) => {
        this.store.dispatch(new SetPrivateChartsAction(privateCharts));
      }
    );
  }

  requestPublicCharts(){
    this.loadingService.enableLoading();
    this.http.get('/tadis/charts/public').pipe(
      finalize(() => { this.loadingService.disableLoading(); })
    ).subscribe(
      (publicCharts: Chart[]) => {
        this.store.dispatch(new SetPublicChartsAction(publicCharts));
      }
    );
  }

  requestFormData(){
    this.loadingService.enableLoading();
    this.http.get('/tadis/charts/form').pipe(
      finalize(() => { 
        this.loadingService.disableLoading();
      })
    ).subscribe(
      (formData: ChartFormData) => {
        this.chartFormData.next(formData);
      }
    );
  }

  requestSaveChart(chart: Chart){
    this.loadingService.enableLoading();
    this.http.put('/tadis/charts', chart).pipe(
      finalize(() => { 
        this.loadingService.disableLoading();
      })
    ).subscribe(
      (chart: Chart) => {
        this.snackBar.open('Graf úspěšně uložen.', 'zavřít', { duration: 2500 });
        this.store.dispatch(new PutUserChartAction(chart));
        this.router.navigate(['/charts/mycharts/']);
      }
    );
  }

  requestPinChart(chartId: number){
    this.loadingService.enableLoading();
    this.http.post('/tadis/charts/private/add/'+chartId, null).pipe(
      finalize(() => { 
        this.loadingService.disableLoading();
      })
    ).subscribe(
      (userChart: UserChart) => {
        this.snackBar.open('Graf úspěšně připnut do privátních.', 'zavřít', { duration: 2500 });
        this.store.dispatch(new AddAddedChart(userChart.chart))
      },
      (error: HttpErrorResponse) => {
        if (error.status === 409){
          this.snackBar.open('Graf nelze připnout. Již ho máte připnutý, nebo jste jeho autorem', 'zavřít', { duration: 5000 });
        }
      }
    );
  }

  requestUnpinChart(chartId: number){
    this.loadingService.enableLoading();
    this.http.delete('/tadis/charts/private/remove/'+chartId).pipe(
      finalize(() => { 
        this.loadingService.disableLoading();
      })
    ).subscribe(
      () => {
        this.snackBar.open('Graf úspěšně odepnut z privátních', 'zavřít', { duration: 2500 });
        this.store.dispatch(new RemoveAddedChart(chartId))
      }
    );
  }

  requestDeleteChart(chartId: number, redirectOnSuccess?: boolean){
    this.loadingService.enableLoading();
    this.http.delete('/tadis/charts/'+chartId).pipe(
      finalize(() => { 
        this.loadingService.disableLoading();
      })
    ).subscribe(
      () => {
        this.snackBar.open('Graf úspěšně odstraněn', 'zavřít', { duration: 2500 });
        this.store.dispatch(new RemoveChartAction(chartId));
        if (redirectOnSuccess){
          this.router.navigate(['/charts/mycharts'])
        }
      }
    );
  }

  requestChartData(chartId: number){
    this.loadingService.enableLoading();
    this.http.get('/tadis/charts/chart/'+chartId).pipe(
      finalize(() => { 
        this.loadingService.disableLoading();
      })
    ).subscribe(
      (chartData: ChartDataPoint[]) => {
        this.store.dispatch(new AddChartDataAction(chartId, chartData));
      },
      (error: HttpErrorResponse) => {
        this.store.dispatch(new AddChartDataAction(chartId, null));
      }
    );
  }


  requestChartMeta(chartId: number){
    this.loadingService.enableLoading();
    return this.http.get('/tadis/charts/chartMeta/'+chartId).pipe(
      finalize(() => { 
        this.loadingService.disableLoading();
      })
    );
  }

  downloadCanvas(canvas: any){
    var link = document.createElement('a');
    link.href = canvas.toDataURL('image/png');;
    link.download = 'export.png';
    link.click();
  }

}