import { getLabelText } from '/components/common/utils.js?v=3.4'
import { VueMultiSelect } from "/Components/Common/VueMultiSelect.js?v=3.4"
import VueSelect from "/Components/Common/VueSelect.js?v=3.4"
import ModalPopUp from '/Components/Common/ModalPopUp.js?v=3.4'

export const VueMultiSelectableSelected = {
    components: {
        VueSelect,
        VueMultiSelect,
        ModalPopUp
    },
    props: {
        items: { type: Array, required: true },
        id: { type: String, required: true },
        useTranslation: { type: Boolean, required: false, default: false }
    },
    data() {
        return {
            selectableId: this.id + "_Selectable",
            selectedId: this.id + "_Selected",
            searchInputId: this.id + "_SearchInput",
            selectAllBtnId: this.id + "_BtnSelectAll",
            selectMultipleBtnId: this.id + "_BtnSelectMultiple",
            deselectAllBtnId: this.id + "_BtnDeselectAll",
            deselectMultipleBtnId: this.id + "_BtnDeselectMultiple",
            selectFromFileModalId: this.id + "_SelectFromFileModal",
            fileDataControlId: this.id + "_SelectFromFileUpload",
            selectFileFormatControlId: this.id + "_SelectFileDataFormatOptions",
            fileDataMatchConditionControlId: this.id + "_SelectFileDataMatchConditions",
            typeAndPressEnterToSearchText: getLabelText('TypeAndPressEnterToSearch'),
            selectableSource: this.items ? this.items.filter(i => !i.selected).map(i => i) : [],
            selectedSource: this.items ? this.items.filter(i => i.selected).map(i => { return { text: i.text, value: i.value, selected: false } }) : [],
            fromSelectedItems: [],
            toSelectedItems: [],
            searchPhrase: null,
            showSelectFromFileModal: false,
            parentContext: {},
            fileDataFormatOptions: [
                { index: 0, value: "line", text: getLabelText("LineSeparatedVals"), selected: true },
                { index: 1, value: "comma", text: getLabelText("CommaSepratedVals"), selected: false },
                { index: 2, value: "semicolon", text: getLabelText("SemicolonSepratedVals"), selected: false }
            ],
            selectedFileDataFormat: getCookie('multiSelectFileFormat'),
            fileDataMatchConditions: [
                { index: 0, text: getLabelText('SMI693'), value: 'equals', checked: false },
                { index: 1, text: getLabelText('GN0000544'), value: 'contains', checked: false },
                { index: 2, text: getLabelText('SMI695'), value: 'startswith', checked: false },
                { index: 3, text: getLabelText('SMI694'), value: 'notequals', checked: false },
                { index: 4, text: getLabelText('SMI697'), value: 'notcontains', checked: false },
                { index: 5, text: getLabelText('SMI696'), value: 'endswith', checked: false }
            ],
            selectedDataMatchCondition: getCookie('FileSelectableMatchingFunction') ? getCookie('FileSelectableMatchingFunction') : 'equals'
        }
    },
    emits: ['selectionInfo'],
    computed: {
        
    },
    created: function () {
        this.returnSelectionInfoToParent();
    },
    updated: function () {
        this.returnSelectionInfoToParent();
    },
    methods: {
        getLabelText,
        selectableChangeHandler: function (selectedItems) {
            this.fromSelectedItems = selectedItems;
            this.searchPhrase = '';//clear search phrase once selection is updated.
        },
        selectedChangeHandler: function (selectedItems) {
            this.toSelectedItems = selectedItems;
            this.searchPhrase = '';//clear search phrase once selection is updated.
        },
        returnSelectionInfoToParent: function () {
            this.$emit('selectionInfo', this.selectableSource.map(i => { return { text: this.useTranslation ? this.getLabelText(i.text) : i.text, value: i.value } }), this.selectedSource.map(i => { return { text: this.useTranslation ? this.getLabelText(i.text) : i.text, value: i.value } }), this.id);
        },
        moveSelectedItems: function (fromList, toList, itemsToMove) {
            let moveItemIndices = [];

            //Push selected items from 'fromList' to 'toList'
            if (fromList)
                fromList.forEach((fi, x) => {
                    if (itemsToMove && itemsToMove.find(i => i.value === fi.value)) //if items selected and exists in from list
                    {
                        moveItemIndices.push(x);
                        if (!toList.find(i => i.value === fi.value)) //and also item doesn't exist in toList
                        {
                            fi.selected = false;
                            toList.push(fi);
                        }
                    }
                });

            //Remove selected items from 'fromList'
            moveItemIndices.sort().reverse().forEach((index) => {
                fromList.splice(index, 1);
            });

            this.fromSelectedItems = [];
            this.toSelectedItems = [];

            this.returnSelectionInfoToParent();
        },
        selectAll: function () {
            this.searchPhrase = null;
            this.selectableSource = [];
            this.fromSelectedItems = [];
            this.toSelectedItems = [];
            this.selectedSource = this.items.map(i => { return { text: this.useTranslation ? this.getLabelText(i.text) : i.text, value: i.value, selected: false } });
        },
        deselectAll: function () {
            this.searchPhrase = null;
            this.selectedSource = [];
            this.fromSelectedItems = [];
            this.toSelectedItems = [];
            this.selectableSource = this.items.map(i => { return { text: this.useTranslation ? this.getLabelText(i.text) : i.text, value: i.value, selected: false } });
        },
        selectMultiple: function () {
            this.searchPhrase = null;
            this.moveSelectedItems(this.selectableSource, this.selectedSource, this.fromSelectedItems);
        },
        deselectMultiple: function () {
            this.searchPhrase = null;
            this.moveSelectedItems(this.selectedSource, this.selectableSource, this.toSelectedItems);
        },
        searchInSelectableSelected: function (e) {

            var temp = e.target.value;
            this.searchPhrase = e.target.value;
            document.getElementById(this.searchInputId).value = this.typeAndPressEnterToSearchText;
            document.getElementById(this.selectMultipleBtnId).focus();

            setTimeout(
                () => {
                    if ((!this.fromSelectedItems || this.fromSelectedItems.length < 1) && (!this.toSelectedItems || this.toSelectedItems < 1)) {
                        document.getElementById(this.searchInputId).focus();
                        document.getElementById(this.searchInputId).value = temp;
                    }
                }, 50);
        },
        showModalHandler: function (e) {
            this.showSelectFromFileModal = true;
        },
        hideModalHandler: function () {
            resetFileCtrl(this.fileDataControlId);//reference multi-selectable.js file
            this.showSelectFromFileModal = false;
            $('#' + this.selectFromFileModalId).modal('hide');
        },
        handleMatchConditionChange: function (e) {
            setCookie('FileSelectableMatchingFunction',this.selectedDataMatchCondition);//v-modal two way binding with element
        },
        handleFileDateFormatChange: function (e) {
            this.selectedFileDataFormat = e.target.value; //one way binding with prop, hence assignment to prop needed for component virutal JS update.
            setCookie('multiSelectFileFormat', this.selectedFileDataFormat);
            
            //multiSelectFileFormatChange(e);//reference multi-selectable.js file
            resetFileCtrl(this.fileDataControlId);//reference multi-selectable.js file
        },
        searchAndSelectFromFile: function (e) {
            let component = this;
            let src = document.getElementById(this.fileDataControlId);
            if (src && src.files && src.files.length > 0) {
                let file = src.files[0];
                
                let dataFormat = this.selectedFileDataFormat;

                let reader = new FileReader();
                reader.onload = function (progressEvent) {

                    let lines = new Array();
                    dataFormat = dataFormat ? dataFormat : 'line';
                    switch (dataFormat) {
                        case 'line':
                            lines = this.result.split('\r\n');
                            break;
                        case 'comma':
                            lines = this.result.split(',');
                            break;
                        case 'semicolon':
                            lines = this.result.split(';');
                            break;
                        default:
                            for (let l of this.result.split('\r\n'))
                                for (let m of l.split(','))
                                    for (let n of m.split(';'))
                                        lines.push(n);
                    }

                    let matchCondition = component.selectedDataMatchCondition; //getCookie('FileSelectableMatchingFunction');

                    matchCondition = matchCondition ? matchCondition : 'contains';

                    //clear all selection from selectable source
                    component.selectableSource.forEach(i => i.selected = false);

                    for (const option of component.selectableSource) {

                        let optText = option.text.toLowerCase();//.trim();

                        for (let line of lines) {
                            line = line.toLowerCase();//.trim();
                            if (!line || line == '')
                                continue;
                            let re = new RegExp(RegExp.escape(line), 'gi');

                            switch (matchCondition) {
                                case 'equals':
                                case 'notequals':
                                    if (optText == line) 
                                        option.selected = true;
                                    break;
                                case 'contains':
                                case 'notcontains':
                                    if (optText.match(re) || optText.includes(line)) 
                                        option.selected = true;
                                    break;
                                case 'startswith':
                                    if (optText.startsWith(line))
                                        option.selected = true;
                                    break;
                                case 'endswith':
                                    if (optText.endsWith(line))
                                        option.selected = true;
                                    break;
                            }
                        }

                        //invert selection when not-- case.
                        if (matchCondition == 'notcontains' || matchCondition == 'notequals')
                            option.selected = !option.selected;
                        
                    }

                    component.fromSelectedItems = component.selectableSource.filter(i => i.selected).map(i => i);

                    component.selectMultiple();

                    component.hideModalHandler();
                };

                reader.readAsText(file);
            }
        }
    },
    template: `
    <ModalPopUp v-if="showSelectFromFileModal" :parentContext="parentContext" :modalTitle="getLabelText('StrSelectFromFile')" @onNo="hideModalHandler" :id="selectFromFileModalId">
        <div class="panel">
            <div class="panel-body" style="max-height: 470.4px; overflow: hidden auto;">
                <div class="row">
                    <div class="col-sm-4 col-xs-12 row-label">
                        <label>
                            {{getLabelText('SelectDataFormat')}}:</label>
                    </div>
                    <div class="col-sm-8 col-xs-12">
                        <div class="form-group">
                            <VueSelect :options="fileDataFormatOptions" :selectedValue="selectedFileDataFormat" @change="handleFileDateFormatChange" :name="selectFileFormatControlId" :id="selectFileFormatControlId" />
                        </div>
                    </div>
                </div>

                <div class="row">
                    <div class="col-sm-4 col-xs-12 row-label">
                        <label>
                            {{getLabelText('StrSelectMatchingCondition')}}:</label>
                    </div>
                    <div class="col-sm-8 col-xs-12">
                        <div class="form-group">
                            <div v-for="c in fileDataMatchConditions" :key="c">
                                <span class="col-xs-4">
                                    <input :id="this.fileDataMatchConditionControlId + c.index" type="radio" :name="this.fileDataMatchConditionControlId" :value="c.value"
                                        v-model="selectedDataMatchCondition" @change="handleMatchConditionChange">
                                    <label :for="this.fileDataMatchConditionControlId + c.index">{{c.text}}</label>
                                </span>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-sm-4 col-xs-12 row-label">
                        <label></label>
                    </div>
                    <div class="col-sm-8 col-xs-12">
                        <div class="form-group">
                            <span class="btn btn-primary btn-file">
                                <span class="fileupload-new">{{getLabelText('strSelectFile')}}</span>
                                <input type="file" :name="this.fileDataControlId" :id="this.fileDataControlId" @change="searchAndSelectFromFile">
                            </span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </ModalPopUp>

    <div :id="id">
        <div class="row">
            <div class="col-xs-6">
                <div class="form-group">
                    <div class="form-line">
                        <input name="{{ searchInputId }}" type="text" :value="typeAndPressEnterToSearchText" :id="searchInputId" class="TypeToSearch form-control" onfocus="ClearDefault(this)" @keyup.enter="searchInSelectableSelected" style="width:100%;">
                    </div>
                </div>
            </div>

            <div class="col-xs-6">
                <div class="form-group">
                    <a href="javascript:void(0)" @click.left="showModalHandler">
                        {{getLabelText('StrSelectFromFile')}}
                    </a>
                </div>
            </div>

        </div>
        <div class="row">
            <div class="col-sm-5 col-xs-12">
                <span class="row-label">
                    Selectable
                </span>
                <VueMultiSelect :items="selectableSource" @selectionChange="selectableChangeHandler" :id="selectableId" :useTranslation="useTranslation" :searchPhrase="searchPhrase" />
            </div>
            <div class="col-sm-2 col-xs-12 align-center SelectArrows">

                <button :id="selectAllBtnId" class="btn btn-primary waves-effect" @click.left.prevent="selectAll">
                    <i class="material-icons btn-icons-position">last_page</i>
                </button>

                <button :id="deselectAllBtnId" class="btn btn-primary waves-effect" @click.left.prevent="deselectAll">
                    <i class="material-icons btn-icons-position">first_page</i>
                </button>

                <div class="clearfix hidden-xs"></div>

                <button :id="selectMultipleBtnId" class="btn btn-primary waves-effect" @click.left.prevent="selectMultiple">
                    <i class="material-icons btn-icons-position">chevron_right</i>
                </button>

                <button :id="deselectMultipleBtnId" class="btn btn-primary waves-effect" @click.left.prevent="deselectMultiple">
                    <i class="material-icons btn-icons-position">chevron_left</i>
                </button>

            </div>
            <div class="col-sm-5 col-xs-12">
                <div class="form-group">
                    <span class="row-label">
                        Selected
                        *
                    </span>
                    <VueMultiSelect :items="selectedSource" @selectionChange="selectedChangeHandler" :id="selectedId" :useTranslation="useTranslation" :searchPhrase="searchPhrase"/>
                </div>
            </div>
        </div>
    </div>
    `
}
