using MegaRobo.Connections.Adapters;
using MegaRobo.Connections.Sockets.Tcp;
using MegaRobo.Contract;
using MegaRobo.ControlDevices.Abstractions;
using MegaRobo.Logger;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MegaRobo.C00225155.ControlDevices.Scanner
{
    public abstract class ScannerCodeBase<TConnectorAdapter> : ConnectorBase<TConnectorAdapter>, IScannerCode where TConnectorAdapter : ConnectorAdapter
    {
        public string Code { get; protected set; }

        /// <summary>
        /// 开始的指令
        /// </summary>
        protected virtual string StartCommandLine { get; set; } = "Start";

        /// <summary>
        /// 停止指令
        /// </summary>
        protected virtual string StopCommandLine { get; set; } = "Stop";

        public virtual event EventHandler<string> ScannedEvent;
        public event EventHandler<TcpMessage> DataReceived;

        public override async Task<string> Initialize(ICoreService coreService, params object[] args)
        {
            try
            {
                this.CoreService = coreService;
                switch (args.Length)
                {
                    case >= 1 when args[0] is TConnectorAdapter connector:
                        this.ConnectorAdapter = connector;
                        break;
                }
                await this.ReconnectAsync();
                return null;
            }
            catch (Exception ex)
            {
                this.Logger.LogException(ex);
                return ex.Message;
            }
        }

        public abstract Task<string> ReadAsnyc(TimeSpan timeout);

        public virtual void Start()
        {
            byte[] sendBytes = this.ConnectorAdapter.StringEncoder.GetBytes(this.StartCommandLine);
            this.Write(sendBytes);
        }

        public virtual void Stop()
        {
            byte[] sendBytes = this.ConnectorAdapter.StringEncoder.GetBytes(this.StopCommandLine);
            this.Write(sendBytes);
        }

        protected virtual void Write(byte[] data)
        {
            try
            {
                switch (this.ConnectorAdapter)
                {
                    case MegaTcpClient megaTcpClient:
                        megaTcpClient.Connector.GetStream().Write(data, 0, data.Length);
                        break;
                        // case MegaTcpClientBase tcpClientBase:
                        //     tcpClientBase.Connector.Write(data);
                        //     break;
                        // case UdpClientBase udpClientBase:
                        //     udpClientBase.Connector.Send(data, data.Length);
                        //     break;
                        // case SerialPortBase serialPortBase:
                        //     serialPortBase.Connector.Write(data, 0, data.Length);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

        protected void OnScannedEvent(string code)
        {
            this.ScannedEvent?.Invoke(this, code);
        }

        protected virtual void OnDataReceived(object sender, TcpMessage msg)
        {
            this.DataReceived?.Invoke(sender, msg);
        }

        protected abstract string ParseMessage(object data, byte[] sourceData);
    }
}
