import { Component, ChangeDetectionStrategy, ChangeDetectorRef, Output, EventEmitter, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { tap, catchError, switchMap, shareReplay, retry, take } from 'rxjs/operators';
import { BehaviorSubject, Subject, Observable } from 'rxjs';
import { MessageService } from '../../_shared/services/message.service';
import { CustomFormBuilder } from '../../_shared/services/custom-form-builder.service';
import { DialogService, DialogSettings } from '@progress/kendo-angular-dialog';
import { NotifyService } from '../../_shared/services/notify.service';
import { SosSaveService } from './sos-save.service';
import * as util from '../../_shared/utils/util';
import { FormGroup, Validators } from '@angular/forms';
import { SosItem, SosDateRangeOptions, SosTransferItem } from '../models';
import dayjs from 'dayjs';
import { SosHelper } from '../sosHelper';
import { FAST_KENDO_COMMON, FAST_PAGE_COMMON } from '../../app.config';

@Component({
  selector: 'app-sos-gas-save[nomDate][deliveryPointId][sosItemForms][isTransferPaths]',
  templateUrl: './sos-save.component.html',
  styleUrls: ['./sos-save.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  imports: [FAST_PAGE_COMMON, FAST_KENDO_COMMON]
})
export class SosSaveComponent implements OnInit {
  @Input() nomDate: Date;
  @Input() deliveryPointId: number;
  @Input() sosItemForms: FormGroup[];
  @Input() isTransferPaths: boolean;
  @Output() closed = new EventEmitter<boolean>()

  util = util;
  icons = util.icons;
  saveForm: util.FormModel<SosDateRangeOptions>;
  sosItems: SosItem[] | SosTransferItem[];

  loading$ = new BehaviorSubject<boolean>(false);
  save$ = new Subject()
  saveResult$ = new Observable()
  checksCompleted$ = new BehaviorSubject<boolean>(false);

  constructor(private messageService: MessageService, private titleService: Title, private service: SosSaveService, private fb: CustomFormBuilder, private ref: ChangeDetectorRef, private dialogService: DialogService, private notify: NotifyService) {

  }

  ngOnInit(): void {
    this.saveForm = this.getSaveForm();

    if (this.isTransferPaths)
      this.sosItems = this.sosItemForms.map(fg => fg.getRawValue() as SosTransferItem);
    else
      this.sosItems = this.sosItemForms.map(fg => fg.getRawValue() as SosItem);

    this.checkMissingRequiredInfo();

    this.saveResult$ = this.save$.pipe(
      switchMap(() => {
        this.loading$.next(true);
        this.saveForm.disable();
        const saveOps = this.saveForm.getRawValue() as SosDateRangeOptions;
        if (util.isNullOrWhitespace(saveOps.saveNotes)) {
          saveOps.saveNotes = null;
        }
        else {
          saveOps.saveNotes = saveOps.saveNotes.trim();
        }

        if (this.isTransferPaths)
          return this.service.savePathNoms(this.sosItems as SosTransferItem[], saveOps.fromDate, saveOps.toDate); //Address Save Notes in SavePathNoms
        else
          return this.service.saveNoms(this.sosItems as SosItem[], saveOps.fromDate, saveOps.toDate, saveOps.saveNotes, this.deliveryPointId);
      }),
      tap(() => {
        this.closed.emit(true);
        this.loading$.next(false);
      }),
      shareReplay(1),
      catchError(err => {
        this.loading$.next(false);
        this.saveForm.enable();
        return util.handleError(err, this.messageService);
      }), retry(10)
    )

    util.focusAndSelectInputTarget();
  }

  getSaveForm() {
    const fb = this.fb;
    const fg: util.FormModel<SosDateRangeOptions> = this.fb.group({
      fromDate: fb.ctr(this.nomDate, Validators.required),
      toDate: fb.ctr(this.nomDate, Validators.required),
      saveNotes: fb.ctr(null)
    });

    return fg;
  }

  save() {
    this.save$.next(null);
  }

  close() {
    this.closed.emit(false);
  }

  restOfMonth() {
    if (this.saveForm.valid) {
      const fromDate = this.saveForm.value.fromDate;
      const monthEnd: Date = dayjs(fromDate).endOf('month').toDate();
      this.saveForm.patchValue({ toDate: monthEnd });
    }
  }

  checkMissingRequiredInfo(): void {
    const dialogSettings: DialogSettings = {
      title: "Please confirm",
      content: "Some rows are missing required info and might not save correctly.",
      actions: [{ text: 'Cancel' }, { text: 'Continue', cssClass: 'k-primary' }],
      cssClass: 'utilError'
    }

    const hasAnyMissingRequiredInfo = this.sosItems.some((item: SosItem | SosTransferItem) => SosHelper.isMissingRequiredInfo(item));
    if (hasAnyMissingRequiredInfo) {
      this.dialogService.open(dialogSettings).result.pipe(take(1)).subscribe(result => {
        if (util.getDialogAction(result) === util.dialogAction.Continue)
          this.checksCompleted$.next(true);
        else
          this.closed.emit(false);
      });
    } else //no missing required info
      this.checksCompleted$.next(true);
  }
}
