import { Component, OnDestroy, OnInit, ViewEncapsulation, TemplateRef } from "@angular/core";
import { ApiResources, UtilHelper } from "@shared/helpers";
import { AppData, HttpService, NotifyService } from "@shared/services";
import { takeUntil, finalize } from "rxjs/operators";
import { HttpErrorResponse } from "@angular/common/http";
import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap";
import { FormGroup, Validators, FormBuilder } from "@angular/forms";
import { Page, IUserAccount, Pagination } from "@shared/models";
import { EncounterType } from "@shared/entities/encounter-type.entity";
import { WhiteSpaceValidator } from "../../../../../shared/validators";

class TrackBy {
    encounterTypes(item: EncounterType) {
        return item.encounterTypeId;
    }
}

class FilterOptions {
    encounterName: string = null;
    encounterTypeId: number;
}

class Filters {
    options: FilterOptions;
    applied: boolean;

    constructor() {
        this.init();
    }

    init() {
        this.options = new FilterOptions();
        this.applied = undefined;
    }
}

@Component({
    templateUrl: "./encounter-type.html",
    encapsulation: ViewEncapsulation.None
})
export class EncounterTypePage implements OnInit, OnDestroy {
    page: Page;
    filters: Filters;
    trackBy: TrackBy;
    pagination: Pagination;
    encounterTypeForm: FormGroup;
    loading: boolean;
    encounterTypes: Array<EncounterType>;
    selectedEncounterType: EncounterType;

    modalRef: NgbModalRef;
    submitting: boolean;
    submitted: boolean;
    modifying: boolean;
    modifyingContent: string;
    constructor(
        private readonly appData: AppData,
        private readonly modalService: NgbModal,
        private readonly formBuilder: FormBuilder,
        private readonly notifyService: NotifyService,
        private readonly httpService: HttpService
    ) {
        this.loading = true;
        this.page = new Page();
        this.filters = new Filters();
        this.trackBy = new TrackBy();
        this.initPagination();
    }

    private initPagination() {
        this.pagination = new Pagination();
        this.pagination.pageIndex = 1;
        this.pagination.pageSize = 10;
    }

    private buildForm() {
        this.encounterTypeForm = this.formBuilder.group({
            encounterTypeId: 0,
            encounterName: [null, [Validators.required, WhiteSpaceValidator.isValid]],
            active: [true],
        });
    }  

    onOpenModel(content: TemplateRef<any>, encounterTypes?: EncounterType) {
        
        this.buildForm();

        if (encounterTypes) {
            this.selectedEncounterType = encounterTypes;
            this.updateForm();
        }

        this.modalRef = this.modalService.open(content, {
            backdrop: "static",
            keyboard: false,
            centered: true,
            windowClass: "custom-modal effect-scale"
        });
    }   

    fetchAddEncounterType() {
        this.loading = true;

        const request = Object.assign(UtilHelper.clone(this.filters.options), UtilHelper.clone(this.pagination));
        this.httpService
            .post<Array<EncounterType>>(ApiResources.getURI(ApiResources.encounterType.base, ApiResources.encounterType.fetch), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => this.loading = false))
            .subscribe(
                (response: Array<EncounterType>) => {
                    this.encounterTypes = response;
                    UtilHelper.applyPagination(this.encounterTypes, this.pagination);
                },
                () => {
                    this.encounterTypes = [];
                }
            );
    }  

    onNextPage() {
        $("body,html").animate({ scrollTop: 0 });
        this.fetchAddEncounterType();
    }       

    onSubmit() {
        
        this.submitted = true;

        if (!this.encounterTypeForm.valid) {
            return;
        }
        console.log(this.encounterTypeForm.value);
        this.submitting = true;
        const request = Object.assign(UtilHelper.clone(this.encounterTypeForm.getRawValue()));
        request["modifiedByName"] = this.page.userAccount.fullName;
        if (Number (this.encounterTypeForm.value.encounterTypeId) === 0) {
            request.createdBy = this.page.userAccount.accountId;
            this.httpService.post(ApiResources.getURI(ApiResources.encounterType.base, ApiResources.encounterType.add), request)
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => {
                    this.submitting = false;
                    this.submitted = false;
                }))
                .subscribe(() => {
                    this.onCloseModal();
                    this.fetchAddEncounterType();
                    this.notifyService.success("Encounter Type has been added successfully.");
                }, (error: HttpErrorResponse) => {
                    const errorMessage = UtilHelper.handleError(error);
                    if (errorMessage) {
                        this.notifyService.warning(errorMessage);
                    } else {
                        this.notifyService.defaultError();
                    }
                });
        } else {
            request.modifiedBy = this.page.userAccount.accountId;
            request["modifiedByName"] = this.page.userAccount.fullName;
            request["createdBy"] = this.page.userAccount.accountId;
            delete request.type;
            this.httpService.put(ApiResources.getURI(ApiResources.encounterType.base, ApiResources.encounterType.update), request)
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => {
                    this.submitting = false;
                    this.submitted = false;
                }))
                .subscribe(() => {
                    this.onCloseModal();
                    this.fetchAddEncounterType();
                    this.notifyService.success("Encounter Type details has been updated successfully.");
                }, (error: HttpErrorResponse) => {
                    const errorMessage = UtilHelper.handleError(error);
                    if (errorMessage) {
                        this.notifyService.warning(errorMessage);
                    } else {
                        this.notifyService.defaultError();
                    }
                });
        }
    }

    get form() {
        return this.encounterTypeForm.controls;
    }    

    private updateForm() {
        this.encounterTypeForm.patchValue({
            encounterTypeId: this.selectedEncounterType.encounterTypeId,
            encounterName: this.selectedEncounterType.encounterName,
            active: this.selectedEncounterType.active
        });
    }  

    onDelete(encounterTypes: EncounterType) {
        
        this.notifyService.delete(() => {
            this.httpService
                .post(ApiResources.getURI(ApiResources.encounterType.base, ApiResources.encounterType.delete), {
                    encounterTypeId: encounterTypes.encounterTypeId, modifiedByName: this.page.userAccount.fullName,
                    createdBy: this.page.userAccount.accountId,
                    modifiedBy: this.page.userAccount.accountId })
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => { }))
                .subscribe(
                    () => {
                        this.notifyService.success("Encounter Type deleted successfully.");
                        this.fetchAddEncounterType();
                    }, (error: HttpErrorResponse) => {
                        const errorMessage = UtilHelper.handleError(error);
                        if (errorMessage) {
                            this.notifyService.warning(errorMessage);
                        } else {
                            this.notifyService.defaultError();
                        }
                    }
                );
        }, () => { });
    }

    onCloseModal() {
        try {
            this.modalRef.close();
            this.modalRef = undefined;
        } catch (e) {
            // ignored;
        }

        this.loading = false;
        this.submitting = undefined;
        this.submitted = undefined;
    }

    ngOnInit() {
        this.appData.userAccount
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((userAccount: IUserAccount) => {
                if (userAccount) {
                    this.page.userAccount = userAccount;
                    this.fetchAddEncounterType();
                } else {
                    this.page.userAccount = undefined;
                }
            });
    }

    ngOnDestroy() {
        this.onCloseModal();
        this.page.unsubscribeAll();
    }
}