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

class TrackBy {
    special(item: Specialization) {
        return item.specializationId;
    }
    resource(item: IResource) {
        return item.id;
    }
}
class FilterOptions {
    specializationId?: number = null;
    locationId?: number = null;
    active?: boolean = true;
}

class Filters {
    options: FilterOptions;
    applied: boolean;

    constructor() {
        this.init();
    }

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

@Component({
    templateUrl: "./specializations.html",
    encapsulation: ViewEncapsulation.None
})
export class SpecializationPage implements OnInit, OnDestroy {
    page: Page;
    pagination: Pagination;
    trackBy: TrackBy;
    activeRoute: string;
    isEdit: boolean = false;
    filters: Filters;
    specialization: Array<Specialization>;
    selectedSpecialization: Specialization;
    loading: boolean;
    modalRef: NgbModalRef;
    uploadForm: FormGroup;
    modifying: boolean;
    icons: Array<IconModel>;
    iconLoading: boolean;
    iconPagination: Pagination;
    submitting: boolean;
    submitted: boolean;
    errorMessage: string;
    warningMessage: string;
    modifyingContent: string;
    locations: Array<IResource>;
    specializationsAll: Array<IResource>;
    loadingSpecialization: boolean;
    specializationForm: FormGroup;
    encounterType: IResource[];

    constructor(
        private readonly appData: AppData,
        private readonly httpService: HttpService,
        private readonly router: Router,
        private readonly modalService: NgbModal,
        private readonly notifyService: NotifyService,
        private readonly formBuilder: FormBuilder,
        private readonly resourceService: ResourceService
    ) {
        this.page = new Page();
        this.icons = new Array<IconModel>();
        this.initIconPagination();
        //this.buildSpecializationForm();
        this.buildspecializationAllForm();
        this.trackBy = new TrackBy();
        this.filters = new Filters();
    }

    safe = (url: any) => {
        if (url) {
            return `assets/images/SpecializationIcons/${url}`
        }
    }

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

    private initIconPagination() {
        this.iconPagination = new Pagination();
        this.iconPagination.pageIndex = 1;
        this.iconPagination.pageSize = 12;
    }

    //private buildSpecializationForm() {
    //    this.uploadForm = this.formBuilder.group({
    //        specializationName: ["", [Validators.required]],
    //        specializationActive: [false, [Validators.required]],
    //        specializationIconId: [0],
    //        specializationJson: [null],
    //        specializationDescription: [""],
    //        locationId: [0],
    //        url: [null],

    //        priority: [null]
    //        //createdBy: [this.page.userAccount.accountId, [Validators.required]]
    //    });
    //}
    private buildspecializationAllForm() {
        this.specializationForm = this.formBuilder.group({
            specializationIds: [0],
            locatlocationIds: [0]
        });
    }

    onApplyFilters() {
        this.filters.applied = UtilHelper.isFiltersApplied(this.filters.options);
        this.loading = true;
        this.fetchSpecializations();

        this.onCloseFilters();
    }

    onCloseFilters() {
        $("body").removeClass("right-bar-enabled");
    }

    onResetFilters() {
        this.loading = true;
        this.filters.init();
        this.fetchSpecializations();

        this.onCloseFilters();
    }

    private fetchSpecializations() {
        this.loading = true;
        const request = {
            ...this.pagination,
            ...this.filters.options
        };
        this.httpService.post(ApiResources.getURI(ApiResources.specialization.base, ApiResources.specialization.fetch), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => { this.loading = false }))
            .subscribe((response: Array<any>) => {
                this.specialization = response;
                UtilHelper.applyPagination(this.specialization, this.pagination);
            });
    }

    private fetchSpecializationsAll() {
        this.loadingSpecialization = true;
        this.resourceService.specializations()
            .pipe(finalize(() => { this.loadingSpecialization = false }))
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((response: Array<IResource>) => {
                this.specializationsAll = response;
            });
    }


    private buildForm() {

        this.uploadForm = this.formBuilder.group({
            specializationId: 0,
            specializationIconId: 0,
            specializationName: [null, [Validators.required, WhiteSpaceValidator.isValid]],
            specializationDescription: "",
            url: "",
            priority: 3,
            locationIds: [null, [Validators.required]],
            encounterTypeId: [null]
        });
    }

    get form() { return this.uploadForm.controls }

