"use strict";

import {Utils} from "../../Utils/Utils.ecma.js";
import {Check} from "../../Utils/Check.ecma.js";

/**
 * @typedef {import("../FormatModule.ecma.js").FormatModule} FormatModule
 */

/**
 * @class SerieFormat
 * @constructor
 * @param {!FormatModule} format 
 * @returns {void}
 * @access public
 * @static
 */
export const SerieFormat = (function(){

    /**
     * @constructs SerieFormat
     * @param {!FormatModule} format 
     * @returns {void}
     * @access private
     * @static
     */
    const SerieFormat = function(format){

        /** @type {SerieFormat} */
        const self = this;

        /**
         * @returns {void}
         * @access private
         */
        const constructor = () => {
            format.modes.serie = self.get;
            format.checks.serie = self.check;
        };

        /**
         * @param {[number, number]} coordenates 
         * @param {!(string|Array.<any|null>)} inputs 
         * @param {!Object.<string, any|null>} [shared = {}] 
         * @param {!Array.<string>} [fragments = []] 
         * @returns {string}
         * @access public
         */
        this.get = ([i, j], inputs, shared = {}, fragments = []) => {

            /** @type {Array.<number|[number, number]>} */
            const options = inputs.split("|").map(item => (
                      item.includes("-") ? item.split("-").map(Number) : 
                      Number(item)
                  )), 
                  /** @type {boolean} */
                  has_uniques = shared && shared.uniques_cache;
            /** @type {number} */
            let value;

            if(shared.serie !== undefined)
                while(options.length){
                    if(Check.is_number(options[0])){
                        if(options[0] >= shared.serie)
                            break;
                    }else if(options[0][1] >= shared.serie){
                        options[0][0] = shared.serie;
                        break;
                    };
                    options.shift();
                };

            for(let _ = 0; _ < 100; _ ++){
                value = Check.is_number(value = Utils.get_random(options)) ? value : Utils.get_random(...value);
                if(!has_uniques || !shared.uniques_cache.includes("" + value))
                    break;
            };
            has_uniques && (shared.uniques_cache.push("" + value));

            // Check.is_string(inputs) && 
            // (inputs = inputs.split("|").map(range => range.split("-").map(Number)));
            
            // shared.serie === undefined || 
            // (inputs = inputs.filter(range => (
            //     !Check.is_array(range) ? shared.serie < range : 
            //     range.length == 1 ? shared.serie < range[0] : 
            // shared.serie < range[1])));

            // /** @type {number|[number]|[number, number]} */
            // const range = Utils.get_random(inputs);

            // if(!Check.is_array(range))
            //     return shared.serie = range;
            // if(range.length == 1)
            //     return shared.serie = range[0];

            // /** @type {number} */
            // let value;
            
            // while((value = Utils.get_random(...range)) <= shared.serie);

            return shared.serie = value;
        };

        /**
         * @param {[number, number]} coordenates 
         * @param {!string} string 
         * @param {!(string|Array.<string>)} inputs 
         * @param {!Object.<string, any|null>} [shared = {}] 
         * @param {!Array.<string>} [fragments = []]
         * @returns {number}
         * @access public
         */
        this.check = ([i, j], string, inputs, shared = {}, fragments = []) => FormatModule.check_range(string, inputs);

        constructor();

    };

    return SerieFormat;
})();