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


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

    loading: boolean;
    modalRef: NgbModalRef;

    loadingRoles: boolean;
    roles: Array<IResource>;
    discounts: Array<IResource>;
    submitted: boolean;
    submitting: boolean;
    moduleForm: FormGroup;
    modules: Array<DiscountModule>;
    discountForm: FormGroup;

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

    private buildModuleForm() {
        this.moduleForm = this.formBuilder.group({
            discountModuleId: 0,
            moduleName: [null, [Validators.required]],
            icon: [""],
            roles: [null, [Validators.required]],
            createdBy: 0
        });
    }

    private buildDiscountForm() {
        this.discountForm = this.formBuilder.group({
            discountsPerModuleId: 0,
            discountModuleId: [null, [Validators.required]],
            roleId: [null, [Validators.required]],
            createdBy: [null],
            allowedPercentage: [null, [Validators.required, Validators.max(100), Validators.min(1)]]
        });
    }

    onModuleFormOpen(content: TemplateRef<any>, module?: DiscountModule) {
        this.buildModuleForm();
        if (module) {
            let role = new Array<number>();
            module.roles.split(",").forEach((item) => {
                role.push(parseInt(item));
            });
            this.moduleForm.patchValue({
                discountModuleId: module.discountModuleId,
                active: true,
                moduleName: module.moduleName,
                icon: module.icon,
                roles: role
            });
            const control = this.moduleForm.controls["moduleName"];
            control.disable();
        }
        this.onOpenModel(content);
    }

    onModuleFormSubmit() {
        this.submitted = true;
        if (!this.moduleForm.valid) {
            return;
        }
        this.submitting = true;
        const request = this.moduleForm.getRawValue();

        request["roles"] = this.moduleForm.value.roles.toString();
        request["createdBy"] = this.page.userAccount.accountId;
        request["CreatedByName"] = this.page.userAccount.fullName;

        this.httpService.post<number>(ApiResources.getURI(ApiResources.discountManagement.base, ApiResources.discountManagement.modifyModule), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => { this.submitted = this.submitting = false }))
            .subscribe((response: number) => {
                if (response > 0) {
                    this.notifyService.successToast(`Discount module ${request["discountModuleId"] > 0 ? 'updated' : 'created'} successfully.`);
                }
                if (response === -1) {
                    this.notifyService.warningToast("This module already exists.");
                }
                if (response === -2) {
                    this.notifyService.warningToast("Unable to update roles.");
                }
                this.fetchAllModules();
                this.onCloseModal();
            });
    }

    onDiscountModuleSubmit(popover: NgbPopover) {
        this.submitted = true;
        if (this.discountForm.invalid) {
            return;
        }
        this.submitting = true;

        const request = this.discountForm.getRawValue();

        this.httpService.post<number>(ApiResources.getURI(ApiResources.discountManagement.base, ApiResources.discountManagement.modifyDiscountsPerModule), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => { this.submitted = this.submitting = false }))
            .subscribe((response: number) => {
                if (response > 0) {
                    this.notifyService.successToast(`Discount for role ${request["discountsPerModuleId"] > 0 ? 'updated' : 'created'} successfully.`);
                }
                this.fetchAllModules();
                popover.toggle();
            });
    }

    onRoleSelected(module: DiscountModule, role: IResource) {
        this.buildDiscountForm();
        this.submitted = this.submitting = false;
        let discountsPerModuleId = 0;
        let allowedDiscount = null;
        if (module.roleDiscounts.length > 0) {
            const filteredRecord = module.roleDiscounts.filter(m => m.roleId === role.id);
            if (filteredRecord.length > 0) {
                discountsPerModuleId = filteredRecord[0].discountsPerModuleId;
                allowedDiscount = filteredRecord[0].allowedPercentage;
            }
        }

        this.discountForm.patchValue({
            discountsPerModuleId: discountsPerModuleId,
            discountModuleId: module.discountModuleId,
            roleId: role.id,
            createdBy: this.page.userAccount.accountId,
            allowedPercentage: allowedDiscount
        });
    }

    private fetchAllModules() {
        this.loading = true;
        const request = {};
        this.httpService.post<Array<DiscountModule>>(ApiResources.getURI(ApiResources.discountManagement.base, ApiResources.discountManagement.fetchModules), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => { this.loading = false }))
            .subscribe((response: Array<DiscountModule>) => {
                this.modules = response;

                this.modules.forEach((item) => {
                    item.allowedRoles = new Array<IResource>();
                    item.roles.split(",").forEach((i) => {
                        var id = parseInt(i);
                        var findRole = UtilHelper.clone(this.roles.find(m => m.id === id));
                        var findDiscounted = item.roleDiscounts.find(x => x.roleId === id);
                        if (findDiscounted) {
                            findRole.optionalText = findDiscounted.allowedPercentage.toString();
                        }
                        item.allowedRoles.push(findRole);
                    });
                });
            });
    }

    onModifyStatus(item: DiscountModule, status: boolean) {
        this.notifyService.confirm(`You want to ${status ? 'Activate' : 'Deactivate'} this module?`, () => {
            const request = {
                modifiedBy: this.page.userAccount.accountId,
                active: status,
                moduleName: item.moduleName,
                discountModuleId: item.discountModuleId,
                modifiedByName: this.page.userAccount.fullName,
                createdByRole: this.page.userAccount.roleName,
                loginRoleId: this.page.userAccount.roleId,
            };

            this.httpService.post(ApiResources.getURI(ApiResources.discountManagement.base, ApiResources.discountManagement.modifyStatus), request)
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => { this.loading = false }))
                .subscribe((response: number) => {
                    if (response > 0) {
                        this.notifyService.successToast(`${status ? 'Activated' : 'Deactivated'} successfully.`);
                    }
                    this.fetchAllModules();
                });
        });
    }

    get forms() {
        return {
            module: this.moduleForm ? this.moduleForm.controls : {},
            discount: this.discountForm ? this.discountForm.controls : {}
        }
    }

    private fetchRoles() {
        this.loadingRoles = true;
        this.resourceService.roles()
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => this.loadingRoles = false))
            .subscribe((response: Array<IResource>) => {
                this.roles = response;
                var indexOfPatient = this.roles.findIndex((item) => { return item.value === "Patient" });
                if (indexOfPatient >= 0) {
                    this.roles.splice(indexOfPatient, 1);
                }
                var indexOfProvider = this.roles.findIndex((item) => { return (item.value === "Provider" || item.value === "Doctor") });
                if (indexOfProvider >= 0) {
                    this.roles.splice(indexOfProvider, 1);
                }
                this.fetchAllModules();
            });
    }

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

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

    //private fetchDiscounts() {
    //    this.resourceService.discountNames()
    //        .pipe(takeUntil(this.page.unSubscribe))
    //        .subscribe((response: Array<IResource>) => {
    //            this.discounts = response;
    //        });
    //}

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

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