    onOpenModal(content: TemplateRef<any>, specialization?: Specialization) {
        this.fetchLocations();
        this.fetchEncounterType();
        this.buildForm();
        this.fetchIcons();


        if (specialization) {

            var locationIds = new Array<number>();
            if (specialization && specialization.locationIds) {
                specialization.locationIds.split(",").forEach((item) => {
                    locationIds.push(parseInt(item))
                });
            }
            //let locationIds = new Array<number>();
            //specialization.locationIds.split(",").forEach((item) => { locationIds.push(parseInt(item)) });

            this.uploadForm.patchValue({
                specializationId: specialization.specializationId,
                specializationIconId: specialization.specializationIconId,
                specializationName: specialization.specializationName,
                specializationDescription: specialization.specializationDescription,
                url: specialization.url,
                priority: specialization.priority,
                locationIds: locationIds,
                encounterTypeId: specialization.encounterTypeId
            });
        }




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

    onSubmit() {
        this.submitted = true;
        if (!this.uploadForm.valid) {
            return;
        }
        this.errorMessage = undefined;
        this.submitting = true;
        const model = Object.assign(UtilHelper.clone(this.uploadForm.getRawValue()));
        //if (model.locationIds) {
        //    model.locationIds = model.locationIds.join(",")
        //}
        if (model["locationIds"]) {
            model["locationIds"] = model.locationIds.join(",");
        }

        if (model["specializationId"] === 0) {
            model["createdBy"] = this.page.userAccount.accountId;
            model["createdByName"] = this.page.userAccount.fullName;
            model["loginRoleId"] = this.page.userAccount.roleId;
            this.httpService
                .postFile(ApiResources.getURI(ApiResources.specialization.base, ApiResources.specialization.add), model)
                .pipe(finalize(() => { this.submitted = false, this.submitting = false; }))
                .pipe(takeUntil(this.page.unSubscribe))
                .subscribe(
                    () => {
                        this.notifyService.success("Specialization added successfully.");
                        this.onCloseModal();
                        this.fetchSpecializationsAll();
                        this.fetchSpecializations();
                    },
                    (error: HttpErrorResponse) => {
                        this.errorMessage = UtilHelper.handleError(error);
                        this.notifyService.warning(this.errorMessage);
                    }
                );
        } else {
            model["modifiedBy"] = this.page.userAccount.accountId;
            model["modifiedByName"] = this.page.userAccount.fullName;
            model["loginRoleId"] = this.page.userAccount.roleId;
            this.httpService
                .put(ApiResources.getURI(ApiResources.specialization.base, ApiResources.specialization.update), model)
                .pipe(finalize(() => { this.submitted = false, this.submitting = false; }))
                .pipe(takeUntil(this.page.unSubscribe))
                .subscribe(
                    () => {
                        this.notifyService.success("Specialization details updated successfully.");
                        this.onCloseModal();
                        this.fetchSpecializationsAll();
                        this.fetchSpecializations();
                    },
                    (error: HttpErrorResponse) => {
                        this.errorMessage = UtilHelper.handleError(error);
                        this.notifyService.warning(this.errorMessage);
                    }
                );
        }
    }

    onDelete(specialization: Specialization) {
        specialization.modifiedBy = this.page.userAccount.accountId;
        this.notifyService.delete(() => {
            this.httpService
                .post(ApiResources.getURI(ApiResources.specialization.base, ApiResources.specialization.delete), { specializationId: specialization.specializationId })
                .pipe(takeUntil(this.page.unSubscribe))
                .subscribe(
                    () => {
                        this.notifyService.success("specialization deleted successfully.");
                        this.fetchSpecializationsAll();
                        this.fetchSpecializations();
                    }
                );
        });
    }

    onCloseModal() {
        if (this.modalRef) {
            this.modalRef.close();
            this.modalRef = undefined;
            this.submitted = undefined;
            this.submitting = undefined;
            this.errorMessage = undefined;
            this.warningMessage = undefined;
            this.modifyingContent = undefined;
        }
    }

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

    onIconSelect(icon: IconModel) {
        this.uploadForm.patchValue({
            specializationIconId: icon.iconsId,
            url: icon.url
        });
    }

    //onRemoveIcon() {
    //    this.uploadForm.patchValue({
    //        specializationIconId: null
    //    });
    //}

    onEditIcon() {
        this.uploadForm.patchValue({
            specializationIconId: 0
        });
    }

    fetchIcons() {
        const model = {
            pageSize: this.iconPagination.pageSize,
            pageIndex: this.iconPagination.pageIndex
        };
        this.iconLoading = true;
        this.httpService.post(ApiResources.getURI(ApiResources.icons.base, ApiResources.icons.fetchIcons), model)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => {
                this.iconLoading = false;
            }))
            .subscribe((response: Array<IconModel>) => {

                this.icons = response;
                UtilHelper.applyPagination(this.icons, this.iconPagination);
            }, (error: HttpErrorResponse) => {
                const errorMessage = UtilHelper.handleError(error);
                if (errorMessage) {
                    this.notifyService.warning("Error occurred while fetching icons.");
                } else {
                    this.notifyService.defaultError();
                }
            });
    }

    updateStatus(specialization: Specialization) {
        specialization.modifiedBy = this.page.userAccount.accountId;
        this.httpService
            .put(ApiResources.getURI(ApiResources.specialization.base, ApiResources.specialization.modifyStatus), specialization)
            .subscribe(() => {
                specialization.active = !specialization.active;
                this.fetchSpecializations();
            });
    }

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

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

    ngOnInit() {
        this.appData.userAccount
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((account: IUserAccount) => {
                if (account) {
                    this.page.userAccount = account;
                    const url = this.router.url;
                    this.activeRoute = url.split("/")[url.split("/").length - 1];
                    this.initPagination();
                    this.fetchSpecializationsAll();
                    this.fetchSpecializations();
                    this.fetchLocations();
                    this.fetchEncounterType();

                } else {
                    this.page.userAccount = undefined;
                }
            });
    }

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