/**
 * @since Last modified: 2024/05/11 11:22:38
 * @namespace plan
 * @description Plan model. Can be created, canceled and implemented. Similar to subscription/publication models.
 * @see {@link https://codepen.io/axui/pen/mdvwQYo|demo @ codepen}
 */
'use strict';
import getDataType from './getDataType';
import trim from './trim';
const plan = {
    handle: (name, type, cb) => {
        let nameArr = [];
        if (type === 'String') {
            name = trim(name);
            nameArr = name.includes(',') ? name.split(',') : name.split(' ');
        }
        else if (type === 'Array') {
            nameArr = name.map((k) => trim(k));
        }
        if (nameArr.length > 0) {
            for (let k of nameArr) {
                cb(k);
            }
        }
    },
    /**
 * @memberOf plan
 * @description Create a plan.
 * @param {string|string[]} name - Plan name.
 * @param {*} instance - Instance object.
 * @param {function} content - Plan content.It should be a function.
 * @returns {plan} Return plan itself.
 * @see {@link https://codepen.io/axui/pen/mdvwQYo|demo @ codepen}
 * @example
 * ax.plan.add('setValues',instance,()=>{});
 */
    add: function (name, instance, content) {
        let nameType = getDataType(name), handle = (str) => {
            if (!instance.plans.hasOwnProperty(str)) {
                instance.plans[str] = [];
            }
            let newValue = content.toString().replace(/\s/g, '').replace(/\;/g, '').match(/{(\S*)}/), oldValue = instance.plans[str].toString().replace(/\s/g, '').replace(/\;/g, '');
            newValue && !oldValue.includes(newValue[1]) ? instance.plans[str].push(content) : null;
        };
        this.handle(name, nameType, (item) => handle(item));
        return this;
    },
    /**
     * @memberOf plan
     * @description Cancel a plan.
     * @param {string|string[]} name - Plan name.
     * @param {*} instance - Instance object.
     * @param {function} [content] - Plan content.It should be a function.
     * @returns {plan} Return plan itself.
     * @see {@link https://codepen.io/axui/pen/mdvwQYo|demo @ codepen}
     * @example
     * ax.plan.remove('setValues',instance,()=>{});
     */
    remove: function (name, instance, content) {
        let nameType = getDataType(name), handle = (str) => {
            if (!instance.plans.hasOwnProperty(str)) {
                return console.warn(`The ${str} event is invalid or unusable!`);
            }
            if (!content) {
                delete instance.plans[str];
            }
            else {
                let index = instance.plans[str].findIndex((k) => k === content);
                if (index < 0) {
                    return console.warn(`The ${str} event is not bound!`);
                }
                instance.plans[str].splice(index, 1);
                instance.plans[str].length === 0 ? delete instance.plans[str] : null;
            }
        };
        this.handle(name, nameType, (item) => handle(item));
        return this;
    },
    /**
     * @memberOf plan
     * @description Implement a plan.
     * @param {string|string[]} name - Plan name.
     * @param {*} instance - Instance object.
     * @param {*} [params] - Plan parameters.0 or multiple.
     * @returns {plan} Return plan itself.
     * @see {@link https://codepen.io/axui/pen/mdvwQYo|demo @ codepen}
     * @example
     * ax.plan.do('setValues',instance,'2026','Los Angeles');
     * <!-- 2026 & Los Angeles are parameters -->
     */
    do: function (name, instance, ...params) {
        let nameType = getDataType(name), handle = (str) => {
            if (!instance.plans.hasOwnProperty(str)) {
                return console.warn(`The ${str} event is unregistered or unusable!`);
            }
            instance.plans[str].forEach((k) => {
                k.call(instance, ...params);
            });
        };
        this.handle(name, nameType, (item) => handle(item));
        return this;
    }
};
export default plan;
