import { MainMustardApp, IAppStatus, IAppStatusCN, MustardName } from '@typings';
import { isFunction, isIAppStatusKey } from '../utils/tools';
import { TDataChangeCallback, TLifeCallback, BindMethod, EventCenter, TCallback, getEventLifeKeyByValue, getEventBindKey, getEventDataChangeKey, getEventDataKey, getEventGlobalDataChangeKey, getEventGlobalLifeKeyByValue, getEventLifeKeyByKey } from './base';

export { getEventLifeKeyByValue, getEventBindKey, getEventDataChangeKey, getEventDataKey, getEventGlobalDataChangeKey, getEventGlobalLifeKeyByValue, getEventLifeKeyByKey };

// 订阅实例
const eventCenter = new EventCenter();

// 全局事件配置注册
type TGlobalEventConfigKeys = IAppStatusCN|'dataChange';

export function setGlobalEvents (options:Partial<Record<IAppStatusCN, TLifeCallback>>|Partial< Record<'dataChange', TDataChangeCallback>>) {
    (Reflect.ownKeys(options) as TGlobalEventConfigKeys[]).forEach(key => {
        if(isFunction(options[key])) {
            if(key === 'dataChange') {
                eventCenter.off(getEventGlobalDataChangeKey());
                eventCenter.on(getEventGlobalDataChangeKey(), options[key]);
            }else if(isIAppStatusKey(key)) {
                eventCenter.off(getEventGlobalLifeKeyByValue(key));
                eventCenter.on(getEventGlobalLifeKeyByValue(key), options[key]);
            }
        }
    });
}

export function globalDataChangeDispatch (name: MustardName, data:unknown) {
    eventCenter.dispatch(getEventGlobalDataChangeKey(), name, data);
    
}
export function globalLifeDispatch (key:IAppStatusCN, name: MustardName) {
    eventCenter.dispatch(getEventGlobalLifeKeyByValue(key), name);
   
}

// 基座通讯集合
export class EventCenterBaseApp {
    
    /**
     * 向子应用发送data数据
     * @param name 子应用名字
     * @param data 发送数据
     */
    dispatch (name:MustardName, data:unknown) {
        eventCenter.dispatch(getEventDataKey(name), MainMustardApp, data);
    }

    /**
     * 订阅props修改事件
     * @param name 子应用名字
     * @param fn 事件
     */
    onData (name:MustardName, fn: TCallback) {
        eventCenter.on(getEventDataChangeKey(name), fn);
    }

    /**
     * 订阅生命事件
     * @param name 子应用名字
     * @param life 生命周期映射
     * @param fn 事件
     */
    onLife (name:MustardName, life:IAppStatusCN, fn: TCallback) {
        eventCenter.on(getEventLifeKeyByKey(name, life), fn);
    }

    /**
     * 订阅自定义事件
     * @param name 子应用名字
     * @param method 自定义方法名
     * @param fn 事件
     */
    onCustomize (name:MustardName, method:BindMethod, fn: TCallback) {
        eventCenter.on(getEventBindKey(name, method), fn);
    }

    /**
     * 取消订阅生命事件
     * @param name 子应用名字
     * @param fn 事件
     */
    offData (name:MustardName, fn: TCallback) {
        eventCenter.off(getEventDataChangeKey(name), fn);
    }

    /**
     * 取消订阅生命事件
     * @param name 子应用名字
     * @param life 生命周期映射
     * @param fn 事件
     */
    offLife (name:MustardName, life:IAppStatusCN, fn: TCallback) {
        eventCenter.off(getEventLifeKeyByKey(name, life), fn);
    }

    /**
     * 取消订阅自定义事件
     * @param name 子应用名字
     * @param method 自定义方法名
     * @param fn 事件
     */
    offCustomize (name:MustardName, method:BindMethod, fn: TCallback) {
        eventCenter.off(getEventBindKey(name, method), fn);
    }
}

// 子应用通讯类（注入到子应用的window.microApp）
export class EventCenterMicroApp {
    name:MustardName;

    constructor (name:MustardName) {
        this.name = name;
    }
    
    // 添加data事件监听
    addDataListener (fn:TCallback) {
        eventCenter.on(getEventDataKey(this.name), fn, { immediately: true, repeatSend: true });
    }

    // 解除data监听
    removeDataListener (fn:TCallback) {
        fn && eventCenter.off(getEventDataKey(this.name), fn);
    }
    
    // 解除所以的data监听事件
    clearDateListener () {
        eventCenter.off(getEventDataKey(this.name));
    }

    /**
     * 发送data数据修改事件
     * @param data 发送数据
     */
    dispatch (data:unknown) {
        globalDataChangeDispatch(this.name, data);
        eventCenter.dispatch(getEventDataChangeKey(this.name), this.name, data);
    }

    /**
     * 发送自定义事件
     * @param method 
     */
    dispatchCustomize (method:BindMethod, data:unknown) {
        eventCenter.dispatch(getEventBindKey(this.name, method), this.name, data);
    }
}

// 子应用生命周期通讯类（内部调用）
export class EventCenterMicorLife {
    private name:MustardName;

    constructor (name:MustardName) {
        this.name = name;
    }
    
    /**
     * 发送生命周期
     * @param state 子应用的生命周期
     */
    public dispatchLife (state:IAppStatus) {
        globalLifeDispatch(IAppStatus[state] as IAppStatusCN, this.name);
        eventCenter.dispatch(getEventLifeKeyByValue(this.name, state), this.name);
    }
}