import { HttpErrorResponse } from "@angular/common/http";
import { Component, OnDestroy, OnInit, TemplateRef, ViewEncapsulation, ViewChild, ElementRef } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap";
import { DietGuidlinesModel } from "@shared/entities";
import { ModalType } from "@shared/enums";
import { ApiResources, UtilHelper } from "@shared/helpers";
import { IUserAccount, Page, ProgressData, Pagination, IResource } from "@shared/models";
import { AppData, HttpService, NotifyService, ResourceService } from "@shared/services";
import { finalize, takeUntil } from "rxjs/operators";
import { DomSanitizer } from '@angular/platform-browser';
import { WhiteSpaceValidator } from "../../../../../shared/validators";
import { PdfViewerModule } from 'ng2-pdf-viewer';

@Component({
    templateUrl: "./diet-guidlines.html",
    encapsulation: ViewEncapsulation.None
})
export class DietGuidLinesPage implements OnInit, OnDestroy {
    @ViewChild("videoPlayer", { static: false }) videoPlayer: ElementRef;

    page: Page;
    modalType = ModalType;
    pagination: Pagination;

    loading: boolean;
    documents: Array<DietGuidlinesModel>;
    document: DietGuidlinesModel;

    modalRef: NgbModalRef;
    uploadForm: FormGroup;
    maxFiles = 1;
    files: Array<File>;
    submitting: boolean;
    submitted: boolean;
    errorMessage: string;
    warningMessage: string;
    modifyingContent: string;

    loadingDocument: boolean;
    documentError: boolean;
    showPrevious: boolean;
    showNext: boolean;


    modifying: boolean;
    loadingDietTypes: boolean;
    dietTypes: Array<IResource>;

    constructor(
        private readonly httpService: HttpService,
        private readonly modalService: NgbModal,
        private readonly notifyService: NotifyService,
        private readonly formBuilder: FormBuilder,
        private readonly appData: AppData,
        private readonly sanitizer: DomSanitizer,
        private readonly resourceService: ResourceService,
    ) {
        this.page = new Page();
        this.initPagination();
        this.documents = new Array<DietGuidlinesModel>();
        this.dietTypes = new Array<IResource>();
    }

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

    private fetchDocuments() {
        this.loading = true;
        const request = Object.assign(UtilHelper.clone(this.pagination));
        this.httpService.post(ApiResources.getURI(ApiResources.dietGuidlines.base, ApiResources.dietGuidlines.fetch), request)
            .pipe(takeUntil(this.page.unSubscribe))
            .pipe(finalize(() => { this.loading = false }))
            .subscribe((response: Array<DietGuidlinesModel>) => {
                console.log(response);
                this.documents = response;

                UtilHelper.applyPagination(this.documents, this.pagination);
            });
    }



    private buildForm(document?: DietGuidlinesModel) {
        this.uploadForm = this.formBuilder.group({
            dietGuidLinesId: [document && document.dietGuidLinesId ? document.dietGuidLinesId : 0, [Validators.required]],
            dietGuidLinesName: [document && document.dietGuidLinesName ? document.dietGuidLinesName : "", [Validators.required, WhiteSpaceValidator.isValid]],
            dietTypeId: [document && document.dietTypeId ? document.dietTypeId : null, [Validators.required]]
        });
    }

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

