using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Peripherals.OscilloscopeClient;

namespace server.Controllers;

/// <summary>
/// 示波器API控制器 - 普通用户权限
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class OscilloscopeApiController : ControllerBase
{
    private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    private readonly Database.UserManager _userManager;

    public OscilloscopeApiController(Database.UserManager userManager)
    {
        _userManager = userManager;
    }

    /// <summary>
    /// 获取示波器实例
    /// </summary>
    private Oscilloscope? GetOscilloscope()
    {
        try
        {
            var userName = User.Identity?.Name;
            if (string.IsNullOrEmpty(userName))
                return null;

            var userRet = _userManager.GetUserByName(userName);
            if (!userRet.IsSuccessful || !userRet.Value.HasValue)
                return null;

            var user = userRet.Value.Value;
            if (user.BoardID == Guid.Empty)
                return null;

            var boardRet = _userManager.GetBoardByID(user.BoardID);
            if (!boardRet.IsSuccessful || !boardRet.Value.HasValue)
                return null;

            var board = boardRet.Value.Value;
            return new Oscilloscope(board.IpAddr, board.Port);
        }
        catch (Exception ex)
        {
            logger.Error(ex, "获取示波器实例时发生异常");
            return null;
        }
    }

    /// <summary>
    /// 初始化示波器
    /// </summary>
    /// <param name="config">示波器配置</param>
    /// <returns>操作结果</returns>
    [HttpPost("Initialize")]
    [EnableCors("Users")]
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> Initialize([FromBody] OscilloscopeFullConfig config)
    {
        try
        {
            if (config == null)
                return BadRequest("配置参数不能为空");

            if (config.HorizontalShift > 1023)
                return BadRequest("水平偏移量必须在0-1023之间");

            if (config.DecimationRate > 1023)
                return BadRequest("抽样率必须在0-1023之间");

            var oscilloscope = GetOscilloscope();
            if (oscilloscope == null)
                return BadRequest("用户未绑定有效的实验板");

            // 首先关闭捕获
            var stopResult = await oscilloscope.SetCaptureEnable(false);
            if (!stopResult.IsSuccessful)
            {
                logger.Error($"关闭捕获失败: {stopResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "关闭捕获失败");
            }

            // 设置触发电平
            var levelResult = await oscilloscope.SetTriggerLevel(config.TriggerLevel);
            if (!levelResult.IsSuccessful)
            {
                logger.Error($"设置触发电平失败: {levelResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置触发电平失败");
            }

            // 设置触发边沿
            var edgeResult = await oscilloscope.SetTriggerEdge(config.TriggerRisingEdge);
            if (!edgeResult.IsSuccessful)
            {
                logger.Error($"设置触发边沿失败: {edgeResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置触发边沿失败");
            }

            // 设置水平偏移量
            var shiftResult = await oscilloscope.SetHorizontalShift(config.HorizontalShift);
            if (!shiftResult.IsSuccessful)
            {
                logger.Error($"设置水平偏移量失败: {shiftResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置水平偏移量失败");
            }

            // 设置抽样率
            var rateResult = await oscilloscope.SetDecimationRate(config.DecimationRate);
            if (!rateResult.IsSuccessful)
            {
                logger.Error($"设置抽样率失败: {rateResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置抽样率失败");
            }

            // 刷新RAM
            if (config.AutoRefreshRAM)
            {
                var refreshResult = await oscilloscope.RefreshRAM();
                if (!refreshResult.IsSuccessful)
                {
                    logger.Error($"刷新RAM失败: {refreshResult.Error}");
                    return StatusCode(StatusCodes.Status500InternalServerError, "刷新RAM失败");
                }
            }

            // 设置捕获开关
            var captureResult = await oscilloscope.SetCaptureEnable(config.CaptureEnabled);
            if (!captureResult.IsSuccessful)
            {
                logger.Error($"设置捕获开关失败: {captureResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置捕获开关失败");
            }

            return Ok(true);
        }
        catch (Exception ex)
        {
            logger.Error(ex, "初始化示波器时发生异常");
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败，请稍后重试");
        }
    }

    /// <summary>
    /// 启动捕获
    /// </summary>
    /// <returns>操作结果</returns>
    [HttpPost("StartCapture")]
    [EnableCors("Users")]
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> StartCapture()
    {
        try
        {
            var oscilloscope = GetOscilloscope();
            if (oscilloscope == null)
                return BadRequest("用户未绑定有效的实验板");

            var result = await oscilloscope.SetCaptureEnable(true);
            if (!result.IsSuccessful)
            {
                logger.Error($"启动捕获失败: {result.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "启动捕获失败");
            }

            return Ok(result.Value);
        }
        catch (Exception ex)
        {
            logger.Error(ex, "启动捕获时发生异常");
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败，请稍后重试");
        }
    }

    /// <summary>
    /// 停止捕获
    /// </summary>
    /// <returns>操作结果</returns>
    [HttpPost("StopCapture")]
    [EnableCors("Users")]
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> StopCapture()
    {
        try
        {
            var oscilloscope = GetOscilloscope();
            if (oscilloscope == null)
                return BadRequest("用户未绑定有效的实验板");

            var result = await oscilloscope.SetCaptureEnable(false);
            if (!result.IsSuccessful)
            {
                logger.Error($"停止捕获失败: {result.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "停止捕获失败");
            }

            return Ok(result.Value);
        }
        catch (Exception ex)
        {
            logger.Error(ex, "停止捕获时发生异常");
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败，请稍后重试");
        }
    }

    /// <summary>
    /// 获取示波器数据和状态
    /// </summary>
    /// <returns>示波器数据和状态信息</returns>
    [HttpGet("GetData")]
    [EnableCors("Users")]
    [ProducesResponseType(typeof(OscilloscopeDataResponse), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> GetData()
    {
        try
        {
            var oscilloscope = GetOscilloscope();
            if (oscilloscope == null)
                return BadRequest("用户未绑定有效的实验板");

            var freqResult = await oscilloscope.GetADFrequency();
            var vppResult = await oscilloscope.GetADVpp();
            var maxResult = await oscilloscope.GetADMax();
            var minResult = await oscilloscope.GetADMin();
            var waveformResult = await oscilloscope.GetWaveformData();

            if (!freqResult.IsSuccessful)
            {
                logger.Error($"获取AD采样频率失败: {freqResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "获取AD采样频率失败");
            }

            if (!vppResult.IsSuccessful)
            {
                logger.Error($"获取AD采样幅度失败: {vppResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "获取AD采样幅度失败");
            }

            if (!maxResult.IsSuccessful)
            {
                logger.Error($"获取AD采样最大值失败: {maxResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "获取AD采样最大值失败");
            }

            if (!minResult.IsSuccessful)
            {
                logger.Error($"获取AD采样最小值失败: {minResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "获取AD采样最小值失败");
            }

            if (!waveformResult.IsSuccessful)
            {
                logger.Error($"获取波形数据失败: {waveformResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "获取波形数据失败");
            }

            var response = new OscilloscopeDataResponse
            {
                ADFrequency = freqResult.Value,
                ADVpp = vppResult.Value,
                ADMax = maxResult.Value,
                ADMin = minResult.Value,
                WaveformData = Convert.ToBase64String(waveformResult.Value)
            };

            return Ok(response);
        }
        catch (Exception ex)
        {
            logger.Error(ex, "获取示波器数据时发生异常");
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败，请稍后重试");
        }
    }

    /// <summary>
    /// 更新触发参数
    /// </summary>
    /// <param name="level">触发电平（0-255）</param>
    /// <param name="risingEdge">触发边沿（true为上升沿，false为下降沿）</param>
    /// <returns>操作结果</returns>
    [HttpPost("UpdateTrigger")]
    [EnableCors("Users")]
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> UpdateTrigger(byte level, bool risingEdge)
    {
        try
        {
            var oscilloscope = GetOscilloscope();
            if (oscilloscope == null)
                return BadRequest("用户未绑定有效的实验板");

            // 设置触发电平
            var levelResult = await oscilloscope.SetTriggerLevel(level);
            if (!levelResult.IsSuccessful)
            {
                logger.Error($"设置触发电平失败: {levelResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置触发电平失败");
            }

            // 设置触发边沿
            var edgeResult = await oscilloscope.SetTriggerEdge(risingEdge);
            if (!edgeResult.IsSuccessful)
            {
                logger.Error($"设置触发边沿失败: {edgeResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置触发边沿失败");
            }

            return Ok(true);
        }
        catch (Exception ex)
        {
            logger.Error(ex, "更新触发参数时发生异常");
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败，请稍后重试");
        }
    }

    /// <summary>
    /// 更新采样参数
    /// </summary>
    /// <param name="horizontalShift">水平偏移量（0-1023）</param>
    /// <param name="decimationRate">抽样率（0-1023）</param>
    /// <returns>操作结果</returns>
    [HttpPost("UpdateSampling")]
    [EnableCors("Users")]
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> UpdateSampling(ushort horizontalShift, ushort decimationRate)
    {
        try
        {
            if (horizontalShift > 1023)
                return BadRequest("水平偏移量必须在0-1023之间");

            if (decimationRate > 1023)
                return BadRequest("抽样率必须在0-1023之间");

            var oscilloscope = GetOscilloscope();
            if (oscilloscope == null)
                return BadRequest("用户未绑定有效的实验板");

            // 设置水平偏移量
            var shiftResult = await oscilloscope.SetHorizontalShift(horizontalShift);
            if (!shiftResult.IsSuccessful)
            {
                logger.Error($"设置水平偏移量失败: {shiftResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置水平偏移量失败");
            }

            // 设置抽样率
            var rateResult = await oscilloscope.SetDecimationRate(decimationRate);
            if (!rateResult.IsSuccessful)
            {
                logger.Error($"设置抽样率失败: {rateResult.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "设置抽样率失败");
            }

            return Ok(true);
        }
        catch (Exception ex)
        {
            logger.Error(ex, "更新采样参数时发生异常");
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败，请稍后重试");
        }
    }

    /// <summary>
    /// 手动刷新RAM
    /// </summary>
    /// <returns>操作结果</returns>
    [HttpPost("RefreshRAM")]
    [EnableCors("Users")]
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    public async Task<IActionResult> RefreshRAM()
    {
        try
        {
            var oscilloscope = GetOscilloscope();
            if (oscilloscope == null)
                return BadRequest("用户未绑定有效的实验板");

            var result = await oscilloscope.RefreshRAM();
            if (!result.IsSuccessful)
            {
                logger.Error($"刷新RAM失败: {result.Error}");
                return StatusCode(StatusCodes.Status500InternalServerError, "刷新RAM失败");
            }

            return Ok(result.Value);
        }
        catch (Exception ex)
        {
            logger.Error(ex, "刷新RAM时发生异常");
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败，请稍后重试");
        }
    }

    /// <summary>
    /// 示波器完整配置
    /// </summary>
    public class OscilloscopeFullConfig
    {
        /// <summary>
        /// 是否启动捕获
        /// </summary>
        public bool CaptureEnabled { get; set; }

        /// <summary>
        /// 触发电平（0-255）
        /// </summary>
        public byte TriggerLevel { get; set; }

        /// <summary>
        /// 触发边沿（true为上升沿，false为下降沿）
        /// </summary>
        public bool TriggerRisingEdge { get; set; }

        /// <summary>
        /// 水平偏移量（0-1023）
        /// </summary>
        public ushort HorizontalShift { get; set; }

        /// <summary>
        /// 抽样率（0-1023）
        /// </summary>
        public ushort DecimationRate { get; set; }

        /// <summary>
        /// 是否自动刷新RAM
        /// </summary>
        public bool AutoRefreshRAM { get; set; } = true;
    }

    /// <summary>
    /// 示波器状态和数据
    /// </summary>
    public class OscilloscopeDataResponse
    {
        /// <summary>
        /// AD采样频率
        /// </summary>
        public uint ADFrequency { get; set; }

        /// <summary>
        /// AD采样幅度
        /// </summary>
        public byte ADVpp { get; set; }

        /// <summary>
        /// AD采样最大值
        /// </summary>
        public byte ADMax { get; set; }

        /// <summary>
        /// AD采样最小值
        /// </summary>
        public byte ADMin { get; set; }

        /// <summary>
        /// 波形数据（Base64编码）
        /// </summary>
        public string WaveformData { get; set; } = string.Empty;
    }

}
