import { Component, OnInit, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { Editor } from 'primeng/editor';
import { OverlayPanel } from 'primeng/overlaypanel';
import { Subscription } from 'rxjs/Subscription';
import { AppService } from '../../app.service';
import { SERVICES } from '../../constants';
import { MessageTemplateModel } from '../../models/messageTemplate.model';
import { PlaceholderOptionsEnum } from '../../models/placeholderOptions.enum';
import { TemplateTypeEnum } from '../../models/templateType.enum';
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 '../base/base.component';
import { EditMessageTemplateService } from './edit-message-template.service';

@Component({
    selector: 'app-edit-message-template',
    templateUrl: './edit-message-template.component.html'
})
export class EditMessageTemplateComponent extends BaseComponent implements OnInit {

    subscriptions: Array<Subscription> = [];
    @ViewChild('form') form: NgForm;
    @ViewChild('messageContent') messageContentEditor: Editor;
    @ViewChild('contentLinkModal') contentLinkModal: OverlayPanel;
    createdObjs;
    updatedObjs;
    deletedObjs;

    messageTemplate = new MessageTemplateModel();
    messageTemplateTypes: Array<TemplateTypeEnum> = [];
    subjectPlaceholderOptions: Array<PlaceholderOptionsEnum> = [];
    contentPlaceholderOptions: Array<PlaceholderOptionsEnum> = [];
    ContentPlaceholderOptionsEnum: Array<PlaceholderOptionsEnum> = [];
    subjectPlaceholder: PlaceholderOptionsEnum;
    contentPlaceholder: PlaceholderOptionsEnum;
    contentCursorPoint;
    temporaryMessageContent = '';
    linkText = '';
    showLoader = false;
    editMode = false;
    options = {minimumResultsForSearch: Infinity};

    constructor(
        private router: Router,
        private activatedRoute: ActivatedRoute,
        private utilsService: UtilsService,
        private saveService: SaveService,
        private appService: AppService,
        private editMessageTemplateService: EditMessageTemplateService,
        private adminPortalLayoutService: AdminPortalLayoutService
    ) {
        super(utilsService);
    }

    ngOnInit(): void {
        this.createdObjs = {};
        this.updatedObjs = {};
        this.deletedObjs = {};
        this.showLoader = true;

        this.utilsService.resetCounter();
        this.getPlaceholderOptions();

        if (!this.adminPortalLayoutService.userData) {
            this.subscriptions.push(this.adminPortalLayoutService.userDataUpdated
                .subscribe(
                    () => {
                        this.startComponent();
                    }
                ));
        }

        this.startComponent();
    }

    startComponent(): void {
        setTimeout(() => {
            this.subscriptions.push(this.appService.getMessageTemplateTypeEnum()
                .subscribe(
                    data => {

                        if (this.createdExists()) {
                            return;
                        }

                        this.messageTemplateTypes = data;
                        this.messageTemplateTypes.map((elem, index) => {
                            elem.id = index;
                            elem.text = elem.Description;
                        });

                        this.subscriptions.push(this.activatedRoute.params
                            .subscribe(
                                (params: Params) => {

                                    if (params.id && params.id !== '0') {
                                        this.editMode = true;

                                        this.getMessageTemplateByID(params.id);
                                    } else {
                                        this.messageTemplate.HiringTeam = this.adminPortalLayoutService.getHiringTeamID().ObjectID;

                                        if (this.messageTemplateTypes) {
                                            this.messageTemplate.TemplateType = this.messageTemplateTypes[0];
                                        }

                                        this.utilsService.createObject(this.messageTemplate, this.createdObjs);
                                        this.setInputListener();
                                        this.showLoader = false;
                                    }

                                }
                            ));
                    },
                    error => {
                        this.utilsService.handleError(error);
                    }
                )
            );
        }, 0);
    }

    showSaveBtn(): boolean {
        return this.messageTemplate && this.messageTemplate.ObjectID ?
            (this.messageTemplate.HiringTeam === this.adminPortalLayoutService.getHiringTeamID().ObjectID ||
                !this.editMode) : false;
    }

    showSaveCopyBtn(): boolean {
        return this.messageTemplate && this.messageTemplate.ObjectID ?
            (!!this.messageTemplate.HiringTeam) : false;
    }

    setInputListener(): void {
        let editElement;
        setTimeout(() => {

            if (this.emailTemplateType()) {
                editElement = this.messageContentEditor.getQuill().container;

                if (editElement) {
                    ['keyup', 'click'].forEach(event => {
                        editElement.addEventListener(event, () => {
                            this.contentCursorPoint = this.messageContentEditor.getQuill()
                                .getSelection().index;
                        });
                    });
                }

            } else {
                editElement = document.getElementById('messageContentTxtAreaId');

                if (editElement) {
                    ['keyup', 'click'].forEach(event => {
                        editElement.addEventListener(event, () => {
                            this.contentCursorPoint = this.getCursorPos(editElement);
                        });
                    });
                }

            }

        }, 0);
    }

    addAnchorText(show: boolean): void {

        if (!show || this.linkText === '') {
            this.contentLinkModal.hide();

            return;
        }

        const delta = {
            ops: [
                {retain: this.contentCursorPoint > 0 ? this.contentCursorPoint : this.contentCursorPoint + 1},
                {insert: this.contentPlaceholder.Placeholder, attributes: {link: this.linkText}}
            ]
        };

        if (this.contentCursorPoint === 0) {
            this.messageContentEditor.getQuill()
                .insertText(this.contentCursorPoint, ' ');
            this.contentCursorPoint++;
        }

        try {
            this.messageContentEditor.getQuill()
                .updateContents(delta);
        } catch (e) {
            this.utilsService.handleError(e);
        }

        this.linkText = '';
        this.contentLinkModal.hide();
    }

    addPlaceholderInMessageContent($event): void {
        this.contentPlaceholder = $event.data[0];

        if (!this.contentPlaceholder || !this.contentPlaceholder.Value) {
            return;
        }

        if (typeof this.contentCursorPoint !== 'number') {
            return;
        }

        if (this.emailTemplateType()) {
            if (this.contentPlaceholder.IsLink) {
                this.contentLinkModal.toggle($event);
            } else {
                this.messageContentEditor.getQuill()
                    .insertText(this.contentCursorPoint, this.contentPlaceholder.Placeholder);
            }
        } else {
            const textarea: HTMLTextAreaElement = document.getElementById('messageContentTxtAreaId') as HTMLTextAreaElement;
            this.setValueAndFocus(textarea, 'messageContentTxtArea', this.contentPlaceholder.Placeholder);
        }

    }

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

        return title;
    }

    storeMessageContent($event): void {
        if (!$event.data[0]) {
            return;
        }
        this.messageTemplate.TemplateType = $event.data[0];

        if (this.messageTemplate.MessageContent !== undefined) {
            if (this.messageTemplate.TemplateType.Description === 'SMS') {
                this.temporaryMessageContent = this.messageTemplate.MessageContent;
                this.messageTemplate.MessageContent = this.showPlainText(this.temporaryMessageContent);
            } else {
                this.messageTemplate.MessageContent = this.temporaryMessageContent !== '' ? this.temporaryMessageContent
                    : this.messageTemplate.MessageContent;
            }
        }

        if (this.ContentPlaceholderOptionsEnum) {
            if (this.emailTemplateType()) {
                this.contentPlaceholderOptions = this.ContentPlaceholderOptionsEnum.filter(option => option.ShowForContent ||
                    option.Value === null);
            } else {
                this.contentPlaceholderOptions = this.ContentPlaceholderOptionsEnum
                    .filter(option => option.ShowForContent && option.Value !== 'JOB_LINK' || option.Value === null);
            }
        }

        this.setInputListener();
    }

    addPlaceholderInSubject($event): void {
        this.subjectPlaceholder = $event.data[0];
        if (this.emailTemplateType() && this.subjectPlaceholder && this.subjectPlaceholder.Value) {
            const input: HTMLInputElement = document.getElementById('subjectInputId') as HTMLInputElement;
            this.setValueAndFocus(input, 'subjectInput', this.subjectPlaceholder.Placeholder);
        }
    }

    getCursorPos(input): number {

        if ('selectionStart' in input && document.activeElement === input) {
            return input.selectionStart;
        }

        return -1;
    }

    getMessageTemplateByID(id): void {
        this.showLoader = true;
        this.createdObjs = {};
        this.updatedObjs = {};
        this.deletedObjs = {};

        this.utilsService.resetCounter();
        this.utilsService.clearErrorMessages();

        this.subscriptions.push(this.editMessageTemplateService.getMessageTemplateByID(id, [])
            .subscribe(
                data => {
                    this.messageTemplate = data;
                    this.messageTemplate.TemplateType =
                        this.messageTemplateTypes.find(elem => elem.Value === this.messageTemplate.TemplateType.Value);
                    this.showLoader = false;
                    setTimeout(() => this.setInputListener(), 0);
                },
                error => {
                    this.showLoader = false;
                    this.utilsService.handleError(error);
                }
            )
        );
    }

    saveMessageTemplate(saveCopy = false): void {
        this.utilsService.clearErrorMessages();
        const service = `svc/${saveCopy ? SERVICES.SAVE_MESSAGE_AS_COPY : SERVICES.SAVE}`;

        if (this.form.invalid) {
            this.utilsService.showAllErrorMessages();
        } else {
            this.showLoader = true;
            this.subscriptions.push(this.saveService.saveObjects(service, this.createdObjs, this.updatedObjs, this.deletedObjs)
                .subscribe(
                    () => {
                        this.utilsService.handleSuccess();
                        this.router.navigate(['/admin/list-message-templates']);
                    },
                    error => {
                        this.showLoader = false;
                        this.utilsService.handleError(error);
                    }
                )
            );
        }
    }

    getPlaceholderOptions(): void {
        this.subscriptions.push(this.appService.getPlaceholderOptionsEnum()
            .subscribe(options => {
                this.ContentPlaceholderOptionsEnum = options;
                this.contentPlaceholderOptions =
                    this.ContentPlaceholderOptionsEnum.filter(option => option.ShowForContent || option.Value === null)
                        .map((elem, index) => {
                            elem.id = index;
                            elem.text = elem.Description;

                            return elem;
                        });
                this.subjectPlaceholderOptions =
                    this.ContentPlaceholderOptionsEnum.filter(option => option.ShowForSubject || option.Value === null)
                        .map((elem, index) => {
                            elem.id = index;
                            elem.text = elem.Description;

                            return elem;
                        });
            })
        );
    }

    emailTemplateType(): boolean {
        return this.messageTemplate && this.messageTemplate.TemplateType ?
            this.messageTemplate.TemplateType.Value === 'EMAIL' :
            false;
    }

    smsTemplateType(): boolean {
        return this.messageTemplate && this.messageTemplate.TemplateType ?
            this.messageTemplate.TemplateType.Value === 'SMS' :
            false;
    }

    setValueAndFocus(element, elementId, placeholder): void {
        const start = element.selectionStart;
        const end = element.selectionEnd;
        element.value = `${element.value.substring(0, start)}${placeholder}${element.value.substring(end)}`;
        this.focusField(elementId);
        element.selectionEnd = end + placeholder.length;
    }

    focusField(elementId: string): void {
        setTimeout(() => {
            try {
                document.getElementById(`${elementId}Id`)
                    .focus();
                document.getElementById(`${elementId}Id`)
                    .getElementsByTagName('input')[0]
                    .focus();
            } catch (e) {
                // ignore this.
            }
        }, 0);
    }

    createdExists(): boolean {
        return Object.keys(this.createdObjs).length > 0;
    }
}
