import { ref,reactive } from "vue";
import WebSocketClient from "./WebSocketClient";
import ReflectSeviceClientAssistant from "./ReflectSeviceClientAssistant";
import EventEmitter from "EventEmitter";

/** abstract */
export default class Reflect_SeviceClient extends WebSocketClient{
 
    constructor(){
        super();
        //-----------------------------------------------------------------
        // public

        /**
         * @description 已经同步完成;已经收到了 CALL_GetAllProperties, 全部属性都与服务器一致;
         * @type bool
         */
        this.IsSynced = ref(false);

        /**
         * @description 当前 INotifyPropertyChanged 对象 引发了 PropertyChanged,  是由于 接收到数据导致的
         * @type bool
         */
        this.IsInPushValue = false;

        this.Data = reactive({});
        this.EventEmitter = new EventEmitter();

        //-----------------------------------------------------------------
        // private
        /**
         * @description 
         * @type ReflectSeviceClientAssistant
         */
        this._assistant = new ReflectSeviceClientAssistant();
    }

    //#region public
    Init(serverName, addr){
        super.Init(serverName,addr);
        this._assistant.Init(this, (data)=>this.send(data));
    }
    /**
     * @description 获取属性
     * @param {string} nodePath 节点
     * @param {(asyncContext:object,retData:object)=>void} asyncDelegate 回调
     * @param {object} asyncContext 上下文
     */
    GetValue(nodePath=null,asyncDelegate=null,asyncContext=null){
        this._assistant.GetValue(nodePath,asyncDelegate,asyncContext);
    }
    /**
     * @description 获取属性 同步版
     * @param {string} nodePath 节点
     */
    async SyncGetValue(nodePath=null){
        return await new Promise((resolve)=>{
            this.GetValue(
                nodePath
                , (context,retData)=>{
                    context(retData);
                },resolve );
        });
    }
    /**
     * @description 设置属性
     * @param {object} value 属性值
     * @param {string} nodePath 节点
     * @param {(asyncContext:object,retData:object)=>void} asyncDelegate 回调
     * @param {object} asyncContext 上下文
     */   
    SetValue(value,nodePath=null,asyncDelegate=null,asyncContext=null){
        this._assistant.SetValue(value,nodePath,asyncDelegate,asyncContext);
    }
    /**
     * @description 设置属性 同步版
     * @param {object} value 属性值
     * @param {string} nodePath 节点
     */
    async SyncSetValue(value,nodePath=null){
        return await new Promise((resolve)=>{
            this.SetValue(
                value, nodePath
                , (context,retData)=>{
                    context(retData);
                },resolve );
        });
    }
    /**
     * @description 远程方法调用
     * @param {string} methodName 方法名
     * @param {object} parameters 参数
     * @param {(asyncContext:object,retData:object)=>void} asyncDelegate 回调
     * @param {object} asyncContext 上下文
     */
    Call(methodName, parameters=null, asyncDelegate=null, asyncContext=null){
        this._assistant.Call(methodName, parameters, asyncDelegate, asyncContext);
    }

    /**
     * @description 远程方法调用 同步版
     * @param {string} methodName 方法名
     * @param {object} parameters 参数
     */
    async SyncCall(methodName, parameters=null){
        return await new Promise((resolve)=>{
            this.Call(
                methodName, parameters
                , (context,retData)=>{
                    context(retData);
                },resolve );
        });
    }

    //#endregion
    

    //#region protected override
    onOpen(){
        this._assistant.OnOpen();
    }
    onMessage(data){
        this._assistant.OnMessage(data);
    }

    onClose(){
        this._assistant.OnClose();
    }
    //#endregion

    //#region protected

    //#endregion
}