using System.Runtime.InteropServices;
using Serilog;
using Ayay.SerilogLogs;

namespace SHH.CameraSdk.DahuaFeatures;

/// <summary>
/// [大华功能组件] 时间同步实现
/// <para>参照原代码逻辑重构，实现 EM_DEV_CFG_TYPE.TIMECFG 配置下发</para>
/// </summary>
public class DahuaTimeSyncProvider : ITimeSyncFeature
{
    private readonly IDahuaContext _context;

    public DahuaTimeSyncProvider(IDahuaContext context)
    {
        _context = context;
    }

    /// <summary>
    /// 获取设备当前时间
    /// </summary>
    public async Task<DateTime> GetTimeAsync()
    {
        IntPtr loginId = _context.GetUserId();
        if (loginId == IntPtr.Zero) throw new InvalidOperationException("大华设备未登录");

        return await Task.Run(() =>
        {
            NET_TIME time = new NET_TIME();
            uint retLen = 0;
            int nSize = Marshal.SizeOf(typeof(NET_TIME));
            IntPtr inPtr = Marshal.AllocHGlobal(nSize);

            try
            {
                // Optimized: [原因] 沿用原代码的 GetDevConfig 逻辑与 TIMECFG 指令
                Marshal.StructureToPtr(time, inPtr, true);
                bool result = NETClient.GetDevConfig(loginId, EM_DEV_CFG_TYPE.TIMECFG, -1, inPtr, (uint)nSize, ref retLen, 5000);

                if (result && retLen == (uint)nSize)
                {
                    time = (NET_TIME)Marshal.PtrToStructure(inPtr, typeof(NET_TIME));
                    // 使用你现有的 ToDateTime() 扩展方法
                    return time.ToDateTime();
                }
                else
                {
                    string err = NETClient.GetLastError();
                    throw new Exception($"[SDK] Dahua 获取时间失败: {err}");
                }
            }
            finally
            {
                Marshal.FreeHGlobal(inPtr);
            }
        });
    }

    /// <summary>
    /// 设置设备时间 (校时)
    /// </summary>
    public async Task SetTimeAsync(DateTime targetTime)
    {
        IntPtr loginId = _context.GetUserId();
        if (loginId == IntPtr.Zero) throw new InvalidOperationException("大华设备未登录");

        await Task.Run(() =>
        {
            // Modified: [原因] 使用你原有的 FromDateTime 静态方法进行结构体转换
            NET_TIME time = NET_TIME.FromDateTime(targetTime);
            int nSize = Marshal.SizeOf(typeof(NET_TIME));
            IntPtr inPtr = Marshal.AllocHGlobal(nSize);

            try
            {
                Marshal.StructureToPtr(time, inPtr, true);

                // Optimized: [原因] 沿用原代码的 SetDevConfig 逻辑
                bool result = NETClient.SetDevConfig(loginId, EM_DEV_CFG_TYPE.TIMECFG, -1, inPtr, (uint)nSize, 5000);

                if (result)
                {
                    Log.ForContext("SourceContext", LogModules.DaHuaSdk)
                       .Information("[SDK] Dahua 校时成功 => {Time}", targetTime.ToString("yyyy-MM-dd HH:mm:ss"));
                }
                else
                {
                    string err = NETClient.GetLastError();
                    Log.ForContext("SourceContext", LogModules.DaHuaSdk)
                       .Error("[SDK] Dahua 校时指令失败. Error: {Error}", err);
                    throw new Exception($"大华校时失败: {err}");
                }
            }
            finally
            {
                Marshal.FreeHGlobal(inPtr);
            }
        });
    }
}