using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using QFrameworkCP;
using System;

namespace JXSoft { 
    public class UDPMangerArchitecture : Architecture<UDPMangerArchitecture>
    {
        protected override void Init()
        {
            this.RegisterUtility(new UDPUtility());
            this.RegisterModel(new UDPEventModel());
        }
    }
    public class UDPClientView : MonoBehaviour, IController
    {
        public UnityEvent onRecievedOpenDevice;
        public UnityEvent onUDPLinkSuccess;
        public UnityEvent onUDPLinkFaild;
        public UnityEvent onServerConnected;
        public UnityEvent onUDPReLink;

        private string UDPAddress;
        private int UDPPort;
        private int deviceId;
        // Start is called before the first frame update
        void Awake()
        {
            initUDPService();
            DontDestroyOnLoad(this);
        }

        public void initUDPService()
        {
            UDPAddress = "127.0.0.1";
            UDPPort = 20000;
            deviceId = 1;

            GetArchitecture().RegisterEvent<UDPStateChangedEvent>(e => {
                if (e.state == UDPLinkState.Linking)
                {
                    Debug.Log("UDP开始链接");
                    this.GetModel<UDPEventModel>().linkServer();
                }
                if (e.state == UDPLinkState.LinkSucess)
                {
                    Debug.Log("UDP链接成功");
                    this.GetModel<UDPEventModel>().onReceive<LinkSuccessResponse>();
                    this.GetModel<UDPEventModel>().sendRequestCommand(new LinkUDPRequest(deviceId));
                    onUDPLinkSuccess.Invoke();
                }
                if (e.state == UDPLinkState.LinkFaild)
                {
                    Debug.Log("UDP连接失败,请联系设备服务管理员");
                    onUDPLinkFaild.Invoke();
                }
            });

            GetArchitecture().RegisterEvent<ResponseMsgEvent>(e =>
            {
                if (e.res.GetType() == typeof(LinkSuccessResponse))
                {
                    Debug.Log("Link Server success");
                    this.GetModel<UDPEventModel>().offReceive<LinkSuccessResponse>();
                    onServerConnected.Invoke();
                }
            });

            this.GetModel<UDPEventModel>().setLinkState((int)UDPLinkState.NoIp);
            this.GetModel<UDPEventModel>().setIP(UDPAddress, UDPPort);
        }

        public void restartUDPService()
        {
            onUDPReLink.Invoke();
            this.GetModel<UDPEventModel>().closeServer();
            StartCoroutine(waitTwoSecond());
        }
        public IEnumerator waitTwoSecond()
        {
            yield return new WaitForSeconds(2.0f);
            this.GetModel<UDPEventModel>().setLinkState((int)UDPLinkState.Linking);
        }
        public IArchitecture GetArchitecture()
        {
            return UDPMangerArchitecture.Interface;
        }
    }


    public class LinkUDPRequest : IRequest
    {
        public string id;
        public int type;
        public LinkUDPRequest(int id)
        {
            this.id = id.ToString();
            this.type = 1;
        }
        public string toProtocolData()
        {
            return JsonUtility.ToJson(this);
        }
    }

}