var { BaseModel, BaseFormModel, FormBuilder, BaseSecondaryForm, BaseInnerModel } = require('../master/baseModels.js');
import { ApiService } from "../../util/apiService";
require('knockout.validation');
import { BaseViewModel } from '../master/baseViewModel.js';

export class Tree extends BaseModel {
    constructor(model) {
        super(model);
        this.shortDesc = ko.pureComputed(function () {
            var valueType = _h.getEnumText(valueTypes, this.valueType());
            var currencyType;
            switch (this.treeType()) {
                case 0:
                    currencyType = _h.getEnumText(currencyTypes, this.currencyType());
                    break;
                case 3:
                    valueType = "تلفیقی عددی ";
                    break;
                case 2:
                    valueType = "تلفیقی مالی ";
                    break;
            }
            var asType = this.treeType() === 1
                ? 'جریان وجوه نقد'
                : _h.getEnumText(assignmentTypes, this.assignmentType());
            var text = asType + " - " + valueType;

            if (currencyType)
                text = text + " - " + currencyType;
            if (this.accountType())
                text += " - " + _h.getEnumText(accountTypes, this.accountType());

            return text;
        }, this);
        this.shortName = ko.pureComputed(function () {
            var name = this.name();
            if (!_h.isEmpty(name)) {
                if (name.length < 50)
                    return name + " (" + this.code() + ")";
                return name.substr(0, 47) + "..." + " (" + this.code() + ")";
            }
            return "";
        }, this);
    }
}

export class TreeForm extends BaseFormModel {
    constructor(viewModel, editMode) {
        super(viewModel, editMode, ["gParent"]);
        if (!editMode) {
            this.id(0);
            this.cbCompanyId = ko.observable(_h.kocnx().loginCompanyId());
            this.valueType(viewModel.valueType());
            this.name("");
            this.description("");
            this.currencyType = ko.observable(1);
        }
        this.isOwner = this.cbCompanyId() === _h.kocnx().loginCompanyId();
        if (_h.kocnx().loginCompanyType() === 0) {
            this.treeTypes = ko.observableArray(treeTypes);
        } else {
            this.treeTypes = ko.observableArray(treeTypes2);
        }

        this.disabledAccountType = ko.computed(function () {
            if (!this.isOwner)
                return true;
            var cond = this.treeType() !== 0 && this.treeType() !== 1 && this.treeType() !== 4;
            if (this.editMode())
                return this.hasChildren() || cond;
            else
                return cond;
        }, this);
        this.condFirst = ko.computed(function () {
            return this.treeType() === 0;
        }, this);
        this.condSecond = ko.computed(function () {
            if (!this.isOwner)
                return true;
            if (!this.editMode())
                return false;
            return this.editMode() === true && this.hasChildren() === true;
        }, this);
        this.setValidationObject();
        this.createForm();
    }

    setValidationObject() {
        var self = this;
        self.validationObject = ko.validatedObservable({
            name: self.name.extend({
                required: true,
                minLength: 3,
                maxLength: 100,
                remoteIsUniqueRule: { params: [self.id, "Tree", "name"] }
            }),
            treeType: self.treeType.extend({
                required: true
            }),
            pattern: self.pattern.extend({
                required: true,
                min: 5,
                max: 24,
                numberOnly: null
            }),
            accountType: self.accountType.extend({
                required: {
                    onlyIf: function () {
                        return _h.contains([0, 1, 4], self.treeType());
                    }
                }
            }),
            currencyType: self.currencyType.extend({
                required: {
                    onlyIf: function () {
                        return _h.contains([0], self.treeType());
                    }
                }
            })
        });
    }

    filterTree(item) {
        if (_h.kocnx().loginCompanyType() === 1 &&
            item.value !== 2 &&
            item.value !== 3) {
            return true;
        }
        return _h.kocnx().loginCompanyType() === 0;
    }

