import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { Editor } from 'primeng/editor';
import { Subscription } from 'rxjs/Subscription';
import { environment } from '../../../environments/environment';

import { AppService } from '../../app.service';
import { ASSOCS } from '../../constants';
import { ChatAttachmentModel } from '../../models/chat-attachment.model';
import { JobApplicationModel } from '../../models/job-application.model';
import { MessageModel } from '../../models/message.model';
import { SentViaEnum } from '../../models/sent-via.enum';
import { IframeMsgHandlingService } from '../../oneit/services/iframe-msg-handling.service';
import { MsgsService } from '../../oneit/services/msgs.service';
import { SaveService } from '../../oneit/services/save.service';
import { UtilsService } from '../../oneit/services/utils.service';
import { AdminPortalLayoutService } from '../admin-portal/admin-portal-layout/admin-portal-layout.service';
import { BaseComponent } from '../admin-portal/base/base.component';
import { MessageEngineApplicantViewService } from './message-engine-applicant-view.service';

@Component({
    selector: 'app-message-engine-applicant-view',
    templateUrl: './message-engine-applicant-view.component.html',
    styleUrls: ['./message-engine-applicant-view.component.scss']
})
export class MessageEngineApplicantViewComponent extends BaseComponent implements OnInit {

    @Input() embedded = false;
    // tslint:disable-next-line:prefer-output-readonly
    @Output() minimize: EventEmitter<any> = new EventEmitter<any>();
    subscriptions: Array<Subscription> = [];
    @ViewChild('form') form: NgForm;
    @ViewChild('message') messageEditor: Editor;
    createdObjs = {};
    updatedObjs = {};
    deletedObjs = {};

    jobApplication = new JobApplicationModel();
    sentViaEnum: Array<SentViaEnum>;
    Message = new MessageModel();
    apiUrl = environment.baseUrl;
    jobId: string;
    loggedInId: string;
    showLoader = false;
    previousUrl: string;

    constructor(
        private router: Router,
        private activatedRoute: ActivatedRoute,
        private utilsService: UtilsService,
        private saveService: SaveService,
        private appService: AppService,
        private messageEngineApplicantViewService: MessageEngineApplicantViewService,
        private adminPortalLayoutService: AdminPortalLayoutService,
        private iframeMsgHandlingService: IframeMsgHandlingService,
        private msgService: MsgsService
    ) {
        super(utilsService);
        router.events
            .filter(event => event instanceof NavigationEnd)
            .subscribe((e: any) => {
                this.previousUrl = e.url;
            });
    }

    ngOnInit(): void {
        this.utilsService.resetCounter();
        // Subscribe to msgReceived of iframeMsgHandlingService to get JobId
        this.subscriptions.push(this.iframeMsgHandlingService.msgReceived.subscribe(
            (message: any) => {
                if (!message || !message.name) {
                    return;
                }

                if (message.name !== 'HiringTeamChat' || message.message === null) {
                    return;
                }

                const msg = JSON.parse(message.message);
                this.jobId = msg.JobApplicationID;

                this.showLoader = true;
                this.subscriptions.push(
                    this.appService.getTypes('SentVia')
                        .subscribe((data: Array<SentViaEnum>) => {
                            this.sentViaEnum = data;
                            if (this.embedded) {
                                if (this.adminPortalLayoutService.userData) {
                                    this.loggedInId = this.adminPortalLayoutService.userData.CompanyUser.User;
                                    this.initComponent();
                                } else {
                                    this.subscriptions.push(this.adminPortalLayoutService.userDataUpdated
                                        .first()
                                        .subscribe(() => {
                                            this.loggedInId = this.adminPortalLayoutService.userData.CompanyUser.User;
                                            this.initComponent();
                                        }));
                                }
                            } else {
                                // For applicant
                                this.embedded = false;
                                this.loggedInId = msg.CandidateID;
                                this.initComponent();
                                // Use candidate ID fetched from iFrameService
                            }
                        })
                );
            }
        ));
    }

    initComponent(): void {
        if (this.jobId) {
            this.getEngineApplicantViewByID(this.jobId);
        } else {
            this.utilsService.createObject(this.jobApplication, this.createdObjs);
            this.Message.JobApplication = this.jobApplication;
            this.Message.Attachments = [];
            this.showLoader = false;
            this.setEditorClass();
            this.createMessage();
        }
    }

