/**
 * @since Last modified: 2024-09-07 10:42:02
 * @function debounce
 * @param {function} fn - Target function.
 * @param {object|null|undefined|number} [options] - Parameters.If the parameter is a standard object, it should be merged with the default value; if it is a number, it represents the delay value; in other cases, it defaults to the standard parameters.
 * @param {number} [options.delay=200]  - The delay of debounce.The operation is invalid within this time.
 * @param {boolean} [options.prevent=false]  - Whether to prevent default events in debounce delay.
 * @param {boolean} [options.auto=false]  - Is there an automatic switch between debounce and throttle on mobile devices?
 * @returns {function} - Return handler function width cancel method.
 * @see {@link https://codepen.io/axui/pen/MWxybYR|demo @ codepen}
 * @example
 * elem.onclick = ax.debounce(()=>{console.log('ok')});
 * <!--return a handler function-->
 */
'use strict';
import { T_null } from "../../../types/ax";
import ax from "../ax";
import config from "../global/config";
import isEmpty from "./isEmpty";
import isMobi from "./isMobi";
import stdParam from "./stdParam";
import throttle from "./throttle";
type T_debounce = {
    delay?: number,
    prevent?: boolean,
    auto?: boolean,
}
const debounce = (fn: any, options?: T_debounce | T_null | number) => {
    let dft = { delay: config.debounce, prevent: false, auto: false },
        opts: T_debounce = stdParam(options, dft, 'delay');
    if (isMobi && opts.auto) {
        return throttle(fn, { intvl: opts.delay, prevent: opts.prevent });
    } else {
        let timer: any = null,
            handler: any = function (this: any, e: any) {
                opts.prevent ? (e.stopPropagation(), e.preventDefault()) : null;
                timer ? clearTimeout(timer) : null;
                timer = setTimeout(() => {
                    fn.apply(this, arguments);
                }, opts.delay);
            }
        handler.cancel = () => {
            timer && clearTimeout(timer);
            return handler;
        };
        return handler;
    }
}
export default debounce;
