import { FormSelectItem } from '@af/digi-ng/_form/form-select';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { SignalRequest } from '@msfa-models/api/signal.request.model';
import { DeltagareAvrop } from '@msfa-models/avrop.model';
import { CustomError } from '@msfa-models/error/custom-error';
import { Signal } from '@msfa-models/signal.model';
import { formatDate } from '@msfa-utils/format-to-date.util';
import { Radiobutton } from '@ui/radiobutton-group/radiobutton.model';
import { add } from 'date-fns';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, shareReplay, switchMap, take } from 'rxjs/operators';
import { SignalFormService } from './signal-form.service';
import { SignalFormValidator } from './signal-form.validator';

@Component({
  selector: 'msfa-signal-form',
  templateUrl: './signal-form.component.html',
  styleUrls: ['./signal-form.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SignalFormComponent {
  shouldValidate$ = new BehaviorSubject<boolean>(false);
  confirmDialogOpen$ = new BehaviorSubject<boolean>(false);
  signalFormGroup = new FormGroup(
    {
      type: new FormControl(null),
      omfattning: new FormControl('heltid'),
      percent: new FormControl(50),
      startDate: new FormControl(new Date()),
    },
    [SignalFormValidator.isSignalValid()]
  );
  submitLoading$ = new BehaviorSubject<boolean>(false);
  lastSubmittedSignal$ = new BehaviorSubject<Date>(null);
  error$ = new BehaviorSubject<CustomError>(null);

  currentGenomforandeReferens$: Observable<number> = this.activatedRoute.params.pipe(
    map(params => +params.genomforandeReferens)
  );
  avrop$: Observable<DeltagareAvrop> = this.currentGenomforandeReferens$.pipe(
    switchMap(genomforandeReferens => this.signalFormService.fetchAvropInformation$(genomforandeReferens)),
    shareReplay(1)
  );

  typeSelectItems: FormSelectItem[] = [
    { name: 'Arbete', value: 'arbete' },
    { name: 'Utbildning', value: 'utbildning' },
  ];

  omfattningRadioButtons: Radiobutton[] = [
    { label: 'Heltid', value: 'heltid' },
    { label: 'Deltid', value: 'deltid' },
  ];

  constructor(private signalFormService: SignalFormService, private activatedRoute: ActivatedRoute) {}

  get formErrors(): { [key: string]: string } {
    return this.signalFormGroup.errors || {};
  }

  get typeFormControl(): FormControl {
    return this.signalFormGroup.get('type') as FormControl;
  }
  get omfattningFormControl(): FormControl {
    return this.signalFormGroup.get('omfattning') as FormControl;
  }
  get percentFormControl(): FormControl {
    return this.signalFormGroup.get('percent') as FormControl;
  }
  get startDateFormControl(): FormControl {
    return this.signalFormGroup.get('startDate') as FormControl;
  }

  get showPercentFormControl(): boolean {
    return this.omfattningFormControl.value === 'deltid';
  }

  get startDateFormValueAsDate(): Date {
    return new Date(this.startDateFormControl.value);
  }

  formControlIsInvalid(formControlName: string): boolean {
    return this.formErrors[formControlName] && this.shouldValidate$.getValue();
  }

  getMaxDate(startDate: Date): Date {
    return add(new Date(startDate), { months: 10, days: 1 });
  }

  openConfirmDialog(): void {
    this.shouldValidate$.next(true);
    if (this.signalFormGroup.invalid) {
      return;
    }

    this.confirmDialogOpen$.next(true);
  }

  cancelConfirmDialog(): void {
    this.confirmDialogOpen$.next(false);
    this.error$.next(null);
  }

  submitAndCloseConfirmDialog(genomforandeReferens: number): void {
    this.submitLoading$.next(true);

    const { type, omfattning, startDate, percent } = this.signalFormGroup.value as Signal;

    const postRequest: SignalRequest = {
      genomforandeReferens: +genomforandeReferens,
      typ: type,
      omfattning,
      omfattning_procent: omfattning === 'deltid' ? percent : null,
      startdatum: formatDate(startDate),
    };

    this.signalFormService
      .postSignal$(postRequest)
      .pipe(take(1))
      .subscribe({
        next: () => {
          this.lastSubmittedSignal$.next(new Date());
          this.submitLoading$.next(false);
          this.confirmDialogOpen$.next(false);
        },
        error: (customError: CustomError) => {
          this.error$.next({ ...customError, message: customError.error.message });
          this.submitLoading$.next(false);
          throw { ...customError, avoidToast: true };
        },
      });
  }
}
