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

class PatientChargeModel {
    patientRegistrationChargeId: number;
    charge: number;
    locationId: number;
    active: boolean;
    createdBy: number;
    createdDate: Date;
    modifiedBy?: number;
    modifiedDate?: Date;
    createdByName: string;
    createdByRole: string;
    modifiedByName: string;
    modifiedByRole: string;
    totalItems: number;
    chargeCategoryId: number;
}

@Component({
    templateUrl: "./patient-registration.html",
    encapsulation: ViewEncapsulation.None
})
export class PatientRegistrationChargePage implements OnInit, OnDestroy {
    page: Page;

    pagination: Pagination;

    loading: boolean;

    modalRef: NgbModalRef;
    submitting: boolean;
    submitted: boolean;
    chargeForm: FormGroup;
    records: Array<PatientChargeModel>;
    chargeType: IResource[];

    constructor(
        private readonly appData: AppData,
        private readonly httpService: HttpService,
        private readonly modalService: NgbModal,
        private readonly formBuilder: FormBuilder,
        private readonly notifyService: NotifyService,
        private readonly resourceService: ResourceService
    ) {
        this.loading = true;
        this.page = new Page();
        this.records = new Array<PatientChargeModel>();
        this.initPagination();
    }

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

    private buildForm() {
        this.chargeForm = this.formBuilder.group({
            patientRegistrationChargeId: 0,
            charge: [null, [Validators.required, Validators.min(1)]],
            chargeCategoryId: [null, Validators.required]
        });
    }

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

    onSubmit() {
        this.submitted = true;
        if (this.chargeForm.invalid) {
            return;
        }
        this.submitting = true;
        const request = {
            ...this.chargeForm.getRawValue(),
            createdBy: this.page.userAccount.accountId,
            loginRoleId: this.page.userAccount.roleId,
            createdByName: this.page.userAccount.fullName
        };
        

        this.httpService.post(ApiResources.getURI(ApiResources.patients.base, ApiResources.patients.modifyRegistrationCharge), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => this.submitted = this.submitting = false))
            .subscribe(
                (response: number) => {
                    if (response > 0) {
                        this.notifyService.successToast(`Record ${request["patientRegistrationChargeId"] > 0 ? 'updated' : 'added'} successfully.`);
                    }
                    if (response === -1) {
                        this.notifyService.warningToast("Given Charge already exists.");
                        return;
                    }
                    this.onCloseModal();
                    this.fetchAll();
                },
                (error: HttpErrorResponse) => {
                    this.onError(error);
                }
            );
    }

    private fetchAll() {
        this.loading = true;
        const request = { ...this.pagination };
        this.httpService.post(ApiResources.getURI(ApiResources.patients.base, ApiResources.patients.fetchRegistrationCharge), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => this.loading = false))
            .subscribe(
                (response: Array<PatientChargeModel>) => {
                    this.records = response;
                },
                (error: HttpErrorResponse) => {
                    this.onError(error)
                }
            );
    }


    private fetchChargeCategory() {
        this.resourceService.chargeCategory()
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((response: Array<IResource>) => {
                this.chargeType = response;
                if (this.chargeType.length > 0) {
                    const patientRegistrationCharge = this.chargeType.filter(m => m.name.toLowerCase() === 'patient registration')
                    this.chargeType = patientRegistrationCharge;
                }
            });
    }

    onNextPage() {
        this.fetchAll();
    }

    private onError(error: HttpErrorResponse) {
        if (error) {
            this.notifyService.errorToast(UtilHelper.handleError(error));
        }
    }

    onApply(record: PatientChargeModel) {
        this.notifyService.confirm("you want to apply this charge",() => {
            const request = {
                id: record.patientRegistrationChargeId
            };
            this.httpService.get(ApiResources.getURI(ApiResources.patients.base, ApiResources.patients.applyRegistrationCharge), request)
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => this.loading = false))
                .subscribe(
                    (response: number) => {
                        if (response > 0) {
                            this.notifyService.successToast("Record applied successfully.");
                        }
                        if (response === -3) {
                            this.notifyService.warningToast("The record you tried to delete can't be deleted because it is being used.");
                        }
                        this.fetchAll();
                    },
                    (error: HttpErrorResponse) => {
                        this.onError(error)
                    }
                );
        })
    }

    onOpenModel(content: TemplateRef<any>, record?: PatientChargeModel) {
        this.buildForm();
        this.fetchChargeCategory();
        if (record) {
            this.chargeForm.patchValue({
                patientRegistrationChargeId: record.patientRegistrationChargeId,
                charge: record.charge,
                chargeCategoryId: record.chargeCategoryId
            });
        }
        this.modalRef = this.modalService.open(content, {
            backdrop: "static",
            keyboard: false,
            centered: false,
            windowClass: "custom-modal effect-scale"
        });
    }


    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.fetchAll();
                } else {
                    this.page.userAccount = undefined;
                }
            });
    }

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