require('knockout.validation');
var { BaseModel, BaseFormModel, BaseInnerModel } = require('../master/baseModels.js');

import { BaseViewModel } from '../master/baseViewModel.js';

export class DynamicTable extends BaseModel {
    constructor(model) {
        super(model);
        this.fieldsShow = ko.observable(false);
        this.fields = ko.observableArray();
        if (_h.any(model.fields))
            for (let j = 0; j < model.fields.length; j++) {
                const record = new Field(model.fields[j]);
                this.fields.push(record);
            }
    }
    refreshModel(model) {
        var fields = ko.toJS(model.fields);
        _autoMapper.fillModel(this, model);
        this.fields.removeAll();
        if (_h.any(fields))
            for (let j = 0; j < fields.length; j++) {
                const record = new Field(fields[j]);
                this.fields.push(record);
            }
    }
}
export class Field extends BaseInnerModel {
    constructor(model) {
        super(model);
        this.hasFormat = ko.observable(false);
        this.index = ko.observable(model.index || false);
    }
}
export function FieldForm() {
    var self = this;
    self.fieldName = ko.observable();
    self.order = ko.observable();
    self.dataType = ko.observable();
    self.dataFormat = ko.observable();
    self.index = ko.observable(false);
    self.hasFormat = ko.observable(false);
    self.dataFormats = ko.observableArray();
    self.dataType.subscribe(function (newValue) {
        self.refreshDataType(newValue);
    });
    self.refreshDataType = function (newValue) {
        self.hasFormat(false);
        if (newValue !== 7)
            self.dataFormats.removeAll();
        if (!_h.isNullOrEmpty(newValue)) {
            switch (newValue) {
                case 3:
                    self.hasFormat(true);
                    self.dataFormats([
                        { text: "1", value: "1" },
                        { text: "1.1", value: "1.1" }
                    ]);
                    break;
                case 4:
                    self.hasFormat(true);
                    self.dataFormats([
                        { text: "yyyymmdd", value: "yyyymmdd" },
                        { text: "jyyyyjmmjdd", value: "jyyyyjmmjdd" },
                        { text: "yyyy/mm/dd", value: "yyyy/mm/dd" },
                        { text: "jyyyy/jmm/jdd", value: "jyyyy/jmm/jdd" },
                        { text: "yyyy-mm-dd", value: "yyyy-mm-dd" },
                        { text: "jyyyy-jmm-jdd", value: "jyyyy-jmm-jdd" }
                    ]);
                    break;
                case 5:
                    self.hasFormat(true);
                    self.dataFormats([
                        { text: "false|true", value: "false|true" },
                        { text: "no|yes", value: "no|yes" },
                        { text: "0|1", value: "0|1" }
                    ]);
                    break;
                case 7:
                    self.hasFormat(true);
                    if (self.dataFormats().length === 0)
                        self.dataFormats.push({ text: "", value: "" });
                    break;
            }
        }
    };
    self.addEnumItem = function () {
        self.dataFormats.push({ text: "", value: "" });
    };
    self.validationObject = ko.validatedObservable({
        fieldName: self.fieldName.extend({
            required: true,
            minLength: 1,
            maxLength: 50
        }),
        dataType: self.dataType.extend({
            required: true
        })
    });
    self.createTagId = function () {
        return "Field-" + self.order();
    };
    self.toggleIndex = function () {
        self.index(!self.index());
    };
    self.fillModel = function (model) {
        self.fieldName(model.fieldName());
        self.order(model.order());
        self.dataType(model.dataType());
        self.index(model.index());
        self.dataFormat(model.dataFormat());
        self.dataFormats(model.dataFormats());
        self.refreshDataType(model.dataType());
    };
}
export class DynamicTableForm extends BaseFormModel {
    constructor(viewModel, editMode, res) {
        super(viewModel, editMode);
        this.lastPriority = ko.observable();
        this.fields = ko.observableArray();

        if (editMode) {
            this.lastPriority(res);
            var model = viewModel.multiCommandExecute("selectedRowRecord");
            if (_h.any(model.fields()))
                for (var i = 0; i < model.fields().length; i++) {
                    var record = new FieldForm();
                    record.fillModel(model.fields()[i]);
                    this.fields.push(record);
                }
        } else {
            this.lastPriority(res + 1);
            this.priority(res + 1);
            this.addField();
        }
        this.setValidationObject();
        this.createForm();
    }
    setValidationObject() {
        var self = this;
        this.validationObject = ko.validatedObservable({
            fields: self.fields,
            name: self.name.extend({
                required: true,
                remoteIsUniqueRule: { params: [self.id, "DynamicTable", "name"] },
                minLength: 3,
                maxLength: 100
            }),
            priority: self.priority.extend({
                required: true,
                number: true
            })
        });
    }
    addField() {
        var record = new FieldForm({ fieldId: 0, fieldCode: 0, fieldName: "", dataType: 0 });
        this.fields.push(record);
    }
    removeField(parent) {
        if (parent.fields().length > 1)
            parent.fields.remove(this);
    }
    createForm() {
        const controls = [
            this.createLine({ t: 'tsp', val: this.priority, min: 1, max: this.editMode() === true ? this.lastPriority() : this.priority() },
                { t: 'txb', val: this.name }),


            this.createLine({ t: 'slc', val: this.folderId, options: this.parentVM.folderList },
                null, true, 30),

            this.createLine({ t: 'tm', templateName: 'dynamictable-fields-form-t' }, undefined, true, 30, 30),
        ];
        this.formControls(controls);
        this.formButtons({
            name: 'footer-form-t', data: {
                buttons: [
                    { name: 'create', vis: !this.editMode(), click: this.parentVM.create },
                    { name: 'edit', vis: this.editMode, click: this.parentVM.edit },
                    { name: 'cancel', click: _h.kocnx().closeForm }]
            }
        });
    }
}

