using System.Net;
using Common;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using WebProtocol;

namespace server.Controllers;

/// <summary>
/// UDP API 
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class UDPController : ControllerBase
{
    private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    private const string LOCALHOST = "127.0.0.1";

    /// <summary>
    /// 页面
    /// </summary>
    [HttpGet]
    public string Index()
    {
        return "This is UDP Controller";
    }

    /// <summary>
    /// 发送字符串
    /// </summary>
    /// <param name="address">IPV4 或者 IPV6 地址</param>
    /// <param name="port">设备端口号</param>
    /// <param name="text">发送的文本</param>
    /// <response code="200">发送成功</response>
    /// <response code="500">发送失败</response>
    [HttpPost("SendString")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async ValueTask<IResult> SendString(string address = LOCALHOST, int port = 1234, string text = "Hello Server!")
    {
        var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
        var ret = await UDPClientPool.SendStringAsync(endPoint, [text]);

        if (ret) { return TypedResults.Ok(); }
        else { return TypedResults.InternalServerError(); }
    }

    /// <summary>
    /// 发送二进制数据
    /// </summary>
    /// <param name="address" example="127.0.0.1">IPV4 或者 IPV6 地址</param>
    /// <param name="port" example="1234">设备端口号</param>
    /// <param name="bytes" example="FFFFAAAA">16进制文本</param>
    [HttpPost("SendBytes")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async ValueTask<IResult> SendBytes(string address, int port, string bytes)
    {
        var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
        var ret = await UDPClientPool.SendBytesAsync(endPoint, Number.StringToBytes(bytes));

        if (ret) { return TypedResults.Ok(); }
        else { return TypedResults.InternalServerError(); }
    }


    /// <summary>
    /// 发送地址包
    /// </summary>
    /// <param name="address">IP地址</param>
    /// <param name="port">UDP 端口号</param>
    /// <param name="opts">地址包选项</param>
    [HttpPost("SendAddrPackage")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async ValueTask<IResult> SendAddrPackage(
        string address,
        int port,
        [FromBody] SendAddrPackOptions opts)
    {
        var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
        var ret = await UDPClientPool.SendAddrPackAsync(endPoint, new WebProtocol.SendAddrPackage(opts));

        if (ret) { return TypedResults.Ok(); }
        else { return TypedResults.InternalServerError(); }
    }

    /// <summary>
    /// 发送数据包
    /// </summary>
    /// <param name="address">IP地址</param>
    /// <param name="port">UDP 端口号</param>
    /// <param name="data">16进制数据</param>
    [HttpPost("SendDataPackage")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async ValueTask<IResult> SendDataPackage(string address, int port, string data)
    {
        var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
        var ret = await UDPClientPool.SendDataPackAsync(endPoint,
            new WebProtocol.SendDataPackage(Number.StringToBytes(data)));

        if (ret) { return TypedResults.Ok(); }
        else { return TypedResults.InternalServerError(); }
    }

    /// <summary>
    /// 获取指定IP地址接收的数据列表
    /// </summary>
    /// <param name="address">IP地址</param>
    /// <param name="taskID">任务ID</param>
    [HttpGet("GetRecvDataArray")]
    [ProducesResponseType(typeof(List<UDPData>), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public async ValueTask<IResult> GetRecvDataArray(string address, int taskID)
    {
        var ret = await MsgBus.UDPServer.GetDataArrayAsync(address, taskID);

        if (ret.HasValue)
        {
            var dataJson = JsonConvert.SerializeObject(ret.Value);
            logger.Debug($"Get Receive Successfully: {dataJson}");

            return TypedResults.Ok(ret.Value);
        }
        else
        {
            logger.Debug("Get Receive Failed");
            return TypedResults.InternalServerError();
        }
    }

}
