import {scrollRunningParams} from '../types/scroll';
import {ScrollConfig} from "../types/on";

import animate from "$utils/animate/animate";

export default class ScrollApi {

    // 锁
    private look:{time:number | undefined,params:scrollRunningParams} | undefined;

    constructor(private config:ScrollConfig,private el:Element) {}

    // 执行
    animateTo(params:scrollRunningParams){

        // 如果存在锁就清楚锁
        if (this.look !== undefined) {
            this.look.params.fail && this.look.params.fail(this.config);
            clearTimeout(this.look.time);
        }

        return this.animateToObservation(params);

    }

    animateToObservation(params:scrollRunningParams){

        let running = true;

        // 执行判定双轴
        if (params.x &&  this.config.x.x === params.x) {
            running = false;
        }
        if (params.y && this.config.y.y === params.y) {
            running = false;
        }

        return running && this.animateToTrigger(params);

    }

    animateToTrigger(params:scrollRunningParams){

        if (params.duration === undefined || params.duration<= 0) {
            this.animateToTriggerScroll(params);
            return params.complete &&  params.complete(this.config);
        } else {
            this.look = {
                time:undefined,
                params:params
            };
            return this.animateToPool(params,Math.ceil(params.duration / 16.66),1,JSON.parse(JSON.stringify(this.config)));
        }

    }

    animateToPool(params:scrollRunningParams,poolCount:number,poolIndex:number,config:ScrollConfig){

        let newParams:scrollRunningParams = {};
        if (params.x !== undefined) {
            newParams.x = animate[params.animate || 'linear'](0,poolIndex,0,params.x,poolCount)
        }

        if (params.y !== undefined) {
            newParams.y = animate[params.animate || 'linear'](0,poolIndex,0,params.y,poolCount)
        }

        this.animateToTriggerScroll(newParams,config);

        poolIndex++;
        if (poolIndex <= poolCount) {
            if (this.look) {
                // @ts-ignore
                this.look.time = setTimeout(()=> this.animateToPool(params,poolCount,poolIndex,config),16.66);
            }
        } else {
            params.complete &&  params.complete(config);
            this.look = undefined;
        }

    }

    // 执行
    animateToTriggerScroll(params:scrollRunningParams,config?:ScrollConfig){

        config = config || this.config;

        params.x !== undefined && config.x && this.animateToPoolRunning('x',config.x.x + params.x);
        return  params.y !== undefined && config.y && this.animateToPoolRunning('y',config.y.y +params.y);
    }

    // 设置值
    animateToPoolRunning(axis:'x' | 'y',value:number){

        let axisKey:'scrollLeft' | 'scrollTop' = axis === 'x' ? 'scrollLeft' :'scrollTop';
        this.el[axisKey] = value;
        if(this.config[axis] !== undefined) {
            // @ts-ignore
            this.config[axis][axis] = value;
        }
    }

    // 销毁
    destroy(){
        if (this.look !== undefined) {
            clearTimeout(this.look.time);
            this.look =undefined;
        }
    }

}