define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {

    var Controller = {
        index: function () {
            Table.api.init({
                extend: {
                    index_url: 'split.number/index' + location.search,
                    add_url: 'split.number/add',
                    edit_url: 'split.number/edit',
                    del_url: 'split.number/del',
                    multi_url: 'split.number/multi',
                    table: 'split_number',
                }
            });

            var table = $("#table");
            var searchSelect = Controller.api.searchSelectColumn;
            var searchSelectMeta = Controller.api.searchSelectMeta;

            table.bootstrapTable({
                url: $.fn.bootstrapTable.defaults.extend.index_url,
                pk: 'id',
                sortName: 'id',
                sortOrder: 'desc',
                fixedColumns: true,
                fixedRightNumber: 1,
                searchFormVisible: true,
                pageSize: 10,
                pageList: Controller.api.streamLoad.PAGE_LIST,
                queryParams: function (params) {
                    return Controller.api.streamLoad.wrapQueryParams(table, params);
                },
                columns: [
                    [
                        {checkbox: true},
                        searchSelect('split_link_id', __('Link_url'), Config.splitLinkFilterList || {}, true),
                        {field: 'id', title: __('Id'), sortable: true},
                        {
                            field: 'link_url_text',
                            title: __('Link_url'),
                            operate: false,
                            formatter: Table.api.formatter.content
                        },
                        {field: 'ticket_name', title: __('Ticket_name'), operate: 'LIKE'},
                        {
                            field: 'number',
                            title: __('Number'),
                            operate: 'LIKE',
                            formatter: Controller.api.formatter.numberWithDeferred
                        },
                        $.extend(
                            {field: 'number_type', title: __('Number_type'), searchList: Config.numberTypeList, formatter: Table.api.formatter.normal},
                            searchSelectMeta(false)
                        ),
                        {field: 'visit_count', title: __('Visit_count'), operate: false, sortable: true},
                        {field: 'inbound_count', title: __('Inbound_count'), operate: false, sortable: true},
                        $.extend(
                            {field: 'platform_status', title: __('Platform_status'), searchList: Config.platformStatusList, formatter: Controller.api.formatter.platformStatus},
                            searchSelectMeta(false)
                        ),
                        $.extend(
                            {field: 'status', title: __('Status'), searchList: Config.statusList, formatter: Table.api.formatter.toggle, yes: 'normal', no: 'hidden'},
                            searchSelectMeta(false)
                        ),
                        $.extend(
                            {
                                field: 'ratio_deferred',
                                title: __('Ratio_deferred'),
                                visible: false,
                                searchable: true,
                                operate: '=',
                                searchList: Config.ratioDeferredList || {}
                            },
                            searchSelectMeta(false)
                        ),
                        {
                            field: 'createtime',
                            title: __('Createtime'),
                            operate: 'RANGE',
                            addclass: 'datetimerange',
                            autocomplete: false,
                            formatter: Table.api.formatter.datetime,
                            sortable: true
                        },
                        {
                            field: 'operate',
                            title: __('Operate'),
                            table: table,
                            events: Table.api.events.operate,
                            formatter: Table.api.formatter.operate
                        }
                    ]
                ]
            });

            table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function () {
                var ids = Table.api.selectedids(table);
                $('.btn-batch-update-status').toggleClass('btn-disabled disabled', ids.length === 0);
            });

            $('.btn-batch-update-status').on('click', function (e) {
                e.preventDefault();
                e.stopPropagation();
                if ($(this).hasClass('disabled')) {
                    return false;
                }
                var ids = Table.api.selectedids(table);
                if (!ids.length) {
                    Toastr.warning(__('Please select at least one item'));
                    return false;
                }
                Controller.api.openBatchUpdateModal(ids, table);
            });

            $('.btn-batch-operate').on('click', function (e) {
                e.preventDefault();
                e.stopPropagation();
                Controller.api.openBatchOperateModal(table);
            });

            table.on('post-body.bs.table', function () {
                table.find('[data-toggle="tooltip"]').tooltip({container: 'body'});
            });

            table.on('post-common-search.bs.table', function (e, tbl) {
                Controller.api.initCommonSearchSelectpicker(tbl);
            });

            Table.api.bindevent(table);
            Controller.api.streamLoad.bind(table);
            Controller.api.bindDeferredFilter(table);
            Controller.api.bindDeferredCleanup(table);
        },
        add: function () {
            Controller.api.bindevent();
        },
        edit: function () {
            Controller.api.bindevent();
        },
        api: {
            searchSelectColumn: function (field, title, searchList, liveSearch) {
                return {
                    field: field,
                    title: title,
                    visible: false,
                    searchList: searchList || {},
                    operate: '=',
                    addclass: 'selectpicker',
                    extend: Controller.api.searchSelectExtend(liveSearch !== false)
                };
            },
            searchSelectMeta: function (liveSearch) {
                return {
                    addclass: 'selectpicker',
                    extend: Controller.api.searchSelectExtend(liveSearch !== false)
                };
            },
            searchSelectExtend: function (liveSearch) {
                var text = __('Please select');
                if (!text || text === 'Please select' || text === 'Please Select') {
                    text = '请选择';
                }
                var ext = 'data-none-selected-text="' + text + '" title="' + text + '"';
                if (liveSearch) {
                    ext += ' data-live-search="true"';
                }
                return ext;
            },
            initCommonSearchSelectpicker: function (tbl) {
                var $form = $('form.form-commonsearch', tbl.$container);
                if ($form.length) {
                    Form.events.selectpicker($form);
                }
            },

            /**
             * 分页选「全部」时改为分块滚动加载，避免一次渲染过多 DOM 导致卡顿
             */
            streamLoad: {
                CHUNK: 50,
                SCROLL_THRESHOLD: 80,
                LOAD_DELAY: 1500,
                PAGE_LIST: [10, 30, 50, 100, 200, 300, 500, 'All'],

                createState: function () {
                    return {
                        enabled: false,
                        loading: false,
                        pendingLoad: false,
                        loadTimer: null,
                        loaded: 0,
                        total: 0,
                        chunk: 50,
                        pendingReset: false,
                        pendingAllSelect: false,
                        appendQuery: false
                    };
                },

                getState: function (table) {
                    var state = table.data('splitStreamLoad');
                    if (!state) {
                        state = Controller.api.streamLoad.createState();
                        table.data('splitStreamLoad', state);
                    }
                    return state;
                },

                getAllLabel: function () {
                    var localeKey = (typeof Config !== 'undefined' && Config.language === 'zh-cn') ? 'zh-CN' : 'en-US';
                    var locale = $.fn.bootstrapTable.locales && $.fn.bootstrapTable.locales[localeKey];
                    if (locale && typeof locale.formatAllRows === 'function') {
                        return locale.formatAllRows();
                    }
                    if ($.fn.bootstrapTable.defaults && typeof $.fn.bootstrapTable.defaults.formatAllRows === 'function') {
                        return $.fn.bootstrapTable.defaults.formatAllRows();
                    }
                    return 'All';
                },

                /**
                 * initServer 首次请求时实例尚未写入 data('bootstrap.table')，getOptions 会退回 jQuery 对象
                 */
                safeGetOptions: function (table) {
                    if (!table || !table.length) {
                        return null;
                    }
                    var opts = table.bootstrapTable('getOptions');
                    if (opts && typeof opts.formatAllRows === 'function') {
                        return opts;
                    }
                    var instance = table.data('bootstrap.table');
                    if (instance && instance.options && typeof instance.options.formatAllRows === 'function') {
                        return instance.options;
                    }
                    return null;
                },

                getDefaultPageList: function () {
                    return Controller.api.streamLoad.PAGE_LIST;
                },

                getMaxNormalPageSize: function (pageList) {
                    var api = Controller.api.streamLoad;
                    var maxNormal = 0;
                    $.each(pageList || api.getDefaultPageList(), function (i, value) {
                        if (api.isAllPageSize(value)) {
                            return;
                        }
                        var num = parseInt(value, 10);
                        if (!isNaN(num) && num > maxNormal) {
                            maxNormal = num;
                        }
                    });
                    return maxNormal;
                },

                isAllPageSize: function (pageSize) {
                    if (pageSize === undefined || pageSize === null || pageSize === '') {
                        return false;
                    }
                    return String(pageSize).toUpperCase() === String(Controller.api.streamLoad.getAllLabel()).toUpperCase();
                },

                isLargeStoredPageSize: function (table, params) {
                    var api = Controller.api.streamLoad;
                    var options = api.safeGetOptions(table);
                    var pageSize = options ? options.pageSize : null;
                    var limit = params ? (parseInt(params.limit, 10) || 0) : 0;

                    if (pageSize !== null && api.isAllPageSize(pageSize)) {
                        return true;
                    }
                    var maxNormal = api.getMaxNormalPageSize(options ? options.pageList : null);
                    if (typeof pageSize === 'number' && pageSize > maxNormal) {
                        return true;
                    }
                    if (!options && limit > maxNormal) {
                        return true;
                    }
                    return false;
                },

                shouldEnable: function (table, params) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);
                    if (state.pendingAllSelect || state.enabled) {
                        return true;
                    }
                    var options = api.safeGetOptions(table);
                    var limit = parseInt(params.limit, 10) || 0;

                    if (options) {
                        var totalRows = parseInt(options.totalRows, 10) || 0;
                        if (api.isAllPageSize(options.pageSize)) {
                            return true;
                        }
                        if (api.isLargeStoredPageSize(table, params)) {
                            return true;
                        }
                        return totalRows > 0 && limit >= totalRows;
                    }

                    // 表格构造阶段：All 模式 totalRows 尚未就绪时 limit 可能为 0
                    if (limit === 0) {
                        var stored = localStorage.getItem('pagesize');
                        if (stored && api.isAllPageSize(stored)) {
                            return true;
                        }
                    }
                    return api.isLargeStoredPageSize(table, params);
                },

                enable: function (table) {
                    var state = Controller.api.streamLoad.getState(table);
                    state.enabled = true;
                    state.loaded = 0;
                    state.loading = false;
                    state.pendingReset = true;
                },

                disable: function (table) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);
                    api.cancelPendingLoad(table);
                    state.enabled = false;
                    state.loaded = 0;
                    state.total = 0;
                    state.loading = false;
                    state.pendingReset = false;
                    state.pendingAllSelect = false;
                    api.updateHint(table);
                    api.togglePaginationNav(table, false);
                    api.showBottomLoading(table, false);
                },

                wrapQueryParams: function (table, params) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);

                    if (api.shouldEnable(table, params)) {
                        state.enabled = true;
                        state.pendingAllSelect = false;
                    }

                    if (!state.enabled) {
                        return params;
                    }

                    params.limit = state.chunk;
                    if (state.appendQuery) {
                        params.offset = parseInt(params.offset, 10) || 0;
                    } else {
                        params.offset = 0;
                        state.pendingReset = true;
                    }
                    state.appendQuery = false;
                    return params;
                },

                bind: function (table) {
                    var api = Controller.api.streamLoad;
                    var $wrapper = table.closest('.bootstrap-table');

                    $wrapper.on('click.splitStream', '.page-list .dropdown-menu li a', function () {
                        api.cancelPendingLoad(table);
                        var label = $.trim($(this).text());
                        if (api.isAllPageSize(label)) {
                            api.getState(table).pendingAllSelect = true;
                            api.enable(table);
                        }
                    });

                    table.on('page-change.bs.table', function (e, pageNumber, pageSize) {
                        var options = api.safeGetOptions(table);
                        if (!options) {
                            return;
                        }
                        if (api.isAllPageSize(pageSize)
                            || (typeof pageSize === 'number' && pageSize === options.totalRows && options.totalRows > 0)) {
                            api.enable(table);
                            return;
                        }
                        if (typeof pageSize === 'number' && pageSize < options.totalRows) {
                            api.disable(table);
                        }
                    });

                    table.on('refresh.bs.table search.bs.table common-search.bs.table', function () {
                        var state = api.getState(table);
                        api.cancelPendingLoad(table);
                        if (!state.enabled) {
                            return;
                        }
                        state.loaded = 0;
                        state.pendingReset = true;
                    });

                    table.on('sort.bs.table', function () {
                        var state = api.getState(table);
                        api.cancelPendingLoad(table);
                        if (!state.enabled) {
                            return;
                        }
                        state.loaded = 0;
                        state.pendingReset = true;
                    });

                    table.on('load-success.bs.table', function (e, data) {
                        var state = api.getState(table);
                        if (!state.enabled || !data || typeof data.total === 'undefined') {
                            return;
                        }

                        state.total = parseInt(data.total, 10) || 0;
                        if (state.pendingReset) {
                            state.loaded = $.isArray(data.rows) ? data.rows.length : 0;
                            state.pendingReset = false;
                        }

                        api.updateHint(table);
                        api.togglePaginationNav(table, true);
                        api.bindScrollContainer(table);
                        api.autoFillViewport(table);

                        var tableOptions = api.safeGetOptions(table);
                        if (tableOptions && tableOptions.fixedColumns) {
                            table.bootstrapTable('resetView');
                        }
                    });

                    table.on('post-body.bs.table', function () {
                        if (!api.getState(table).enabled) {
                            return;
                        }
                        api.updateHint(table);
                    });
                },

                bindScrollContainer: function (table) {
                    var api = Controller.api.streamLoad;
                    var $body = table.closest('.bootstrap-table').find('.fixed-table-body');
                    if (!$body.length || $body.data('splitStreamBound')) {
                        return;
                    }
                    $body.data('splitStreamBound', true);
                    $body.on('scroll.splitStream', function () {
                        api.onScroll(table, this);
                    });
                },

                onScroll: function (table, el) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);
                    if (!state.enabled || state.loading || state.loaded >= state.total) {
                        return;
                    }
                    var atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - api.SCROLL_THRESHOLD;
                    if (!atBottom) {
                        api.cancelPendingLoad(table);
                        return;
                    }
                    if (state.pendingLoad) {
                        return;
                    }
                    api.scheduleLoadMore(table);
                },

                isNearBottom: function (table) {
                    var api = Controller.api.streamLoad;
                    var $body = table.closest('.bootstrap-table').find('.fixed-table-body');
                    if (!$body.length) {
                        return false;
                    }
                    var el = $body[0];
                    return el.scrollTop + el.clientHeight >= el.scrollHeight - api.SCROLL_THRESHOLD;
                },

                scheduleLoadMore: function (table) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);
                    if (state.loading || state.pendingLoad || !state.enabled || state.loaded >= state.total) {
                        return;
                    }
                    state.pendingLoad = true;
                    api.showBottomLoading(table, true);
                    api.updateHint(table, false, true);

                    state.loadTimer = setTimeout(function () {
                        state.pendingLoad = false;
                        state.loadTimer = null;
                        if (!state.enabled) {
                            api.showBottomLoading(table, false);
                            api.updateHint(table);
                            return;
                        }
                        if (!api.isNearBottom(table)) {
                            api.showBottomLoading(table, false);
                            api.updateHint(table);
                            return;
                        }
                        api.loadMore(table);
                    }, api.LOAD_DELAY);
                },

                cancelPendingLoad: function (table) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);
                    if (state.loadTimer) {
                        clearTimeout(state.loadTimer);
                        state.loadTimer = null;
                    }
                    state.pendingLoad = false;
                    if (!state.loading) {
                        api.showBottomLoading(table, false);
                        api.updateHint(table);
                    }
                },

                showBottomLoading: function (table, show) {
                    var $body = table.closest('.bootstrap-table').find('.fixed-table-body');
                    if (!$body.length) {
                        return;
                    }
                    var $bar = $body.children('.split-stream-loading-bar');
                    if (show) {
                        if (!$bar.length) {
                            var loadingText = __('Stream loading bottom');
                            if (!loadingText || loadingText === 'Stream loading bottom') {
                                loadingText = '加载中...';
                            }
                            $bar = $('<div class="split-stream-loading-bar text-center" style="padding:14px 0;color:#999;border-top:1px solid #f0f0f0;background:#fafafa;">'
                                + '<i class="fa fa-spinner fa-spin"></i> ' + Fast.api.escape(loadingText)
                                + '</div>');
                            $body.append($bar);
                        }
                        $bar.show();
                    } else if ($bar.length) {
                        $bar.hide();
                    }
                },

                buildRequestParams: function (table, offset, limit) {
                    var options = Controller.api.streamLoad.safeGetOptions(table);
                    if (!options) {
                        return {offset: offset, limit: limit};
                    }
                    var state = Controller.api.streamLoad.getState(table);
                    state.appendQuery = true;
                    return options.queryParams({
                        search: options.searchText,
                        sort: options.sortName,
                        order: options.sortOrder,
                        offset: offset,
                        limit: limit
                    });
                },

                loadMore: function (table) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);
                    if (state.loading || !state.enabled || state.loaded >= state.total) {
                        return;
                    }

                    state.loading = true;
                    api.updateHint(table, true);

                    var options = api.safeGetOptions(table);
                    if (!options) {
                        state.loading = false;
                        return;
                    }
                    $.ajax({
                        url: options.url,
                        type: options.method,
                        data: api.buildRequestParams(table, state.loaded, state.chunk),
                        dataType: 'json'
                    }).done(function (res) {
                        state.loading = false;
                        api.showBottomLoading(table, false);
                        if (!res || typeof res.rows === 'undefined') {
                            Toastr.error(__('Unknown data format'));
                            api.updateHint(table);
                            return;
                        }

                        var rows = res.rows || [];
                        if (rows.length === 0) {
                            state.loaded = state.total;
                            api.updateHint(table);
                            return;
                        }

                        table.bootstrapTable('append', rows);
                        state.loaded += rows.length;
                        api.updateHint(table);
                        api.autoFillViewport(table);

                        if (options.fixedColumns) {
                            table.bootstrapTable('resetView');
                        }
                    }).fail(function () {
                        state.loading = false;
                        api.showBottomLoading(table, false);
                        api.updateHint(table);
                        Toastr.error(__('Unknown data format'));
                    });
                },

                autoFillViewport: function (table) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);
                    if (!state.enabled || state.loading || state.pendingLoad || state.loaded >= state.total) {
                        return;
                    }
                    var $body = table.closest('.bootstrap-table').find('.fixed-table-body');
                    if (!$body.length) {
                        return;
                    }
                    var el = $body[0];
                    if (el.scrollHeight <= el.clientHeight + api.SCROLL_THRESHOLD) {
                        api.scheduleLoadMore(table);
                    }
                },

                togglePaginationNav: function (table, hide) {
                    table.closest('.bootstrap-table').find('.fixed-table-pagination .pagination').toggle(!hide);
                },

                getHintText: function (loaded, total, loading, pending) {
                    if (pending) {
                        var pendingText = __('Stream loading pending');
                        if (!pendingText || pendingText === 'Stream loading pending') {
                            pendingText = '即将加载更多，可切换显示条数取消...';
                        }
                        return pendingText;
                    }
                    if (loading) {
                        var loadingText = __('Stream loading');
                        return loadingText && loadingText !== 'Stream loading' ? loadingText : '加载中...';
                    }
                    var template = __('Stream loaded');
                    if (!template || template === 'Stream loaded') {
                        template = '已加载 %loaded% / %total%，继续滚动加载更多';
                    }
                    return template
                        .replace('%loaded%', String(loaded))
                        .replace('%total%', String(total));
                },

                updateHint: function (table, loading, pending) {
                    var api = Controller.api.streamLoad;
                    var state = api.getState(table);
                    var $wrapper = table.closest('.bootstrap-table');
                    var $detail = $wrapper.find('.pagination-detail');

                    if (!state.enabled) {
                        $wrapper.find('.split-stream-hint').remove();
                        return;
                    }

                    var $hint = $wrapper.find('.split-stream-hint');
                    if (!$hint.length) {
                        $hint = $('<span class="split-stream-hint text-muted" style="margin-left:10px;font-size:12px;"></span>');
                        $detail.append($hint);
                    }
                    var isPending = pending !== undefined ? pending : state.pendingLoad;
                    var isLoading = loading !== undefined ? loading : state.loading;
                    $hint.text(api.getHintText(state.loaded, state.total, isLoading, isPending));
                }
            },

            formatter: {
                platformStatus: function (value, row) {
                    var text = row.platform_status_text != null && row.platform_status_text !== ''
                        ? String(row.platform_status_text)
                        : (Config.platformStatusList && Config.platformStatusList[value] ? Config.platformStatusList[value] : value);
                    var cls = value === 'online' ? 'success' : (value === 'offline' ? 'default' : 'warning');
                    return '<span class="text-' + cls + '">' + Fast.api.escape(text || '') + '</span>';
                },
                isRatioDeferred: function (row) {
                    return parseInt(row.ratio_deferred, 10) === 1 && String(row.status || '') === 'normal';
                },
                ratioDeferredTooltip: function (row) {
                    var streak = parseInt(row.no_inbound_click_streak, 10) || 0;
                    var template = __('Ratio deferred tooltip');
                    if (!template || template === 'Ratio deferred tooltip') {
                        template = '连续 %s 次访问无进线增长，已触线下号比率，选号已后置，等待同步裁决';
                    }
                    return template.indexOf('%s') >= 0 ? template.replace('%s', String(streak)) : template;
                },
                ratioDeferredBadgeHtml: function (tooltip) {
                    var label = __('Ratio deferred badge');
                    if (!label || label === 'Ratio deferred badge') {
                        label = '降权中';
                    }
                    return '<span class="label label-warning split-ratio-deferred-badge" style="margin-left:6px;font-size:11px;font-weight:500;vertical-align:middle;"'
                        + ' data-toggle="tooltip" data-placement="top" title="' + Fast.api.escape(tooltip) + '">'
                        + '<i class="fa fa-level-down"></i> ' + Fast.api.escape(label)
                        + '</span>';
                },
                numberWithDeferred: function (value, row) {
                    var html = Fast.api.escape(String(value || ''));
                    if (Controller.api.formatter.isRatioDeferred(row)) {
                        html += Controller.api.formatter.ratioDeferredBadgeHtml(
                            Controller.api.formatter.ratioDeferredTooltip(row)
                        );
                    }
                    return html;
                }
            },
            refreshSearchSelect: function ($field) {
                if ($field.length && $field.hasClass('selectpicker') && $field.data('selectpicker')) {
                    $field.selectpicker('refresh');
                }
            },
            syncStatusTabs: function (table, statusValue) {
                var $tabs = table.closest('.panel-intro').find('.panel-heading [data-field="status"]');
                if (!$tabs.length) {
                    return;
                }
                $tabs.find('li').removeClass('active');
                $tabs.find('li a[data-value="' + (statusValue === null || statusValue === undefined ? '' : statusValue) + '"]')
                    .parent()
                    .addClass('active');
            },
            /**
             * 工具栏「降权中」快捷筛选：与列表徽章一致（ratio_deferred=1 且 status=normal）
             */
            bindDeferredFilter: function (table) {
                var active = false;
                var savedStatus = '';
                var $btn = $('.btn-filter-ratio-deferred');
                if (!$btn.length) {
                    return;
                }

                var applyFilter = function () {
                    var $form = table.closest('.bootstrap-table').find('form.form-commonsearch');
                    if (!$form.length) {
                        return false;
                    }
                    var $ratioField = $form.find('[name="ratio_deferred"]');
                    var $statusField = $form.find('[name="status"]');

                    if (active) {
                        savedStatus = $statusField.length ? String($statusField.val() || '') : '';
                        if ($ratioField.length) {
                            $ratioField.val('1');
                            Controller.api.refreshSearchSelect($ratioField);
                        }
                        if ($statusField.length) {
                            $statusField.val('normal');
                            Controller.api.refreshSearchSelect($statusField);
                        }
                        Controller.api.syncStatusTabs(table, 'normal');
                    } else {
                        if ($ratioField.length) {
                            $ratioField.val('');
                            Controller.api.refreshSearchSelect($ratioField);
                        }
                        if ($statusField.length) {
                            $statusField.val(savedStatus);
                            Controller.api.refreshSearchSelect($statusField);
                        }
                        Controller.api.syncStatusTabs(table, savedStatus);
                        savedStatus = '';
                    }

                    table.trigger('uncheckbox');
                    $form.trigger('submit');
                    return true;
                };

                $btn.on('click', function (e) {
                    e.preventDefault();
                    active = !active;
                    $btn.toggleClass('btn-warning', active).toggleClass('btn-default', !active);
                    if (!applyFilter()) {
                        active = !active;
                        $btn.toggleClass('btn-warning', active).toggleClass('btn-default', !active);
                        Toastr.warning('筛选表单未就绪，请刷新页面后重试');
                    }
                });
            },
            /**
             * 清理无效降权池：无落地页访问基线却标记 ratio_deferred=1 的号码
             */
            bindDeferredCleanup: function (table) {
                var $btn = $('.btn-cleanup-ratio-deferred');
                if (!$btn.length) {
                    return;
                }
                $btn.on('click', function (e) {
                    e.preventDefault();
                    Fast.api.ajax({
                        url: 'split.number/cleanupdeferredpreview',
                        type: 'get'
                    }, function (data) {
                        var count = parseInt(data.count, 10) || 0;
                        if (count <= 0) {
                            Toastr.info(__('Ratio deferred cleanup none'));
                            return false;
                        }
                        var template = __('Ratio deferred cleanup confirm');
                        if (!template || template === 'Ratio deferred cleanup confirm') {
                            template = '将清除 %d 条无效降权记录。确定继续？';
                        }
                        var message = template.indexOf('%d') >= 0
                            ? template.replace('%d', String(count))
                            : template;
                        Layer.confirm(message, {icon: 3, title: __('Warning')}, function (index) {
                            Layer.close(index);
                            Fast.api.ajax({
                                url: 'split.number/cleanupdeferred',
                                type: 'post'
                            }, function (data, ret) {
                                table.bootstrapTable('refresh');
                                Toastr.success(ret.msg || __('Ratio deferred cleanup success'));
                            });
                        });
                        return false;
                    });
                });
            },
            bindevent: function () {
                Form.api.bindevent($('form[role=form]'));
                Controller.api.fixSelectPlaceholder();
                Controller.api.bindNumberTypeToggle();
            },
            fixSelectPlaceholder: function () {
                var text = __('Please select');
                if (!text || text === 'Please select' || text === 'Please Select') {
                    text = '请选择';
                }
                $('#c-split_link_id').each(function () {
                    var $el = $(this);
                    $el.attr({'data-none-selected-text': text, 'title': text});
                    $el.find('option[value=""]').first().text(text);
                    if ($el.data('selectpicker')) {
                        $el.selectpicker('render');
                    }
                });
            },
            bindNumberTypeToggle: function () {
                var $type = $('#c-number_type');
                var $wrap = $('.split-number-type-custom');
                var $custom = $('#c-number_type_custom');
                if (!$type.length) {
                    return;
                }
                var toggle = function () {
                    var val = $type.val();
                    if (val === 'custom') {
                        $wrap.removeClass('hide');
                        $custom.attr('data-rule', 'required');
                    } else {
                        $wrap.addClass('hide');
                        $custom.removeAttr('data-rule');
                        if (!$wrap.closest('form').attr('id') || $('#edit-form').length === 0) {
                            $custom.val('');
                        }
                    }
                };
                $type.on('changed.bs.select change', toggle);
                toggle();
            },
            openBatchUpdateModal: function (ids, table) {
                var statusHtml = '';
                $.each(Config.statusList || {}, function (key, label) {
                    var checked = key === 'normal' ? ' checked' : '';
                    statusHtml += '<label class="radio-inline"><input type="radio" name="batch_status" value="' + key + '"' + checked + '> ' + label + '</label>';
                });
                var manualHtml = '';
                $.each(Config.manualManageList || {}, function (key, label) {
                    var checked = key === '0' ? ' checked' : '';
                    manualHtml += '<label class="radio-inline"><input type="radio" name="batch_manual_manage" value="' + key + '"' + checked + '> ' + label + '</label>';
                });
                var html = [
                    '<div class="split-batch-update-modal" style="padding:18px 22px;">',
                    '  <div class="form-group">',
                    '    <label class="control-label">' + __('Batch selected count') + '</label>',
                    '    <p class="form-control-static" style="font-size:18px;font-weight:600;margin:0;">' + ids.length + ' ' + __('Unit count') + '</p>',
                    '  </div>',
                    '  <div class="form-group">',
                    '    <label class="control-label">' + __('Status') + '</label>',
                    '    <div>' + statusHtml + '</div>',
                    '  </div>',
                    '  <div class="form-group" style="margin-bottom:0;">',
                    '    <label class="control-label">' + __('Manual_manage') + '</label>',
                    '    <div>' + manualHtml + '</div>',
                    '  </div>',
                    '</div>'
                ].join('');

                Layer.open({
                    type: 1,
                    title: __('Batch update title'),
                    area: ['420px', 'auto'],
                    shadeClose: false,
                    content: html,
                    btn: [__('OK'), __('Cancel')],
                    yes: function (index, layero) {
                        var status = layero.find('input[name="batch_status"]:checked').val();
                        var manualManage = layero.find('input[name="batch_manual_manage"]:checked').val();
                        if (typeof status === 'undefined' || typeof manualManage === 'undefined') {
                            Toastr.error(__('Invalid parameters'));
                            return false;
                        }
                        Fast.api.ajax({
                            url: 'split.number/batchupdate',
                            type: 'post',
                            data: {
                                ids: ids.join(','),
                                status: status,
                                manual_manage: manualManage
                            }
                        }, function () {
                            Layer.close(index);
                            table.bootstrapTable('refresh');
                            $('.btn-batch-update-status').addClass('btn-disabled disabled');
                            Toastr.success(__('Batch update success'));
                        });
                        return false;
                    }
                });
            },
            openBatchOperateModal: function (table) {
                var pleaseSelect = __('Please select');
                if (!pleaseSelect || pleaseSelect === 'Please select' || pleaseSelect === 'Please Select') {
                    pleaseSelect = '请选择';
                }
                var linkOptions = ['<option value="">' + Fast.api.escape(pleaseSelect) + '</option>'];
                $.each(Config.splitLinkSelectList || {}, function (id, label) {
                    linkOptions.push('<option value="' + Fast.api.escape(String(id)) + '">' + Fast.api.escape(String(label)) + '</option>');
                });
                var html = [
                    '<div class="split-batch-operate-modal" style="padding:18px 22px;">',
                    '  <div class="form-group">',
                    '    <label class="control-label">' + __('Link_url') + '<span class="text-danger">*</span></label>',
                    '    <select id="batch-operate-split-link" class="form-control selectpicker" data-live-search="true" data-none-selected-text="' + pleaseSelect + '" title="' + pleaseSelect + '">',
                    linkOptions.join(''),
                    '    </select>',
                    '  </div>',
                    '  <div class="form-group">',
                    '    <label class="control-label">' + __('Number') + '<span class="text-danger">*</span></label>',
                    '    <textarea id="batch-operate-numbers" class="form-control" rows="8" placeholder="' + Fast.api.escape(__('Numbers one per line')) + '"></textarea>',
                    '  </div>',
                    '  <div class="form-group">',
                    '    <label class="control-label">' + __('Batch operate action') + '<span class="text-danger">*</span></label>',
                    '    <select id="batch-operate-action" class="form-control selectpicker" data-none-selected-text="' + pleaseSelect + '" title="' + pleaseSelect + '">',
                    '      <option value="enable">' + Fast.api.escape(__('Batch operate enable')) + '</option>',
                    '      <option value="disable">' + Fast.api.escape(__('Batch operate disable')) + '</option>',
                    '      <option value="delete">' + Fast.api.escape(__('Batch operate delete')) + '</option>',
                    '    </select>',
                    '  </div>',
                    '  <div class="form-group" style="margin-bottom:0;text-align:right;">',
                    '    <button type="button" class="btn btn-primary btn-batch-operate-confirm">' + __('OK') + '</button> ',
                    '    <button type="button" class="btn btn-default btn-batch-operate-cancel">' + __('Cancel') + '</button>',
                    '  </div>',
                    '</div>'
                ].join('');

                var layerIndex = Layer.open({
                    type: 1,
                    title: __('Batch operate title'),
                    area: ['520px', 'auto'],
                    shadeClose: false,
                    content: html,
                    success: function (layero, index) {
                        Form.events.selectpicker(layero);
                        layero.find('.btn-batch-operate-cancel').on('click', function () {
                            Layer.close(index);
                        });
                        layero.find('.btn-batch-operate-confirm').on('click', function () {
                            var splitLinkId = $.trim(layero.find('#batch-operate-split-link').val());
                            var numbers = $.trim(layero.find('#batch-operate-numbers').val());
                            var action = $.trim(layero.find('#batch-operate-action').val());

                            if (!splitLinkId) {
                                Toastr.warning(__('Please select split link'));
                                return false;
                            }
                            if (!numbers) {
                                Toastr.warning(__('Please fill at least one number'));
                                return false;
                            }
                            if (!action) {
                                Toastr.error(__('Invalid batch operate action'));
                                return false;
                            }

                            var submit = function () {
                                Fast.api.ajax({
                                    url: 'split.number/batchoperate',
                                    type: 'post',
                                    data: {
                                        split_link_id: splitLinkId,
                                        numbers: numbers,
                                        action: action
                                    }
                                }, function (data, ret) {
                                    Layer.close(index);
                                    table.bootstrapTable('refresh');
                                    Toastr.success(ret.msg || __('Batch operate success'));
                                });
                            };

                            if (action === 'delete') {
                                Layer.confirm(__('Batch operate delete confirm'), {icon: 3, title: __('Warning')}, function (confirmIndex) {
                                    Layer.close(confirmIndex);
                                    submit();
                                });
                                return false;
                            }

                            submit();
                            return false;
                        });
                    }
                });
            }
        }
    };
    return Controller;
});