    private prepareDocument(document: DietGuidlinesModel) {
        this.loadingDocument = true;
        this.document = document;
        this.documentError = false;
        this.document.isImage = this.document.contentType.indexOf("pdf") < 0 && this.document.contentType.indexOf("video") < 0;
        this.document.isVideo = this.document.contentType.indexOf("video") >= 0;

        if (this.document.isImage || this.document.isVideo) {
            this.document.formedUrl = this.sanitizer.bypassSecurityTrustResourceUrl(`${ApiResources.getURI(ApiResources.dietGuidlines.base, ApiResources.dietGuidlines.downloadFileGet)}?id=${this.document.dietGuidLinesId}&url=${this.document.documentUrl}`);
        }

        if (!this.document.isImage && !this.document.isVideo) {
            this.httpService
                .post(ApiResources.getURI(ApiResources.dietGuidlines.base, ApiResources.dietGuidlines.downloadFile), { ...document })
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => { this.loadingDocument = false; }))
                .subscribe(
                    (response: DietGuidlinesModel) => {
                        this.document.formedUrl = this.sanitizer.bypassSecurityTrustResourceUrl(`data:application/pdf;base64, ${response.base64}`);
                    }
                );

        } else {
            this.loadingDocument = false;
        }
    }

    toggleVideo() {
        this.videoPlayer.nativeElement.play();
    }

    onDocumentLoad() {
        this.loadingDocument = false;
    }

    onDocumentError() {
        this.loadingDocument = false;
        this.documentError = true;
    }

    onOpenModal(content: TemplateRef<any>, type: ModalType, document?: DietGuidlinesModel) {
        if (type === ModalType.View) {
            this.prepareDocument(document);
            const index = this.documents.findIndex((m => m.dietGuidLinesId === this.document.dietGuidLinesId) as any);
            if (index === 0 && this.documents.length === 1) {
                this.showPrevious = false;
                this.showNext = false;
            } else if (index === 0) {
                this.showPrevious = false;
                this.showNext = true;
            } else if (index === this.documents.length - 1) {
                this.showPrevious = true;
                this.showNext = false;
            } else {
                this.showPrevious = true;
                this.showNext = true;
            }

            this.modalRef = this.modalService.open(content, {
                keyboard: false,
                centered: true,
                windowClass: "document-view-modal custom-modal effect-scale"
            });
        } else if (type === ModalType.Edit) {
            this.document = document;
            this.buildForm(document);

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

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

    onModifyStatus(item: DietGuidlinesModel, status: boolean) {

        this.notifyService.confirm(`You want to ${status ? 'Activate' : 'Deactivate'} this diet Type?`, () => {
            const request = {
                modifiedBy: this.page.userAccount.accountId,
                active: status,
                dietGuidLinesId: item.dietGuidLinesId,
                modifiedByName: this.page.userAccount.fullName,
                createdByRole: this.page.userAccount.roleName,
                loginRoleId: this.page.userAccount.roleId,
                dietGuidLinesName: item.dietGuidLinesName
            };

            this.httpService.post(ApiResources.getURI(ApiResources.dietGuidlines.base, ApiResources.dietGuidlines.modifyStatus), request)
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => { this.loading = false }))
                .subscribe((response: string) => {
                    if (response) {
                        this.notifyService.successToast(`${status ? 'Activated' : 'Deactivated'} successfully.`);
                    }
                    this.fetchDocuments();
                }, (error: HttpErrorResponse) => {
                    this.notifyService.errorToast(error.error);
                });
        });
    }

    onPrevious() {
        let index = this.documents.findIndex((m => m.dietGuidLinesId === this.document.dietGuidLinesId) as any);
        index = index - 1;
        this.showPrevious = index !== 0;
        this.showNext = true;
        this.document = undefined;
        this.prepareDocument(this.documents[index]);
    }

    onNext() {
        let index = this.documents.findIndex((m => m.dietGuidLinesId === this.document.dietGuidLinesId) as any);
        index = index + 1;
        this.showNext = index !== this.documents.length - 1;
        this.showPrevious = true;
        this.document = undefined;
        this.prepareDocument(this.documents[index]);
    }

    onProgress(progressData: ProgressData) {
        if (progressData.loaded === progressData.total) {
            this.loadingDocument = false;
        }
    }

    onCloseModal() {
        if (this.modalRef) {
            this.modalRef.close();
            this.modalRef = undefined;
            this.submitted = undefined;
            this.submitting = undefined;
            this.errorMessage = undefined;
            this.warningMessage = undefined;
            this.files = [];
            this.document = undefined;
            this.loadingDocument = undefined;
            this.documentError = undefined;
            this.showNext = undefined;
            this.showPrevious = undefined;
            this.modifying = undefined;
            this.modifyingContent = undefined;
        }
    }

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

    onFileSelect(files: Array<File>) {
        this.files = files;
    }
    onDelete(document: DietGuidlinesModel) {
        this.notifyService.delete(() => {
            const request = {
                dietGuidLinesId: document.dietGuidLinesId,
                modifiedBy: this.page.userAccount.accountId,
                modifiedByName: this.page.userAccount.fullName,
                documentUrl: document.documentUrl,
                dietGuidLinesName: document.dietGuidLinesName
            };
            this.httpService.post(ApiResources.getURI(ApiResources.dietGuidlines.base, ApiResources.dietGuidlines.delete), request)
                .pipe(takeUntil(this.page.unSubscribe))
                .pipe(finalize(() => this.loading = false))
                .subscribe(
                    (response: number) => {
                        if (response > 0) {
                            this.notifyService.successToast("Record deleted successfully.");
                        }
                        if (response === -3) {
                            this.notifyService.warningToast("The record you tried to delete can't be deleted because it is being used.");
                        }
                        this.fetchDocuments();
                    },

                );
        })
    }
    onSubmit() {
        this.submitted = true;
        if (!this.uploadForm.valid || this.warningMessage) {
            return;
        }

        this.errorMessage = undefined;
        this.submitting = true;
        const model = UtilHelper.clone(this.uploadForm.value);

        if (model["dietGuidLinesId"] === 0) {
            const formData = new FormData();

            formData.append("CreatedBy", this.page.userAccount.accountId.toString());
            formData.append("CreatedByName", this.page.userAccount.fullName);
            formData.append("DietGuidLinesName", model["dietGuidLinesName"]);
            formData.append("DietTypeId", model["dietTypeId"]);
            const files = this.files;

            if (!files || !files.length) {
                this.submitting = false;
                this.notifyService.info("Please select at least one file");
                return;
            }

            const n = files.length;
            if (n > this.maxFiles) {
                files.splice(this.maxFiles, files.length);
            }

            files.forEach((file: File, index: number) => {
                formData.append(`File${index + 1}`, file, file.name);
            });

            this.httpService
                .postFile(ApiResources.getURI(ApiResources.dietGuidlines.base, ApiResources.dietGuidlines.insert), formData)
                .pipe(finalize(() => { this.submitted = false; this.submitting = false; }))
                .pipe(takeUntil(this.page.unSubscribe))
                .subscribe(
                    (response: any) => {
                        if (response.length > 0) {
                            this.files = new Array();
                            this.notifyService.successToast("Document uploaded successfully.");
                        }
                        if (response <= 0) {
                            this.notifyService.warningToast("Document name exists already.");
                        }
                        this.onCloseModal();
                        this.fetchDocuments();
                    },
                    (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;

            delete model["file"];
            this.httpService
                .put(ApiResources.getURI(ApiResources.dietGuidlines.base, ApiResources.dietGuidlines.update), model)
                .pipe(finalize(() => { this.submitted = false, this.submitting = false; }))
                .pipe(takeUntil(this.page.unSubscribe))
                .subscribe(
                    () => {
                        this.notifyService.successToast("Document details updated successfully.");
                        this.onCloseModal();
                        this.fetchDocuments();
                    },
                    (error: HttpErrorResponse) => {
                        this.errorMessage = UtilHelper.handleError(error);
                        this.notifyService.warning(this.errorMessage);
                    }
                );
        }
    }
    private fetchDietTypes() {
        this.loadingDietTypes = true;
        this.resourceService.dietTypes()
            .pipe(finalize(() => { this.loadingDietTypes = false }))
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((response: Array<IResource>) => {
                this.dietTypes = response;
            })
    }
    ngOnInit() {
        this.appData.userAccount
            .pipe(takeUntil(this.page.unSubscribe))
            .subscribe((account: IUserAccount) => {
                if (account) {
                    this.page.userAccount = account;

                    this.fetchDietTypes();
                    this.fetchDocuments();
                }
            });
    }

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