using BLW_Log.Models;
using Common;
using DAL.PGModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NLog;
using Npgsql; // 添加 Npgsql 引用
using System.Data.Common;
using System.Text.Json.Serialization;

namespace BLW_Log.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class DbInfoController : ControllerBase
    {
        private readonly PostgresContext dbContext;
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();

        public DbInfoController(PostgresContext db)
        {
            this.dbContext = db;
        }

        /// <summary>
        /// 获取历史日志
        /// </summary>
        [HttpPost]
        public async Task<ReturnInfo> GetHisLog([FromBody] HisLogQuery QueryData)
        {
            ReturnInfo info = new ReturnInfo { isok = true };

            try
            {
                // 验证输入参数
                if (QueryData == null)
                {
                    info.isok = false;
                    info.message = "查询参数不能为空";
                    return info;
                }

                // 解析时间参数
                if (!DateTime.TryParse(QueryData.Start_Time, out DateTime sst))
                {
                    info.isok = false;
                    info.message = "开始时间格式无效";
                    return info;
                }

                if (!DateTime.TryParse(QueryData.End_Time, out DateTime eet))
                {
                    info.isok = false;
                    info.message = "结束时间格式无效";
                    return info;
                }

                // 验证时间范围
                if (eet < sst)
                {
                    info.isok = false;
                    info.message = "结束时间不能小于开始时间";
                    return info;
                }

                long l1 = Tools.ToUnixTimestampByMilliseconds(sst);
                long l2 = Tools.ToUnixTimestampByMilliseconds(eet);
                // 构建 SQL 查询（添加实际时间过滤条件）
                string sql = $"""
                    SELECT "Room","count"("Room") 
                    FROM "public"."{QueryData.HotelCode}_Rooms" 
                    WHERE "LoopAddr" <> '000000000' AND "RcuStatus" = TRUE AND "ModuleStopTime" BETWEEN {l1} AND {l2} 
                    GROUP BY "Room";
                    """;
                string sql0 = $"""
                    SELECT "Room","count"("Room") 
                    FROM "public"."{QueryData.HotelCode}_Rooms" 
                    WHERE "LoopAddr" = '000000000' AND "RcuStatus" = FALSE AND "ModuleStopTime" BETWEEN {l1} AND {l2} 
                    GROUP BY "Room";
                    """;
                string sql1 = $"""
                    SELECT "Room","count"("Room") 
                    FROM "public"."{QueryData.HotelCode}_Rooms" 
                    WHERE "ModuleStopTime" BETWEEN {l1} AND {l2} 
                    GROUP BY "Room";
                    """;
                string sql2 = $"""
                    SELECT "Room", "count" ("Room") 
                    FROM "public"."{QueryData.HotelCode}_Rooms" 
                    WHERE "ModuleStopTime" BETWEEN {l1} AND {l2} AND "StateTyp" IN('6','7','8') AND "RcuStatus" = TRUE 
                    GROUP BY "Room";
                    """;
                string sql3 = $"""
                    SELECT "Room", "count" ("Room") 
                    FROM "public"."{QueryData.HotelCode}_Rooms" 
                    WHERE "ModuleStopTime" BETWEEN {l1} AND {l2} AND "StateTyp" IN('2','3','4','5') AND "RcuStatus" = TRUE 
                    GROUP BY "Room";
                    """;

                // 使用 ADO.NET 方式执行查询

                var results = ExecuteSqlQuery(sql);
                var results0 = ExecuteSqlQuery(sql0);
                var results1 = ExecuteSqlQuery(sql1);
                var results2 = ExecuteSqlQuery(sql2);
                var results3 = ExecuteSqlQuery(sql3);



                List<CountTongJi> lll = [];

                foreach (Dictionary<string, object> item in results)
                {
                    string? RoomNUM = item["Room"]?.ToString();
                    string? Count = item["count"]?.ToString();

                    var q0 = results0.FirstOrDefault(A => A["Room"].ToString().Equals(RoomNUM));
                    var q1 = results1.FirstOrDefault(A => A["Room"].ToString().Equals(RoomNUM));
                    var q2 = results2.FirstOrDefault(A => A["Room"].ToString().Equals(RoomNUM));
                    var q3 = results3.FirstOrDefault(A => A["Room"].ToString().Equals(RoomNUM));

                    string? Count0 = q0?["count"]?.ToString() ?? "0";
                    string? Count1 = q1?["count"]?.ToString() ?? "0";
                    string? Count2 = q2?["count"]?.ToString() ?? "0";
                    string? Count3 = q3?["count"]?.ToString() ?? "0";

                    CountTongJi c = new()
                    {
                        RoomNum = RoomNUM,
                        CountErr = Count,
                        CountOff = Count0,
                        CountAll = Count1,
                        CountDoor = Count2,
                        CountLeida = Count3
                    };
                    lll.Add(c);
                }
                info.isok = true;
                info.response = lll;
                info.message = "查询成功";
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "获取历史日志失败");
                info.isok = false;
                info.message = $"查询失败: {ex.Message}";
            }
            return info;
        }

        public class CountTongJi
        {
            public string? RoomNum { get; set; }
            public string? CountErr { get; set; }
            public string? CountOff { get; set; }
            public string? CountAll { get; set; }
            public string? CountDoor { get; set; }
            public string? CountLeida { get; set; }
        }


        /// <summary>
        /// 获取离线日志
        /// </summary>
        [HttpPost]
        public ReturnInfo GetOfflineLog([FromBody] HisLogQuery QueryData)
        {
            ReturnInfo info = new ReturnInfo { isok = true };

            try
            {
                // 验证输入参数
                if (QueryData == null)
                {
                    info.isok = false;
                    info.message = "查询参数不能为空";
                    return info;
                }

                // 解析时间参数
                if (!DateTime.TryParse(QueryData.Start_Time, out DateTime sst))
                {
                    info.isok = false;
                    info.message = "开始时间格式无效";
                    return info;
                }

                if (!DateTime.TryParse(QueryData.End_Time, out DateTime eet))
                {
                    info.isok = false;
                    info.message = "结束时间格式无效";
                    return info;
                }

                // 验证时间范围
                if (eet < sst)
                {
                    info.isok = false;
                    info.message = "结束时间不能小于开始时间";
                    return info;
                }

                long l1 = Tools.ToUnixTimestampByMilliseconds(sst);
                long l2 = Tools.ToUnixTimestampByMilliseconds(eet);
                // 构建 SQL 查询（添加实际时间过滤条件）
                string sql = $"""
                    SELECT "Room","count"("Room") 
                    FROM "public"."{QueryData.HotelCode}_Rooms" 
                    WHERE "LoopAddr" = '000000000' AND "RcuStatus" = FALSE AND "ModuleStopTime" BETWEEN {l1} AND {l2} 
                    GROUP BY "Room";
                    """;
                // 注意：实际表结构可能不同，请修改create_time为实际时间字段

                // 使用 ADO.NET 方式执行查询
                var results = ExecuteSqlQuery(sql);

                info.isok = true;
                info.response = results;
                info.message = "查询成功";
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "获取历史日志失败");
                info.isok = false;
                info.message = $"查询失败: {ex.Message}";
            }
            return info;
        }

        /// <summary>
        /// 获取房间日志
        /// </summary>
        [HttpPost]
        public ReturnInfo GetRoomLog([FromBody] RoomLogQuery QueryData)
        {
            ReturnInfo info = new ReturnInfo { isok = true };

            try
            {
                // 验证输入参数
                if (QueryData == null)
                {
                    info.isok = false;
                    info.message = "查询参数不能为空";
                    return info;
                }

                // 解析时间参数
                if (!DateTime.TryParse(QueryData.Start_Time, out DateTime sst))
                {
                    info.isok = false;
                    info.message = "开始时间格式无效";
                    return info;
                }

                if (!DateTime.TryParse(QueryData.End_Time, out DateTime eet))
                {
                    info.isok = false;
                    info.message = "结束时间格式无效";
                    return info;
                }

                // 验证时间范围
                if (eet < sst)
                {
                    info.isok = false;
                    info.message = "结束时间不能小于开始时间";
                    return info;
                }

                long l1 = Tools.ToUnixTimestampByMilliseconds(sst);
                long l2 = Tools.ToUnixTimestampByMilliseconds(eet);
                // 构建 SQL 查询（添加实际时间过滤条件）
                string sql = $"""
                    SELECT
                        * 
                    FROM
                        "public"."{QueryData.HotelCode}_Rooms" 
                    WHERE
                        "LoopAddr" <> '000000000' 
                        AND "Room" = '{QueryData.RoomNum}' 
                        AND "ModuleStopTime" BETWEEN {l1} AND {l2} 
                        AND "RcuStatus" = TRUE;
                    """;
                // 注意：实际表结构可能不同，请修改create_time为实际时间字段

                // 使用 ADO.NET 方式执行查询
                var results = ExecuteSqlQuery(sql);

                info.isok = true;
                info.response = results;
                info.message = "查询成功";
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "获取历史日志失败");
                info.isok = false;
                info.message = $"查询失败: {ex.Message}";
            }
            return info;
        }
        /// <summary>
        /// 获取房间日志
        /// </summary>
        [HttpPost]
        public ReturnInfo GetRoomOffOnLineLog([FromBody] RoomLogQuery QueryData)
        {
            ReturnInfo info = new ReturnInfo { isok = true };

            try
            {
                // 验证输入参数
                if (QueryData == null)
                {
                    info.isok = false;
                    info.message = "查询参数不能为空";
                    return info;
                }

                // 解析时间参数
                if (!DateTime.TryParse(QueryData.Start_Time, out DateTime sst))
                {
                    info.isok = false;
                    info.message = "开始时间格式无效";
                    return info;
                }

                if (!DateTime.TryParse(QueryData.End_Time, out DateTime eet))
                {
                    info.isok = false;
                    info.message = "结束时间格式无效";
                    return info;
                }

                // 验证时间范围
                if (eet < sst)
                {
                    info.isok = false;
                    info.message = "结束时间不能小于开始时间";
                    return info;
                }

                long l1 = Tools.ToUnixTimestampByMilliseconds(sst);
                long l2 = Tools.ToUnixTimestampByMilliseconds(eet);
                // 构建 SQL 查询（添加实际时间过滤条件）
                string sql = $"""
                    SELECT
                        * 
                    FROM
                        "public"."{QueryData.HotelCode}_SimplificationLogs" 
                    WHERE
                        "Room" = '{QueryData.RoomNum}' 
                        AND "Address" = '000000000' 
                        AND "TimeStamp" BETWEEN {l1} AND {l2}
                    ORDER BY
                        "TimeStamp"
                    """;
                // 注意：实际表结构可能不同，请修改create_time为实际时间字段

                // 使用 ADO.NET 方式执行查询
                var results = ExecuteSqlQuery(sql);

                info.isok = true;
                info.response = results;
                info.message = "查询成功";
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "获取历史日志失败");
                info.isok = false;
                info.message = $"查询失败: {ex.Message}";
            }
            return info;
        }
        /// <summary>
        /// 获取回路日志
        /// </summary>
        [HttpPost]
        public ReturnInfo GetAddressLog([FromBody] AddressLogQuery QueryData)
        {
            ReturnInfo info = new ReturnInfo { isok = true };

            try
            {
                // 验证输入参数
                if (QueryData == null)
                {
                    info.isok = false;
                    info.message = "查询参数不能为空";
                    return info;
                }

                // 解析时间参数
                if (!DateTime.TryParse(QueryData.Start_Time, out DateTime sst))
                {
                    info.isok = false;
                    info.message = "开始时间格式无效";
                    return info;
                }

                if (!DateTime.TryParse(QueryData.End_Time, out DateTime eet))
                {
                    info.isok = false;
                    info.message = "结束时间格式无效";
                    return info;
                }

                // 验证时间范围
                if (eet < sst)
                {
                    info.isok = false;
                    info.message = "结束时间不能小于开始时间";
                    return info;
                }

                long l1 = Tools.ToUnixTimestampByMilliseconds(sst);
                long l2 = Tools.ToUnixTimestampByMilliseconds(eet);
                // 构建 SQL 查询（添加实际时间过滤条件）
                string sql = $"""
                    SELECT
                        * 
                    FROM
                        "public"."{QueryData.HotelCode}_SimplificationLogs" 
                    WHERE
                        "Room" = '{QueryData.RoomNum}' 
                        AND "Address" = '{QueryData.Address}' 
                        AND "TimeStamp" BETWEEN {l1} AND {l2}  
                    ORDER BY
                        "TimeStamp" ;
                    """;
                // 注意：实际表结构可能不同，请修改create_time为实际时间字段

                // 使用 ADO.NET 方式执行查询
                var results = ExecuteSqlQuery(sql);

                info.isok = true;
                info.response = results;
                info.message = "查询成功";
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "获取历史日志失败");
                info.isok = false;
                info.message = $"查询失败: {ex.Message}";
            }
            return info;
        }


        /// <summary>
        /// 获取问题清单
        /// </summary>
        [HttpPost]
        public ReturnInfo GetIssueList()
        {
            ReturnInfo info = new ReturnInfo { isok = true };

            try
            {
                // 构建 SQL 查询（添加实际时间过滤条件）
                string sql = $"""
                    SELECT * 
                    FROM "public"."Log_Filter_Rule";
                    """;
                // 使用 ADO.NET 方式执行查询
                var results = ExecuteSqlQuery(sql);

                info.isok = true;
                info.response = results;
                info.message = "查询成功";
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "获取历史日志失败");
                info.isok = false;
                info.message = $"查询失败: {ex.Message}";
            }
            return info;
        }
        /// <summary>
        /// 执行原始 SQL 查询并返回结果
        /// </summary>
        private List<Dictionary<string, object>> ExecuteSqlQuery(string sql)
        {
            var results = new List<Dictionary<string, object>>();

            var connection = dbContext.Database.GetDbConnection();
            if (connection.State != System.Data.ConnectionState.Open)
            {
                connection.Open();
            }


            using (var command = connection.CreateCommand())
            {
                command.CommandText = sql;
                command.CommandTimeout = 30; // 30秒超时

                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var row = new Dictionary<string, object>();

                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            string columnName = reader.GetName(i);
                            object value = reader.IsDBNull(i) ? null : reader.GetValue(i);
                            row.Add(columnName, value);
                        }

                        results.Add(row);
                    }
                }
            }


            return results;
        }
    }

    /// <summary>
    /// 查询参数类
    /// </summary>
    public class HisLogQuery
    {
        [JsonPropertyName("hotelCode")]
        public string HotelCode { get; set; }

        [JsonPropertyName("start_time")]
        public string Start_Time { get; set; }

        [JsonPropertyName("end_time")]
        public string End_Time { get; set; }
    }

    public class RoomLogQuery : HisLogQuery
    {
        [JsonPropertyName("roomnum")]
        public string RoomNum { get; set; }
    }

    public class AddressLogQuery : RoomLogQuery
    {
        [JsonPropertyName("address")]
        public string Address { get; set; }
    }

    public class Emp
    {
        public string? em { get; set; }
    }

}