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


class TrackBy {
    charge(item: ChargeManagement) {
        return item.chargeGroupId;
    }
}

class FilterOptions {
    wardName: string = null;
    departmentId?: number;
    chargeGroupId: number;
    repeatTypeId: number;
    locationIds?: number;
    fromDate: string = null;
    toDate: string = null;
}

class Filters {
    options: FilterOptions;
    applied: boolean;

    constructor() {
        this.init();
    }

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

@Component({
    templateUrl: "./department.html",
    encapsulation: ViewEncapsulation.None
})
export class DepartmentPage implements OnInit, OnDestroy {
    page: Page;
    filters: Filters;
    trackBy: TrackBy;
    pagination: Pagination;
    showCharge: boolean;

    loading: boolean;
    departmentManagements: Array<ChargeManagement>;
    chargeGroupManagements: Array<ChargeManagement>;
    chargeManagements: Array<ChargeManagement>;
    selectedbedManagements: ChargeManagement;
    selectedChargeManagement: ChargeManagement;
    showDepartments: boolean = false;
    showChargeGroups: boolean = false;
    showCharges: boolean = false;
    modifying: boolean;
    modifyingContent: string;
    loadingDepartments: boolean;
    loadingChargeGroups: boolean;
    loadingCharges: boolean;
    departments: Array<ChargeManagement>;
    chargeGroups: Array<ChargeManagement>;
    charges: Array<ChargeManagement>;

    selectedDepartment: ChargeManagement;
    selectedChargeGroup: ChargeManagement;
    selectedCharges: ChargeManagement;

    selectedbedRooms: ChargeManagement;
    chargeManagement: ChargeManagement;
    department: ChargeManagement;
    chargeGroup: ChargeManagement;
    charge: ChargeManagement;

    modalRef: NgbModalRef;
    departmentManagementForm: FormGroup;
    chargeGroupManagementForm: FormGroup;
    chargeManagementForm: FormGroup;
    submitting: boolean;
    submitted: boolean;
    departmentTypeId: number;
    chargeGroupTypeId: number;

    locations: Array<IResource>;

    loadingDepts: boolean;
    dept: Array<IResource>;
    setMaxDate: NgbDate;
    setMinDate: NgbDate;
    pathologyEdit: boolean=true;

    constructor(
        private readonly appData: AppData,
        private readonly modalService: NgbModal,
        private readonly formBuilder: FormBuilder,
        private readonly notifyService: NotifyService,
        private readonly httpService: HttpService,
        private readonly resourceService: ResourceService
    ) {
        this.loading = true;
        this.page = new Page();
        this.filters = new Filters();
        this.trackBy = new TrackBy();
        this.loading = true;
        this.initPagination();
        this.selectedChargeManagement = new ChargeManagement();
        this.department = new ChargeManagement();
    }
    private fetchDeptAll() {
        this.loadingDepts = true;
        this.resourceService.department()
            .pipe(finalize(() => { this.loadingDepts = false }))
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((response: Array<IResource>) => {
                this.dept = response;
            });
    }
    private initPagination() {
        this.pagination = new Pagination();
        this.pagination.pageIndex = 1;
        this.pagination.pageSize = 10;
    }

    private fetchLocations() {
        this.resourceService.locations()
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((response: Array<IResource>) => {
                this.locations = response;
            });
    }

    fetchDeparments() {       
        this.loadingDepartments = true;
        this.showDepartments = true;
        this.showChargeGroups = false;
        this.showCharges = false;
        const request = Object.assign(UtilHelper.clone(this.filters.options), UtilHelper.clone(this.pagination));
        this.httpService.post<Array<ChargeManagement>>(ApiResources.getURI(ApiResources.department.base, ApiResources.department.fetch), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => this.loadingDepartments = false))
            .subscribe((response: Array<ChargeManagement>) => {
                this.departments = response;
                UtilHelper.applyPagination(this.departments, this.pagination);
            });
    }

    private departmentForm() {
        this.departmentManagementForm = this.formBuilder.group({
            departmentId: 0,
            departmentName: [null, [Validators.required, WhiteSpaceValidator.isValid]],
            deptType: [null, [Validators.required, WhiteSpaceValidator.isValid]],
            active: [true],
            locationIds: [null, [Validators.required]]
        });
    }   