    createForm() {
        const controls = [
            this.createLine({ t: 'txb', val: this.name, dis: !this.isOwner },
                { t: 'txb', val: this.pattern, dis: this.condSecond }, true),
            this.createLine({ t: 'slc', val: this.treeType, options: this.treeTypes, dis: (this.editMode() || !this.isOwner) },
                { t: 'slc', val: this.accountType, options: accountTypes, dis: this.disabledAccountType }, true, 30),
            this.createLine({
                t: 'slc',
                val: this.currencyType,
                options: currencyTypes,
                dis: !this.isOwner
            }, null, this.condFirst, 30),
            this.createLine({ t: 'slc', val: this.folderId, options: this.parentVM.folderList },
                null, true, 30),
            this.createLine({ t: 'txa', val: this.description }, undefined, true, 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 function NodeForm() {
    var _ = this;
    _.liTarget = null;
    _.uid = ko.observable();
    _.id = ko.observable();
    _.code = ko.observable();
    _.treeType = ko.observable();
    _.valueType = ko.observable();
    _.formula = ko.observable();
    _.assignmentType = ko.observable();
    _.parentNodeTemplate = ko.observable();
    _.showAccountType = ko.observable(false);
    _.accountType = ko.observable();
    _.parentId = ko.observable();
    _.nodeType = ko.observable();
    _.nodeTemplate = ko.observable();
    _.name = ko.observable("");
    _.description = ko.observable();
    _.cashFlowCalculation = ko.observable();
    _.consolidateCompany = ko.observable();
    _.companyList = ko.observableArray();
    _.addByAutoComplete = ko.observable();
    _.cbCompanyId = ko.observable();
    _.refreshValue = ko.observable(false);
    _.createValueProperty = function (treeType) {
        switch (treeType) {
            case 0:
            case 1:
            case 4:
            case 5:
                _.value = ko.observable();
                break;
            case 2:
                _.value = ko.observable()
                    .extend({
                        inputNumberFormatter: { negative: true, decimalNumber: false },
                        treeFiscalValueValidate: true
                    });
                break;
            case 3:
                _.value = ko.observable()
                    .extend({
                        inputNumberFormatter: { negative: true, decimalNumber: true },
                        treeNumeralDecimalValueValidate: true
                    });
                break;
            case 6:
                _.value = ko.observable().extend({ treeNonNumeralValueValidate: true });
                break;
            case 7:
                _.value = ko.observable()
                    .extend({
                        inputNumberFormatter: { negative: true, decimalNumber: true },
                        treeNumeralDecimalValueValidate: true
                    });
                break;
            case 8:
                _.value = ko.observable().extend({
                    inputNumberFormatter: { negative: true, decimalNumber: false },
                    treeFiscalValueValidate: true
                });
                break;
        }
    };
    _.fillModel = function (model) {
        _.refreshValue(true);
        if (model.uid)
            _.uid(model.uid);
        _.id(model.id);
        if (!ko.isObservable(_.value))
            _.createValueProperty(model.tt);

        _.liTarget = model.liTarget;
        if (model.parentNodeTemplate)
            _.parentNodeTemplate(model.parentNodeTemplate);
        if (model.co !== "null")
            _.code(model.co);
        _.assignmentType(model.as);
        _.treeType(model.tt);
        if (model.pId)
            _.parentId(model.pId);
        _.valueType(model.vt);
        if (model.v !== "null") {

            _.value(model.v);
        }
        _.nodeType(model.nt);
        _.accountType(model.at);
        _.name(model.na);
        if (model.f !== "null")
            _.formula(model.f);
        if (_h.isNullOrEmpty(model.cfc) || model.cfc === 0)
            _.cashFlowCalculation(1);
        else
            _.cashFlowCalculation(model.cfc);


        if (_h.isNullOrEmpty(model.nte) || model.nte === 0)
            _.nodeTemplate(null);
        else
            _.nodeTemplate(model.nte);

        if (_h.isNullOrEmpty(model.cc) || model.cc === 0)
            _.consolidateCompany(null);
        else
            _.consolidateCompany(model.cc);
        _.description(model.de);
        _.isShowAccountType(model);
        _.cbCompanyId(model.ci);
        _.refreshValue(false);
    };
    _.showNodeTemplate = ko.computed(function () {
        return _.id() === 0 && _.treeType() === 0
            && _h.kocnx().loginCompanyType() === 0
            && (_h.isNullOrEmpty(_.parentNodeTemplate())
                || _.parentNodeTemplate() === 0 || _.parentNodeTemplate() === undefined);
    });
    _.onChangeFormula = function (val) {
        _.formula(val);
    };
    _.isShowAccountType = function (itemTarget) {
        var res = _h.contains([0, 1, 4], itemTarget.tt);
        _.showAccountType(res);
    };
    _.validationObject = ko.validatedObservable({
        name: _.name.extend({
            required: true,
            minLength: 2,
            maxLength: 100
        }),
        nodeType: _.nodeType.extend({
            required: true
        }),
        accountType: _.accountType.extend({
            required: {
                onlyIf: function () {
                    return _h.contains([0, 1, 4], _.treeType());
                }
            }
        }),
        cashFlowCalculation: _.cashFlowCalculation.extend({
            required: {
                onlyIf: function () {
                    var context = _h.kocnx();
                    var periodClosed = context.periodItem() !== null &&
                        context.periodItem() !== undefined &&
                        context.periodItem().cl;
                    return !periodClosed && _h.contains([1], _.treeType()) && _.nodeType() === 2;
                }
            }
        }),
        formula: _.formula.extend({

            remoteIsValidateFormula: { params: 4 }
        }),
        code: _.code.extend({
            minLength: 3,
            maxLength: 24,
            remoteIsUniqueRule: { params: [_.id, "Node", "code"] }
        })
    });
    _.toUpdateTree = function () {
        var uid = _.uid();
        if (_.uid() === "undefined")
            uid = "";
        return {
            id: _.id(),
            uid: uid,
            nt: _.nodeType(),
            nte: _.nodeTemplate(),
            co: _.code(),
            tt: _.treeType(),
            at: _.accountType(),
            cfc: _.cashFlowCalculation(),
            v: _.value(),
            f: _.formula(),
            na: _h.clearHtmlTag(_.name()),
            as: _.assignmentType(),
            dv: _h.formatTextIfNull(_.value()),
            de: _h.clearHtmlTag(_.description()),
            ci: _.cbCompanyId(),
            children: [],
            gid: _.addByAutoComplete()
        };
    };
    _.isValid = function () {
        if (!_.validationObject.isValid()) {
            _.validationObject.errors.showAllMessages();
            return false;
        }
        return true;
    };
    _.onNodeAutoSelect = function (controlName, item) {
        _.addByAutoComplete(item.id);
        item.id = 0;
        _.parentId(model.pi);
        _.fillModel(item);
    };
}

export class NodeValuePartViewModel extends FormBuilder {
    constructor(id) {
        super();
        this.width = "600px";
        this.caption = ko.observable();
        this.treeName = ko.observable();
        this.nodeName = ko.observable();
        ko.utils.extend(this, new BaseViewModel({
            entityName: "NodeValuePart",
            apiService: {
                actionList: ["filterby"]
            },
            filters: [
                { name: 'nodeId' }
            ],
            extraParams: ["tree", "node", "sum"],
            buttons: [
                { name: 'help', access: false, cMenu: false },
                { name: 'refresh', access: false, cMenu: false }
            ],
            sortDirection: "Ascending",
            sortProperty: "company",
            context: this,
            cols: valuepartsModelRes,
            getList: true,
            saveState: true,
            tableStyle: "font-size: 11px;",
            footerTemplate: "nodevaluepart-footertable-template",
            selectRow: false,
            contextMenu: false
        }));
        this.nodeId(id);
        this.createCaption = ko.computed(function () {
            if (!_h.isEmpty(this.tree()))
                this.caption(this.tree() + " - " + this.node());
            return "";
        }.bind(this));
        this.btnVisibility = ko.computed(function () {
            this.vishelp(true);
            this.visrefresh(true);
        }.bind(this));
        this.fillTableProperties();
        this.createForm();
        this.getRecords();
    }

    createForm() {
        const controls = [
            this.createLine({ t: 'tm', templateName: 'nodevaluepart-form-t' }, undefined, true, 0, 0),
        ];
        this.formControls(controls);
        this.formButtons({
            name: 'footer-form-t', data: {
                buttons: [
                    { name: 'cancel', click: _h.kocnx().closeForm }]
            }
        });
    }

}

export class NodeValuePart extends BaseModel {
    constructor(model) {
        super(model);
    }
}

export class TreeSettingForm extends BaseSecondaryForm {
    constructor(viewModel, model) {
        super(viewModel, [
            { name: "consolidatedNodes", type: "ar", val: model.consolidatedNodes },
            { name: "selectedItems", type: "obar" },
            { name: "selector", type: "", val: "#tree_view_cs" }
        ], "treeSettingCaption");
        this.createForm();

        this.configTools();
    }

    configTools() {
        if (this.consolidatedNodes && this.consolidatedNodes.length)
            for (var i = 0; i < this.consolidatedNodes.length; i++) {
                if (this.consolidatedNodes[i].selected)
                    this.selectedItems.push({ value: this.consolidatedNodes[i].id });
                if (this.consolidatedNodes[i].children && this.consolidatedNodes[i].children.length)
                    this.findSelectedChild(this.consolidatedNodes[i].children);
            }
        var array = this.consolidatedNodes;
        setTimeout(function () {
            $("#tree_view_cs").treeView({
                tType: "CompanySetting",
                location: "CompanySetting",
                nodes: array,
                rootId: 10001,
                permitPeriodEdit: _h.kocnx().permitPeriodEdit()
            });
        }, 1);
    }

    findSelectedChild(children) {
        for (var i = 0; i < children.length; i++) {
            if (children[i].selected)
                this.selectedItems.push({ value: children[i].id });
            if (children[i].children && children[i].children.length)
                this.findSelectedChild(children[i].children);
        }
    }

    toServer() {
        var items = $(this.selector).treeView("selectedCheckedItems");
        return {
            consolidatedNodes: items
        };
    }

    exportExcelBtn(formModel, btnm) {
        var items = $("#tree_view_cs").treeView("selectedCheckedItems");
        var model = {
            controllerName: 5,
            inputData: items
        };
        _h.kocnx().createExcel(model);
    }

    createForm() {
        const controls = [
            this.createLine({ t: 'tm', templateName: 'treesetting-form-t' }, undefined, true, 0, 0),
        ];
        this.formControls(controls);
        this.formButtons({
            name: 'footer-form-t', data: {
                buttons: [
                    {
                        name: "custom",
                        resText: 'confirmedCaption',
                        vis: _h.kocnx().permitPeriodEdit,
                        click: this.parentVM.confirmSettingNode
                    },
                    {
                        name: "custom",
                        resText: 'exportExcelSetting',
                        vis: true,
                        click: this.exportExcelBtn,
                        icon: "ExportExcel"
                    },
                    { name: 'cancel', click: _h.kocnx().closeForm }]
            }
        });
    }
}