    getEngineApplicantViewByID(jobId: string): void {

        this.showLoader = true;
        this.utilsService.resetCounter();
        this.utilsService.clearErrorMessages();
        this.createdObjs = {};
        this.createMessage();

        const assocs =
            [ASSOCS.JOB, [ASSOCS.JOB, ASSOCS.HIRING_TEAM].join('.'), ASSOCS.MESSAGES, [ASSOCS.MESSAGES, ASSOCS.SENT_BY].join('.'),
                [ASSOCS.MESSAGES, ASSOCS.ATTACHMENTS].join('.')];
        this.subscriptions.push(this.messageEngineApplicantViewService.getEngineApplicantViewByID(jobId, assocs)
            .subscribe(
                data => {
                    this.jobApplication = data;
                    this.jobApplication.Messages = this.jobApplication.Messages || [];
                    this.Message.JobApplication = this.jobApplication;
                    this.Message.Attachments = [];
                    this.utilsService.sort(this.jobApplication.Messages, ['ObjectCreated'], [1]);

                    this.showLoader = false;
                    setTimeout(() => {
                        const msgWrapper = document.getElementsByClassName('messages-wrapper')[0];
                        msgWrapper.scrollTop = msgWrapper.scrollHeight;
                    }, 0);
                    this.setEditorClass();
                },
                error => {
                    this.showLoader = false;
                    this.utilsService.handleError(error);
                }
            )
        );
    }

    markAsRead(): void {
        this.showLoader = true;
        const params = {
            formParams: {
                JobApplication: this.jobApplication.ObjectID
            }
        };
        this.appService.processObjects('MarkAsRead', params)
            .subscribe(
                () => this.showLoader = false,
                err => {
                    this.utilsService.handleError(err);
                    this.showLoader = false;
                }
            );
    }

    saveEngineApplicantView(): void {
        this.utilsService.clearErrorMessages();

        if (this.form.invalid || this.IsMessageEmpty()) {
            this.utilsService.showAllErrorMessages();
        } else {
            this.showLoader = true;
            this.subscriptions.push(this.saveService.saveObjectsWithDefaultSvc(this.createdObjs, this.updatedObjs, this.deletedObjs)
                .subscribe(
                    data => {
                        this.utilsService.handleSuccess();
                        let idToNavigate = this.jobApplication.ObjectID;
                        if (data.created[idToNavigate]) {
                            idToNavigate = data.created[idToNavigate];
                        }
                        this.getEngineApplicantViewByID(idToNavigate);
                    },
                    error => {
                        this.showLoader = false;
                        this.utilsService.handleError(error);
                    }
                )
            );
        }
    }

    onUpload(event: any): void {
        const chatAttachment = new ChatAttachmentModel();
        this.utilsService.createObject(chatAttachment, this.createdObjs);
        chatAttachment.File = {
            FileToken: JSON.parse(event.xhr.response).files[0].token,
            Name: JSON.parse(event.xhr.response).files[0].fileName
        };
        chatAttachment.Message = this.Message;
        this.Message.Attachments.push(chatAttachment);
    }

    createMessage(): void {
        this.Message.SentBy = this.loggedInId;
        this.Message.SentVia = this.sentViaEnum[2] ? this.sentViaEnum[2] : this.sentViaEnum[0];
        this.utilsService.createObject(this.Message, this.createdObjs);
    }

    /**
     * Helper functions
     */

    updateSentVia($event): void {
        this.Message.SentVia = this.sentViaEnum.find(opt => opt.Value === $event.Value);
    }

    setEditorClass(): void {
        setTimeout(() => {
            const editElement = this.messageEditor.getQuill().container;

            if (!editElement) {
                return;
            }

            const editor = editElement.getElementsByClassName('ql-editor');

            if (!editor[0]) {
                return;
            }

            editor[0].classList.add('form-control');
            editor[0].classList.add('editor');
            editor[0].innerHTML = '';

        }, 0);
    }

    /**
     * Convert rich text into simple text and check if is empty or not!
     */
    showPlainText(HTMLTitle: string): string {

        if (HTMLTitle === undefined) {
            return '';
        }

        const temp = document.getElementById('showPlainText');
        temp.innerHTML = HTMLTitle;
        const title = temp.innerText.trim();
        temp.innerHTML = '';

        return title;
    }

    IsMessageEmpty(): boolean {
        if (this.showPlainText(this.Message.MessageContent) === '') {
            this.msgService.addErrorMessages(
                [this.utilsService.getValidationMessage('required', 'Message Content', {})]
            );
            this.messageEditor.getQuill()
                .focus();

            return true;
        }

        return false;
    }

}
