using System;
using System.Collections.Generic;
using System.Linq;
using Dapper;
using CncModels.Entity;
using CncModels.Dto;
using CncModels.Dto.Alert;
using CncRepository.Base;
using CncRepository.Interface;

namespace CncRepository.Impl
{
    public class AlertRepository : BusinessRepository, IAlertRepository
    {
        public AlertRepository(string connectionString) : base(connectionString) { }

        /// <summary>Alert SELECT列映射模板（snake_case列名 → PascalCase属性名）</summary>
        private const string SelectColumns = @"id as Id, alert_type as AlertType, machine_id as MachineId, collect_address_id as CollectAddressId, title as Title, detail as Detail, is_resolved as IsResolved, resolved_at as ResolvedAt, created_at as CreatedAt";

        public Alert GetById(long id)
        {
            using (var conn = CreateConnection())
            {
                string sql = $"SELECT {SelectColumns} FROM cnc_alert WHERE id = @Id";
                return conn.QuerySingleOrDefault<Alert>(sql, new { Id = id });
            }
        }

        public PagedResult<AlertListItem> GetList(AlertQuery query)
        {
            using (var conn = CreateConnection())
            {
                string sql = @"SELECT a.id AS Id, a.created_at AS CreatedAt, a.alert_type AS AlertType, a.title AS Title, m.name AS MachineName, a.detail AS Detail, a.is_resolved AS IsResolved, a.resolved_at AS ResolvedAt
                                FROM cnc_alert a LEFT JOIN cnc_machine m ON a.machine_id = m.id
                                WHERE 1=1";
                string countSql = @"SELECT COUNT(*) FROM cnc_alert a LEFT JOIN cnc_machine m ON a.machine_id = m.id WHERE 1=1";
                var p = new DynamicParameters();
                if (!string.IsNullOrEmpty(query.AlertType)) { sql += " AND a.alert_type = @AlertType"; countSql += " AND a.alert_type = @AlertType"; p.Add("AlertType", query.AlertType); }
                if (query.IsResolved.HasValue) { sql += " AND a.is_resolved = @IsResolved"; countSql += " AND a.is_resolved = @IsResolved"; p.Add("IsResolved", query.IsResolved.Value); }
                if (query.MachineId.HasValue) { sql += " AND a.machine_id = @MachineId"; countSql += " AND a.machine_id = @MachineId"; p.Add("MachineId", query.MachineId.Value); }
                if (query.StartDate.HasValue) { sql += " AND a.created_at >= @Start"; countSql += " AND a.created_at >= @Start"; p.Add("Start", query.StartDate.Value); }
                if (query.EndDate.HasValue) { sql += " AND a.created_at <= @End"; countSql += " AND a.created_at <= @End"; p.Add("End", query.EndDate.Value); }

                int offset = (query.Page - 1) * query.PageSize;
                sql += " ORDER BY a.created_at DESC LIMIT @Limit OFFSET @Offset";
                p.Add("Limit", query.PageSize);
                p.Add("Offset", offset);

                var items = conn.Query<AlertListItem>(sql, p).AsList();
                int total = conn.ExecuteScalar<int>(countSql, p);
                return new PagedResult<AlertListItem> { Items = items, Total = total, Page = query.Page, PageSize = query.PageSize };
            }
        }

        public long Create(Alert entity)
        {
            using (var conn = CreateConnection())
            {
                string sql = @"INSERT INTO cnc_alert (alert_type, machine_id, collect_address_id, title, detail, is_resolved, resolved_at, created_at)
                                VALUES (@AlertType, @MachineId, @CollectAddressId, @Title, @Detail, @IsResolved, @ResolvedAt, @CreatedAt); SELECT LAST_INSERT_ID();";
                return conn.ExecuteScalar<long>(sql, entity);
            }
        }

        public bool Resolve(long id)
        {
            using (var conn = CreateConnection())
            {
                string sql = "UPDATE cnc_alert SET is_resolved = 1, resolved_at = NOW() WHERE id = @Id";
                int affected = conn.Execute(sql, new { Id = id });
                return affected > 0;
            }
        }

        public int BatchResolve(List<long> ids)
        {
            using (var conn = CreateConnection())
            {
                string sql = "UPDATE cnc_alert SET is_resolved = 1, resolved_at = NOW() WHERE id IN @Ids";
                return conn.Execute(sql, new { Ids = ids });
            }
        }

        public AlertStatisticsResponse GetStatistics()
        {
            using (var conn = CreateConnection())
            {
                string sql = @"SELECT alert_type AS AlertType, COUNT(*) AS Count 
                               FROM cnc_alert WHERE is_resolved = 0 GROUP BY alert_type";
                var rows = conn.Query<AlertTypeCount>(sql).AsList();
                var dict = rows.ToDictionary(r => r.AlertType, r => r.Count);
                return new AlertStatisticsResponse
                {
                    UnresolvedCount = dict.Values.Sum(),
                    UnresolvedByType = dict
                };
            }
        }

        /// <summary>
        /// 告警类型计数内部类，用于Dapper映射
        /// </summary>
        private class AlertTypeCount
        {
            public string AlertType { get; set; }
            public int Count { get; set; }
        }
    }
}