    onOpenDepartmentModel(content: TemplateRef<any>, department?: ChargeManagement) {
        
        this.departmentForm();
        var deptId = this.departmentManagementForm.get("departmentId").value;
        if (deptId == 0) {
            this.pathologyEdit = true;
        }
        if (department) {           
            this.department = department;
            this.updateDepartmentForm();

            if (department.locationIds) {
                let location = new Array<number>();
                department.locationIds.split(",").forEach((item) => { location.push(parseInt(item)) });
                this.departmentManagementForm.patchValue({
                    locationIds: location
                });
            }          
        }

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

    private updateDepartmentForm() {
        this.departmentManagementForm.patchValue({
            departmentId: this.department.departmentId,
            departmentName: this.department.departmentName,
            deptType:this.department.deptType,
        });        

        var getControl = this.departmentManagementForm.controls["departmentName"];
        var getControlofDepartmentType = this.departmentManagementForm.controls["deptType"];

        if (this.department && this.department.departmentName === "Pathology") {
            getControl.disable();
            getControlofDepartmentType.disable();
        } else {
            getControl.enable();
            getControlofDepartmentType.enable();
        }
    }

    onSubmit() {
        this.submitted = true;
        if (!this.departmentManagementForm.valid) {
            return;
        }

        this.submitting = true;
        const request = Object.assign(UtilHelper.clone(this.departmentManagementForm.getRawValue()));
        request["modifiedByName"] = this.page.userAccount.fullName;

        if (request.locationIds) {
            request.locationIds = request.locationIds.join(",")
        }

        if (this.departmentManagementForm.value.departmentId === 0) {
            request.createdBy = this.page.userAccount.accountId;
            this.httpService.post(ApiResources.getURI(ApiResources.department.base, ApiResources.department.add), request)
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => {
                    this.submitting = false;
                    this.submitted = false;
                }))
                .subscribe(() => {
                    this.onCloseModal();
                    this.fetchDeparments();
                    this.fetchDeptAll();
                    this.notifyService.success("Department has been added successfully.");
                }, (error: HttpErrorResponse) => {
                    const errorMessage = UtilHelper.handleError(error);
                    if (errorMessage) {
                        this.notifyService.warning(errorMessage);
                    } else {
                        this.notifyService.defaultError();
                    }
                });
        } else {
            request["modifiedByName"] = this.page.userAccount.fullName;
            request["createdBy"] = this.page.userAccount.accountId;
            request.modifiedBy = this.page.userAccount.accountId;
            delete request.type;
            this.httpService.put(ApiResources.getURI(ApiResources.department.base, ApiResources.department.update), request)
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => {
                    this.submitting = false;
                    this.submitted = false;
                }))
                .subscribe(() => {
                    this.onCloseModal();
                    this.fetchDeparments();
                    this.fetchDeptAll();
                    this.notifyService.success("Department 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.departmentManagementForm.controls;
    }

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

        this.submitting = undefined;
        this.submitted = undefined;
        this.department = new ChargeManagement();
    }    

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

    onDeleteDepartment(department: ChargeManagement) {
        
        this.notifyService.delete(() => {
            this.httpService
                .post(ApiResources.getURI(ApiResources.department.base, ApiResources.department.delete), {
                    departmentId: department.departmentId, 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("Department deleted successfully.");
                        this.fetchDeparments();
                        this.fetchDeptAll();
                    }
                );
        }, () => { });
    }   

    ngOnInit() {
        
        this.appData.userAccount
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((userAccount: IUserAccount) => {
                if (userAccount) {
                    this.page.userAccount = userAccount;
                    this.fetchDeparments();
                    // this.fetchChargeGroup();
                    //this.fetchCharges();
                    
                    this.fetchLocations();
                    this.fetchDeptAll();
                } else {
                    this.page.userAccount = undefined;
                }
            });
    }

    onApplyFilters() {

        this.filters.applied = UtilHelper.isFiltersApplied(this.filters.options);        
        this.loading = true;
        this.setMaxDate = null;
        this.setMinDate = null;
        this.fetchDeparments();        
    }

    onResetFilters() {
        this.filters.init();
        this.setMaxDate = null;
        this.setMinDate = null;
        this.fetchDeparments();       
    }

    ngOnDestroy() {
        this.onCloseModal();
        this.page.unsubscribeAll();
    }
    getMinDate() {
        const date = this.filters.options.fromDate.split("-");
        const year = Number(date[0]);
        const month = Number(date[1]);
        const day = Number(date[2]);
        this.setMinDate = new NgbDate(year, month, day);
    }

    getMaxDate() {
        const date = this.filters.options.toDate.split("-");
        const year = Number(date[0]);
        const month = Number(date[1]);
        const day = Number(date[2]);
        this.setMaxDate = new NgbDate(year, month, day);
    }
}