/**
 * <p>
 *  directory
 * </p>
 *
 * @author Administrator
 * @since 2021/6/1
 */
// 目录树数据缓存
const dirCache = new Map();
layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'dropdown', 'laydate', 'dict', 'datalabel', 'flow'], function () {
    const listPage = layui.listPage,
        form = layui.form,
        element = layui.element,
        laydate = layui.laydate,
        globalTree = layui.globalTree,
        DataLabel = layui.datalabel;
    const tHeadSetLayer = new THeadSetLayer(layui);

    let metaListTable, dirFileTable, tagSelector, tags = [], conditions = [], preciseQuery = '';
    const unchecked_tags = new Set();
    // 初始化
    initDirectoryTree();


    // 加载并渲染目录树
    function initDirectoryTree() {
        let dirTree = globalTree.init({
            id: 'directoryTree',
            url: `${ctx}/business/directory/tree?busType=${bus_type}`,
            request: {reviewStatus: ReviewStatus.SUBMITTED, allChild: false},
            cache: false,
            // type: 'all',
            initLevel: 1, // 默认展开一级
            scroll: '#tree-toobar-div',
            width: 'fit-content',
            done: treeInitDone,
            onClick: nodeClickEventListener,
            sendSuccess: fetchRequestSendSuccess,
        });

        /**
         * 树组件请求数据接口成功后的回调函数
         * @param res
         */
        function fetchRequestSendSuccess(res) {
            if (res.flag) {
                res.data.forEach(item => {
                    dirCache.set(item.id, item);
                })

                setTimeout(() => {
                    $('.dtree-nav-div.dtree-theme-item').each((index, elem) => {
                        let data = $(elem).data('basic');
                        if (data) {
                            if (typeof data === 'string') {
                                data = JSON.parse(data);
                            }
                            let title = data.metadataComment || data.directoryName || data.fileName + data.fileSuffix;
                            $(elem).attr('title', title)
                        }
                    });
                }, 200)
            }
        }

        /**
         * 树组件初始化完成回调函数
         * @param nodes
         * @param elem
         */
        function treeInitDone(nodes, elem) {
            // 模拟鼠标点击事件展开第一层目录
            elem.find('li:first>div:first>i:first').click();
            elem.find('li:first>div:first').click();
            // 搜索事件监听
            treeSearchEventListener()
        }

        let activeDirectory = {};

        /**
         * 节点点击事件监听
         * @param node
         */
        function nodeClickEventListener(node) {
            let {basicData} = node.param;
            activeDirectory = basicData || {id: DIR_ROOT_ID};
            //设置当前位置
            setCurrentPosition(activeDirectory);
            if ($('#metaQuery').hasClass("layui-this")) {
                // 初始化数据资源表格
                initMetadataTable(activeDirectory.id)
            }
            if ($('#fileQuery').hasClass("layui-this")) {
                //初始化文件搜索表格
                initFileSearchTable(activeDirectory.id);
            }
            if ($('#pictureQuery').hasClass('layui-this')) {
                $('#picSearchKey').val('')
                queryImages(activeDirectory.id, '');
            }
        }

        element.on('tab(metadataListCardBody)', function ({index}) {
            if (index === 1 && !dirFileTable) {
                initFileSearchTable(DIR_ROOT_ID);
            } else if (index === 2) {
                queryImages('ROOT', '')
            }
        });

        $('.pic-search button[lay-event="query"]').on('click', function () {
            queryImages(activeDirectory.id, $('#picSearchKey').val())
        })

        /**
         * 设置当前位置
         * @param basicData
         */
        function setCurrentPosition(basicData) {
            let directoryPath = basicData.directoryPath.replaceAll('/', ' / ');
            $('.current-position label').text(directoryPath);
        }

        /**
         * 树组件搜索事件监听
         */
        function treeSearchEventListener() {
            $('#directoryTreeSearchBox').on('keyup', function () {
                setTimeout(() => {
                    dirTree.fuzzySearch(this.value);
                }, 500)
            })
        }
    }

    /**
     * 加载数据资源列表
     */
    function initMetadataTable(id) {
        const theadConfig = THeadSetLayer.filterConfigData(resourceTableId);
        metaListTable = listPage.init({
            table: {
                id: 'dirMetadataTable',
                toolbar: '#tableToolBar',
                searchFieldNames: 'metadataName',
                url: `${ctx}/search/metadata/all/page/${id}`,
                height: 'full-110',
                method: 'post',
                autoSort: false,
                defaultToolbar: [
                    {title: '导出', layEvent: 'export', icon: 'layui-icon-export'},
                    {title: '列表配置', layEvent: 'theadSet1', icon: 'layui-icon-cols'}
                ],
                request: {pageName: 'page', limitName: 'size'},
                limit: 30,
                minWidth: 80,
                cols: THeadSetLayer.convertColumns(theadConfig, 'dirMetadataTable'),
                done: function (res, _table) {
                    initConditionBlock();
                    if (_table.where) {
                        metaListTable.where = _table.where;
                        if (_table.where.conditions && _table.where.conditions.length > 0) {
                            let formVal = form.val('search-form');
                            formVal = Object.assign(formVal, whereConditionToFormValue(_table.where));
                            if (preciseQuery === 'eq') {
                                formVal['preciseQuery'] = 'eq';
                            }
                            form.val('search-form', formVal);
                            // $('div[lay-event="export"]').show();
                        }
                        renderConditionTabByForm(true);
                    }

                    const suggest = new SearchSuggest(layui, 'searchKeyInput')
                    suggest.onClickItem(function (text) {
                        setSearchKeyCondition(text, preciseQuery === 'eq' ? 'eq' : 'like');
                        this.$searchBtn.click();
                    })
                }
            },
        });
        metaListTable.gtable.on('sort', function (data) {
            const {field, type} = data;
            let sort = type;
            if (!sort || sort === 'null') {
                sort = undefined;
            }
            metaListTable.where.sort = {field: field.trim(), sort: sort}
            beginSearch();
        })
        metaListTable.addTableRowEvent('export', function (obj) {
            if (id === DIR_ROOT_ID) {
                showErrorMsg('不允许导出根目录数据');
                return false;
            }
            layer.confirm('该导出操作比较耗时，导出时请勿刷新页面', {title: '提示信息'}, () => exportDirectory(id, metaListTable.where));
        })
        // 查看按钮监听
        metaListTable.addTableRowEvent('details', function (obj) {
            if (obj.resourceType === 'file') {
                openMaxLayerWithURL(`${ctx}/sys/file/view?fileId=${obj.id}`)
            } else {
                openMaxLayerWithURL(`${ctx}/search/meta/${obj.id}`)
            }
        })

        metaListTable.addTableRowEvent('theadSet1', () => tHeadSetLayer.show(resourceTableId))
    }

    /**
     * 搜索条件模块初始化
     */
    function initConditionBlock() {
        // 监听更多条件按钮点击事件
        $('#condition-btn').click(function () {
            const display = $('#condition-div').css('display');
            if (display == 'none') {
                $('div[lay-id="dirMetadataTable"] .mengban').show().on('click', function () {
                    $('#condition-div').slideUp(100, 'linear')
                    $(this).hide();
                    //$('#condition-btn').click();
                });
            }
            $('#condition-div').slideToggle(100, 'linear', conditionSlideToggle)
        });


        $('#mark-selector-input').on('click', function () {
            DataLabel.openChooseDialog(null, null, null, true).then((labels) => {
                tags = labels || [];
                setMarkTagInputValue();
            })
        })
        // 监听标签点击事件
        element.on('tab(condition-tab)', function (data) {
            // 点击后移除选中样式
            $('#condition-tab ul li').removeClass('layui-this')
        });

        $('#condition-cancel-btn').on('click', function () {
            $('#condition-div').slideUp(100, 'linear')
            $('div[lay-id="dirMetadataTable"] .mengban').hide();
        });

        // 监听条件标签删除事件
        element.on('tabDelete(condition-tab)', function (data) {
            let key = $(this).parent().data('key');
            if (key === 'markTag') {
                tags = [];
            }
            let formVal = form.val('search-form');
            formVal[key] = '';
            form.val('search-form', formVal);
            let where = metaListTable.where;
            if (where.conditions) {
                metaListTable.where.conditions = where.conditions.filter(item => item.fieldName != key);
            }
            renderConditionTabByForm()
        });

        // 监听重置按钮
        $('#condition-clear-btn').on('click', function () {
            $('#searchKeyInput').val('');
            tags = [];
            unchecked_tags.clear();
            conditions = [];
            beginSearch();
        });

        layui.dict.render();

        /**
         * 渲染时间选择组件
         */
        laydate.render({
            elem: '#input-date-begin'
            , type: 'date'
            , range: '至'
        });

        form.on('checkbox(precise-query)', function ({value, othis}) {
            preciseQuery = othis.hasClass('layui-form-checked') ? value : '';
            setSearchKeyCondition($('#searchKeyInput').val(), preciseQuery === 'eq' ? 'eq' : 'like');
        });

        $('#searchKeyInput').on('change', function () {
            let value = $(this).val();
            setSearchKeyCondition(value, preciseQuery === 'eq' ? 'eq' : 'like');
        })
    }

    function setSearchKeyCondition(value, logic) {
        let where = metaListTable.where || {};
        let conditions = where.conditions || [];
        conditions = conditions.filter(item => item.fieldName !== 'metadataName')
        if (value && value.trim()) {
            conditions.push({fieldName: 'metadataName', fieldValue: value.trim(), logicJudgement: logic})
        }
        where.conditions = conditions;
        metaListTable.where = where;
    }

    function setMarkTagInputValue() {
        let temp = [];
        for (let tag of tags) {
            temp.push(tag.title);
        }
        $('#mark-selector-input').val(temp.join(', '));
    }

    /**
     * 条件下拉框显示隐藏的回调
     */
    function conditionSlideToggle() {
        const display = $('#condition-div').css('display');
        // 隐藏时，根据搜索表单的值渲染条件标签，并根据条件检索
        if (display === 'none') {
            renderConditionTabByForm();
        } else {
            setMarkTagInputValue();
        }
    }

    /**
     * 根据条件表单数据渲染条件标签
     */
    function renderConditionTabByForm(isCallback) {
        let formVal = form.val('search-form') || {};
        let htm = '';
        conditions = [];
        for (let key in formVal) {
            if (key === 'searchKeyInput') continue;
            let fieldName = key, fieldValue = formVal[key], logicJudgement;
            // 如果fieldName是条件下拉框，则跳过
            if (fieldName.startsWith('logic-') || fieldName === 'directoryId' || fieldName === 'metadataId' || fieldName === 'preciseQuery') continue;

            let hasText = fieldValue.trim();
            if (hasText) {
                logicJudgement = formVal[`logic-${fieldName}`];
                let title = $(`label.layui-form-label[label-name='${fieldName}']`).text();
                let condition = '';
                switch (logicJudgement) {
                    case 'eq':
                        condition = '等于';
                        break;
                    case 'nq':
                        condition = '不等于';
                        break;
                    case 'gt':
                        condition = '大于';
                        break;
                    case 'lt':
                        condition = '小于';
                        break;
                    case 'like':
                        condition = '包含';
                }

                if (fieldName === 'secretLevel') {
                    hasText = $(`select[name="secretLevel"] option[value="${fieldValue}"]`).text();
                } else if (fieldName === 'dataFrom') {
                    hasText = $(`select[name="dataFrom"] option[value="${fieldValue}"]`).text();
                } else if (fieldName === 'dataType') {
                    hasText = $(`select[name="dataType"] option[value="${fieldValue}"]`).text();
                }
                conditions.push({fieldName, fieldValue, logicJudgement})
                htm += `<li data-key="${fieldName}" style="color:#009688"><label style="color:#333">${title}</label><label style="color:gray;margin-left:5px">${condition}</label>: ${hasText}</li>`
            }
        }

        let tag_htm = '';
        for (let tag of tags) {
            let checked = 'checked';
            if (unchecked_tags.has(tag.id + '')) {
                checked = '';
            }
            tag_htm += `<input type="checkbox" title="${tag.title}" value="${tag.id}" ${checked} lay-skin="primary">`;
        }
        if (tag_htm) {
            htm += `<li data-key="markTag">置标标签：${tag_htm}</li>`;
        }

        $('#condition-tab ul').html(htm);
        element.render('tab');
        $('#condition-tab ul li[data-key="markTag"] i').css({'margin-left': '-10px'});
        form.render('checkbox');

        $('li[data-key="markTag"] .layui-form-checkbox').on('click', function () {
            let val = $(this).prev().val();
            if (unchecked_tags.has(val)) {
                unchecked_tags.delete(val);
            } else {
                unchecked_tags.add(val);
            }
            beginSearch();
        })

        // 开始检索
        if (!isCallback) {
            beginSearch();
        }
    }

    function beginSearch() {
        setMarkTagsValue()
        metaListTable.where.conditions = conditions;
        metaListTable.reloadTable({table: metaListTable})
    }

    function setMarkTagsValue() {
        let values = [];
        $(`li[data-key="markTag"] .layui-form-checked`).each(function (index, elem) {
            values.push($(elem).prev().val())
        });
        if (values.length > 0) {
            conditions.push({fieldName: 'markTag', fieldValue: values.join(','), logicJudgement: 'eq'});
        }
    }

    function whereConditionToFormValue(where) {
        let params = {};
        if (where.conditions) {
            where.conditions.forEach(item => {
                params[item.fieldName] = item.fieldValue;
                if (item.logicJudgement) {
                    params[`logic-${item.fieldName}`] = item.logicJudgement;
                }
            })
        }
        return params;
    }

    function exportDirectory(id, params) {
        Util.exportResource(`/search/export/directory/${id}`, params)
    }

    /**
     * 初始化文件全文检索查询列表
     * @param id 目录ID
     */
    function initFileSearchTable(id) {
        const theadConfig = THeadSetLayer.filterConfigData(fileTableId);
        let queryType = '';
        dirFileTable = listPage.init({
            table: {
                id: 'dirFileTable',
                toolbar: '#fileTableToolBar',
                searchInput: 'fileSearchKeyInput',
                searchFieldNames: 'search',
                url: `${ctx}/search/full/file?metaId=${id}`,
                height: 'full-110',
                where: {searchFields: THeadSetLayer.filterConfigData(fileTableId).filter(conf => conf.isShow).map(conf => conf.colName).join(',')},
                request: {pageName: 'page', limitName: 'size'},
                defaultToolbar: [{title: '列表配置', layEvent: 'theadSet2', icon: 'layui-icon-cols'}],
                autoSort: false,
                limit: 30,
                method: 'get',
                minWidth: 80,
                cols: THeadSetLayer.convertColumns(theadConfig, 'dirFileTable'),
                done: () => {
                    form.val('full-search-form', {queryType});
                    const suggest = new SearchSuggest(layui, 'fileSearchKeyInput');
                    suggest.onClickItem(function (text) {
                        $('#fileSearchKeyInput').val(text);
                        this.$searchBtn.click();
                    })
                }
            },
        });

        form.on('checkbox(query-type)', function ({value, othis}) {
            queryType = othis.hasClass('layui-form-checked') ? value : '';
            dirFileTable.table.where.searchType = queryType;
        });

        dirFileTable.gtable.on('sort', function (data) {
            const {field, type} = data;
            let sort = type;
            if (!sort || sort === 'null') {
                sort = undefined;
            }
            dirFileTable.table.where.field = field.trim();
            dirFileTable.table.where.sort = sort;
            dirFileTable.reloadTable({table: dirFileTable.table})
        })

        // 查看按钮监听
        dirFileTable.addTableRowEvent('details-file', function (obj) {
            openMaxLayerWithURL(`${ctx}/sys/file/view?fileId=${obj.id}`)
        })

        dirFileTable.addTableRowEvent('theadSet2', () => tHeadSetLayer.show(fileTableId))
    }


    /**
     * 流式加载图片
     */
    function queryImages(dirId, searchText) {
        const {protocol, host, port} = window.location;
        let pageNo = 1, pageSize = 20;
        $('#pic-container').html('')
        layui.flow.load({
            elem: '#pic-container',
            isAuto: true,
            mb: 100,
            scrollElem: $('#pic-container').parent(),
            done: function (page, next) { //执行下一页的回调
                pageNo = page;
                Util.get(`/search/image/page/${dirId}`, {pageNo, pageSize, searchText}).then(({flag, data, msg}) => {
                    if (flag) {
                        console.info(data);
                        const {records, pageTotal} = data, picItems = [];
                        const domain = protocol + "//" + host, pubDomain = 'http://24.47.112.32:6688';
                        for (const pic of records) {
                            if (pic.src.startsWith(pubDomain) && host !== '24.47.112.32') {
                                pic.src = pic.src.replace(pubDomain, domain)
                            }
                            const htm = `
                        <li class="pic-item">
                            <img layer-pid="${pic.id}" layer-src="${pic.src}" src="${pic.src}" alt="${pic.title}">
                            <p>${pic.title}</p>
                        </li>`;
                            picItems.push(htm);
                        }
                        next(picItems.join(''), pageNo < pageTotal);
                        layer.photos({
                            photos: '#pic-container',
                            anim: 5
                        });
                    } else {
                        showErrorMsg(msg);
                    }
                }).catch(err => {
                    showErrorMsg(err);
                });
            }
        });
    }
})