export class DynamicTableData extends BaseModel {
    constructor(model) {
        super(model);
        if (_h.any(model.cells))
            for (var j = 0; j < model.cells.length; j++) {
                var field = model.cells[j];
                this[field.order] = field.value;
            }
        this.styleRowValue = ko.pureComputed(function () {
            if (this.stateType() === 0)
                return 'color: #ccc;';
            return '';
        }.bind(this));
    }
}

export class DynamicTableDataViewModel {
    constructor(cols) {
        ko.utils.extend(this, new BaseViewModel({
            entityName: "DynamicTableData",
            apiService: {
                actionList: ["filterby", "delete"]
            },
            buttons: [
                { name: 'disables', access: true, icon: 'DocsDisable', cMenu: true },
                { name: 'enables', access: true, icon: 'DocsEnable', cMenu: true },
                { name: 'disable', access: true, icon: 'DocDisable', cMenu: true },
                { name: 'enable', access: true, icon: 'DocEnable', cMenu: true },
                { name: 'deleteAll', access: false, icon: 'Delete', cMenu: false },
                {
                    name: 'importExcel', access: false, icon: 'ImportExcel', cMenu: false,
                    action: _h.kocnx().tavm().importExcelBtn
                },
                { name: 'exportExcelFile', access: false, icon: 'ExportExcel', cMenu: false },
                { name: 'help', access: false, cMenu: false },
                { name: 'refresh', access: false, cMenu: false },
                { name: 'tools', access: false, cMenu: false }
            ],
            filters: [{ name: "tableId" }],
            sortDirection: "",
            sortProperty: "",
            context: this,
            dynamicCols: true,
            extraParams: [],
            saveState: true,
            cols: cols,
            getList: true,
            selectRow: true,
            contextMenu: true,
            searchKeyType: "enter",
            styleRow: "styleRowValue",
            tableStyle: "margin-top: 120px;width: 200%;margin-top: 10px;table-layout:initial;",
            isMultiSelectRows: true
        }));
        this.btnVisibility = ko.computed(function () {
            var context = _h.kocnx();
            var permitPeriodEdit = context.permitPeriodEdit();
            this.visexportExcelFile(true);
            this.visimportExcel(permitPeriodEdit && !context.periodItem().cl);
            this.visdeleteAll(permitPeriodEdit && !context.periodItem().cl);
            var enableCount = 0;
            var disableCount = 0;
            var selectedList = 0;
            var selectedRow = null;
            for (let i = 0; i < this.records().length; i++) {
                var record = this.records()[i];
                if (record.selected()) {
                    selectedRow = record;
                    if (record.stateType() === 0)
                        disableCount++;
                    if (record.stateType() === 1)
                        enableCount++;
                    selectedList++;
                }
            }
            if (selectedList === 0) {
                this.visdisable(false);
                this.visenable(false);
                this.visdisables(false);
                this.visenables(false);
            }
            if (selectedList === 1) {
                this.visdisable(permitPeriodEdit && !context.periodItem().cl && selectedRow.stateType() === 1);
                this.visenable(permitPeriodEdit && !context.periodItem().cl && selectedRow.stateType() === 0);
                this.visdisables(false);
                this.visenables(false);
            }
            if (selectedList > 1) {
                this.visdisable(false);
                this.visenable(false);
                this.visdisables(permitPeriodEdit && !context.periodItem().cl && disableCount >= 0 && enableCount > 0);
                this.visenables(permitPeriodEdit && !context.periodItem().cl && disableCount >= 0 && enableCount === 0);
            }
            this.vishelp(true);
            this.visrefresh(true);
            this.vistools(true);
        }.bind(this));
        this.countSelectedRecord = ko.pureComputed(function () {
            var count = 0;
            for (let i = 0; i < this.records().length; i++) {
                var record = this.records()[i];
                if (record.selected())
                    count++;
            }
            return count;
        }.bind(this));
    }
    exportExcelFileBtn() {
        var filterModel = this.createFilterByModel();
        var model = {
            controllerName: 49,
            inputData: filterModel
        };
        var cols = [];
        for (let i = 0; i < this.tableProperties().length; i++) {
            var record = this.tableProperties()[i];
            if (record.visibleCol())
                cols.push(record.name);
        }
        model.inputData.columns = cols;
        _h.kocnx().createExcel(model);
    }
    deleteAllBtn() {
        var confirmText = toast.createMessage(this.entityName, 'delrange', null, 'confirm');
        _h.confirmDeleteAlert(confirmText,
            function (res) {
                if (res) {
                    this.apiService.request({
                        name: "delete",
                        data: { id: this.tableId() },
                        success: function (data) {
                            this.records.removeAll();
                            toast.success(this.entityName, 'delrange');
                        }.bind(this),
                        error: function () {
                            toast.error(this.entityName, 'delrange');
                        }.bind(this)
                    });
                }
            }.bind(this));
    }
    init() {
        this.fillTableProperties();
        this.getRecords();
    }
}