using Serilog;

namespace SHH.CameraSdk.HikFeatures;

public class HikPtzProvider : IPtzFeature
{
    private readonly IHikContext _context;

    public HikPtzProvider(IHikContext context)
    {
        _context = context;
    }

    /// <summary>
    /// 判断该动作是否支持速度参数
    /// </summary>
    private static bool IsSpeedSupported(PtzAction action)
    {
        // Optimized: 方向和缩放支持速度，其余(雨刷/聚焦/光圈)为开关量或标准调节
        return action <= PtzAction.ZoomOut;
    }

    public async Task PtzControlAsync(PtzAction action, bool stop, int speed)
    {
        int userId = _context.GetUserId();
        if (userId < 0) throw new InvalidOperationException("设备离线");

        // 1. 映射指令
        uint hikCommand = action switch
        {
            PtzAction.Left => HikNativeMethods.PAN_LEFT,
            PtzAction.Up => HikNativeMethods.TILT_UP,
            PtzAction.Right => HikNativeMethods.PAN_RIGHT,
            PtzAction.Down => HikNativeMethods.TILT_DOWN,
            
            PtzAction.LeftUp => HikNativeMethods.UP_LEFT,         // 海康 SDK: 左上
            PtzAction.LeftDown => HikNativeMethods.DOWN_LEFT,     // 海康 SDK: 左下
            PtzAction.RightUp => HikNativeMethods.UP_RIGHT,       // 海康 SDK: 右上
            PtzAction.RightDown => HikNativeMethods.DOWN_RIGHT,   // 海康 SDK: 右下

            PtzAction.Auto => HikNativeMethods.PAN_AUTO,

            PtzAction.ZoomIn => HikNativeMethods.ZOOM_IN,
            PtzAction.ZoomOut => HikNativeMethods.ZOOM_OUT,
            PtzAction.FocusNear => HikNativeMethods.FOCUS_NEAR,
            PtzAction.FocusFar => HikNativeMethods.FOCUS_FAR,
            PtzAction.IrisOpen => HikNativeMethods.IRIS_OPEN,
            PtzAction.IrisClose => HikNativeMethods.IRIS_CLOSE,
            PtzAction.Wiper => HikNativeMethods.WIPER_PWRON,
            _ => 0
        };

        if (hikCommand == 0) return;

        // 2. 转换停止标志 (海康: 0=开始, 1=停止)
        uint dwStop = stop ? 1u : 0u;

        // 3. 调用 SDK
        await Task.Run(() =>
        {
            bool result;
            // Optimized: 接口分流逻辑，确保不同类型的动作调用正确的 SDK 接口
            if (IsSpeedSupported(action))
            {
                uint dwSpeed = (uint)Math.Clamp(speed, 1, 7);
                result = HikNativeMethods.NET_DVR_PTZControlWithSpeed_Other(userId, 1, hikCommand, dwStop, dwSpeed);
            }
            else
            {
                // 对于雨刷、聚焦、光圈，使用不带速度的接口
                result = HikNativeMethods.NET_DVR_PTZControl_Other(userId, 1, hikCommand, dwStop);
            }

            if (!result)
            {
                // Modified: 统一记录到 D:\Logs
                uint errorCode = HikNativeMethods.NET_DVR_GetLastError();
                Log.Warning("Ayay.AiVideo: PTZ {Action} failed. Stop: {Stop}, ErrorCode: {ErrorCode}",
                    action, stop, errorCode);
            }
        });
    }

    public async Task PtzStepAsync(PtzAction action, int durationMs, int speed)
    {
        // 1. 开始转动 (调用已有的逻辑，stop=false)
        await PtzControlAsync(action, false, speed);

        // 2. 等待指定时间 (非阻塞等待)
        // 注意：这里使用 Task.Delay，精度对云台控制来说足够了
        if (durationMs > 0)
        {
            await Task.Delay(durationMs);
        }

        // 3. 停止转动 (调用已有的逻辑，stop=true)
        await PtzControlAsync(action, true, speed);
    }
}