class SearchSuggest {
    isHide = true;
    // 系统级热词
    systemHotWords = [];
    // 用户级历史搜索
    userHistoryWords = [];

    constructor(lay, elemId) {
        this.layer = lay.layer;
        this.$bindElem = $(`#${elemId}`);
        this.$searchBtn = this.$bindElem.parent().find('button[lay-event="query"]');
        this.$shadeBox = $('.mengban');
        this.$elem = this.$bindElem.parent().find('.hot-words-box')
        this.bindElem();
        // 获取系统级别的热词推荐
        Util.get(`/search/suggest/system/words`, {}, false).then(res => {
            if (res.flag) {
                this.systemHotWords = res.data;
            }
        })
    }

    bindElem() {
        this.$bindElem.on('focus', () => this.show())
        // 获取系统级别的热词推荐
        Util.get(`/search/suggest/user/history`, {}, false).then(res => {
            if (res.flag) {
                this.userHistoryWords = res.data;
            }
        })
    }

    show() {
        if (this.isHide) {
            const e_width = this.$bindElem.outerWidth(),
                e_height = this.$bindElem.outerHeight(),
                e_border_width = this.$bindElem.css('border-left-width').replace('px', ''),
                width = e_width - parseFloat(e_border_width);
            this.$bindElem.css({'z-index': '999', position: 'relative'})
            this.$searchBtn.css({'z-index': '999', position: 'relative'});
            this.$elem.css({'top': `${e_height + 9}px`, 'width': width + 'px'}).show();
            this.$shadeBox.show().on('click', () => this.hide());
            this.$elem.find('.words-history ul').html('');
            for (let i = 0; i < Math.min(this.userHistoryWords.length, 5); i++) {
                const word = this.userHistoryWords[i];
                this.$elem.find('.words-history ul').append(`<li>${word}</li>`);
            }
            this.$elem.find('.system-words ul').html('');
            for (let i = 0; i < Math.min(this.systemHotWords.length, 5); i++) {
                const word = this.systemHotWords[i];
                this.$elem.find('.system-words ul').append(`<li>${word}</li>`);
            }
            this.$elem.find('ul li').on('click', (event) => {
                const $li = $(event.target);
                this.$bindElem.val($li.text());
                this.onclickItemCallback && this.onclickItemCallback($li.text());
            });
            this.isHide = false;
        }
    }

    hide() {
        this.$elem.hide();
        this.$shadeBox.hide();
        this.$bindElem.css({'display': 'unset', 'z-index': 700});
        this.isHide = true;
        this.bindElem();
    }

    onClickItem(callback) {
        this.onclickItemCallback = callback;
    }
}

/**
 * 表格表头配置组件
 */
class THeadSetLayer {
    constructor(lay) {
        this.id = 'theadConfig';
        this.layer = lay.layer;
        this.form = lay.form;
        this.gtable = lay.gtable;
    }

    show(tableId) {
        const {layer, id} = this;
        layer.open({
            id: id + 'Layer',
            title: '数据列表配置',
            type: 1,
            area: ['1000px', '700px'],
            shadeClose: true,
            maxmin: false,
            anim: 0,
            content: `<table id="${id}" lay-filter="${id}"></table>`,
            btn: ['保存', '取消'],
            success: () => {
                this._renderInnerTable(tableId);
            },
            yes: (layerIndex) => {
                this._saveTheadSet().then(() => {
                    window.location.reload();
                    layer.close(layerIndex);
                })
            }
        });
    }

    _renderInnerTable(tableId) {
        const {gtable, form, id} = this;
        gtable.init({
            id,
            data: THeadSetLayer.filterConfigData(tableId),
            method: 'get',
            toolbar: false,
            height: 'full',
            page: false,
            limit: 1000,
            cols: [[
                {field: 'id', hide: true},
                {field: 'colName', title: '列名'},
                {field: 'colTitle', title: '列标题', edit: 'text'},
                {field: 'colSort', title: '列顺序', edit: 'text'},
                {field: 'colWidth', title: '列宽度', edit: 'text'},
                {
                    field: 'isSort',
                    title: '是否允许排序',
                    templet: (data) => renderSwitch('isSort', data)
                },
                {
                    field: 'isShow',
                    title: '是否显示',
                    templet: (data) => renderSwitch('isShow', data)
                }
            ]],
        });
        gtable.on(`edit(${id})`, ({field, value, data}) => {
            theadConfigMap.get(data.id)[field] = value;
        })
        // 监听switch按钮
        form.on(`switch(${id}-switch)`, ({elem}) => {
            const id = $(elem).attr('id'), name = $(elem).attr('name');
            const value = theadConfigMap.get(id)[name];
            theadConfigMap.get(id)[name] = !value;
        });

        function renderSwitch(colName, data) {
            const dataId = data.id, value = data[colName];
            return `<input type="checkbox" id="${dataId}" name="${colName}" value="${value}" title="是|否" lay-skin="switch" lay-filter="${id}-switch" ${value ? 'checked' : ''} />`
        }
    }


    _saveTheadSet() {
        return new Promise(resolve => {
            Util.post(`/sys/thead/config/api/save`, {params: JSON.stringify([...theadConfigMap.values()])}).then(res => {
                if (res.flag) {
                    showOkMsg('保存成功')
                } else {
                    showErrorMsg2('保存失败：' + res.msg)
                }
            })
            resolve();
        })
    }

    static filterConfigData(tableId) {
        return theadConfig.filter(item => item.tableId === tableId);
    }

    static convertColumns(tHeadConfig = [], tableId) {
        // 提前定义好需要使用templet属性的字段
        const templets = {
            source: data => DICT.getText('data_source', data.source) || data.source || '',
            dataSource: data => DICT.getText('data_source', data.source) || data.source || '',
            dataType: data => DICT.getText('data_type', data.dataType) || data.dataType || '',
            taskCode: data => DICT.getText('task_code', data.taskCode) || data.taskCode || '',
            taskNature: data => DICT.getText('task_nature', data.taskNature) || data.taskNature || '',
            troopCode: data => DICT.getText('troop_code', data.troopCode) || data.troopCode || '',
            missileNumber: data => DICT.getText('missile_number', data.missileNumber) || data.missileNumber || '',
            equipmentModel: data => DICT.getText('equipment_model', data.equipmentModel) || data.equipmentModel || '',
            targetNumber: data => DICT.getText('target_type', data.targetNumber) || data.targetNumber || '',
            secretLevel: data => DICT.getText('secret_level', data.secretLevel) || data.secretLevel || '',
            exerciseData: data => data.exerciseData ? '是' : '否',
            resourceType: data => data.resourceType === 'file' ? '文件' : '数据库表',
            fileSize: data => {
                return Util.fileSizeFormat(data.fileSize, 'M');
            }
        }

        // 遍历配置项转换为列
        const cols = tHeadConfig.map(conf => {
            const {colName, colTitle, colWidth, isShow, isSort} = conf;
            const width = !colWidth ? undefined : (Number.isInteger(colWidth) ? parseInt(colWidth) : colWidth);
            let col = {field: colName, title: colTitle, width, sort: isSort, hide: !isShow}
            if (templets[colName]) {
                col['templet'] = templets[colName];
            }
            return col;
        });

        // 设置操作列
        let operateCol = {fixed: 'right', title: '操作', toolbar: '', width: 100, align: 'center'};
        if (tableId === 'dirMetadataTable') {
            operateCol.toolbar = '#rowToolBar'
        } else if (tableId === 'dirFileTable') {
            operateCol.toolbar = '#fileRowToolBar'
        }
        cols.push(operateCol);
        return [cols];
    }
}