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

namespace CncRepository.Impl.Log
{
    /// <summary>
    /// 采集分析仓储实现（日志库 - log_collect_analysis）
    /// </summary>
    public class CollectAnalysisRepository : LogRepository, ICollectAnalysisRepository
    {
        public CollectAnalysisRepository(string connectionString) : base(connectionString) { }

        public PagedResult<CollectAnalysisListItem> GetAnalysisList(CollectAnalysisQuery query)
        {
            using (var conn = CreateConnection())
            {
                var whereParts = new List<string> { "1=1" };
                var p = new DynamicParameters();

                if (query.StartDate.HasValue)
                {
                    whereParts.Add("a.analysis_time >= @StartDate");
                    p.Add("StartDate", query.StartDate);
                }
                if (query.EndDate.HasValue)
                {
                    whereParts.Add("a.analysis_time <= @EndDate");
                    p.Add("EndDate", query.EndDate);
                }
                if (query.CollectAddressId.HasValue)
                {
                    whereParts.Add("a.collect_address_id = @CollectAddressId");
                    p.Add("CollectAddressId", query.CollectAddressId);
                }
                if (query.MachineId.HasValue)
                {
                    whereParts.Add("a.machine_id = @MachineId");
                    p.Add("MachineId", query.MachineId);
                }
                if (!string.IsNullOrEmpty(query.AnalysisType))
                {
                    whereParts.Add("a.analysis_type = @AnalysisType");
                    p.Add("AnalysisType", query.AnalysisType);
                }
                if (!string.IsNullOrEmpty(query.ProgramName))
                {
                    whereParts.Add("a.current_program LIKE CONCAT('%', @ProgramName, '%')");
                    p.Add("ProgramName", query.ProgramName);
                }

                var whereSql = string.Join(" AND ", whereParts);

                // 统计总条数
                var total = conn.ExecuteScalar<int>(
                    $"SELECT COUNT(1) FROM log_collect_analysis a WHERE {whereSql}", p);

                // 分页查询（左连机床表获取名称）
                var dataSql = $@"SELECT
                        a.id AS Id,
                        DATE_FORMAT(a.analysis_time, '%Y-%m-%d %H:%i:%s') AS AnalysisTime,
                        a.collect_address_id AS CollectAddressId,
                        a.machine_id AS MachineId,
                        NULL AS MachineName,
                        a.analysis_type AS AnalysisType,
                        a.previous_program AS PreviousProgram,
                        a.current_program AS CurrentProgram,
                        a.part_count_delta AS PartCountDelta,
                        a.analysis_summary AS AnalysisSummary
                    FROM log_collect_analysis a
                    WHERE {whereSql}
                    ORDER BY a.analysis_time DESC
                    LIMIT @PageSize OFFSET @Offset";

                var items = conn.Query<CollectAnalysisListItem>(dataSql,
                    new { PageSize = query.PageSize, Offset = query.Offset }).AsList();

                return new PagedResult<CollectAnalysisListItem>
                {
                    Items = items,
                    Total = total,
                    Page = query.Page,
                    PageSize = query.PageSize
                };
            }
        }

        public CollectAnalysisDetail GetAnalysisDetail(long id)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"SELECT
                        a.id AS Id,
                        DATE_FORMAT(a.analysis_time, '%Y-%m-%d %H:%i:%s') AS AnalysisTime,
                        a.collect_address_id AS CollectAddressId,
                        a.machine_id AS MachineId,
                        NULL AS MachineName,
                        a.analysis_type AS AnalysisType,
                        a.previous_program AS PreviousProgram,
                        a.current_program AS CurrentProgram,
                        a.part_count_delta AS PartCountDelta,
                        a.previous_part_count AS PreviousPartCount,
                        a.current_part_count AS CurrentPartCount,
                        a.previous_status AS PreviousStatus,
                        a.current_status AS CurrentStatus,
                        a.analysis_summary AS AnalysisSummary,
                        a.analysis_detail AS AnalysisDetail,
                        a.raw_log_id AS RawLogId
                    FROM log_collect_analysis a
                    WHERE a.id = @Id";
                return conn.QueryFirstOrDefault<CollectAnalysisDetail>(sql, new { Id = id });
            }
        }

        public List<CollectAnalysisListItem> GetAnalysisByRawLogId(long rawLogId)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"SELECT
                        a.id AS Id,
                        DATE_FORMAT(a.analysis_time, '%Y-%m-%d %H:%i:%s') AS AnalysisTime,
                        a.collect_address_id AS CollectAddressId,
                        a.machine_id AS MachineId,
                        NULL AS MachineName,
                        a.analysis_type AS AnalysisType,
                        a.previous_program AS PreviousProgram,
                        a.current_program AS CurrentProgram,
                        a.part_count_delta AS PartCountDelta,
                        a.analysis_summary AS AnalysisSummary
                    FROM log_collect_analysis a
                    WHERE a.raw_log_id = @RawLogId
                    ORDER BY a.analysis_time DESC";
                return conn.Query<CollectAnalysisListItem>(sql, new { RawLogId = rawLogId }).AsList();
            }
        }

        public long Create(CollectAnalysis entity)
        {
            using (var conn = CreateConnection())
            {
                var sql = @"INSERT INTO log_collect_analysis
                    (analysis_time, raw_log_id, collect_address_id, machine_id, analysis_type,
                     previous_program, current_program, previous_part_count, current_part_count,
                     part_count_delta, previous_status, current_status, analysis_summary,
                     analysis_detail, created_at)
                    VALUES (@AnalysisTime, @RawLogId, @CollectAddressId, @MachineId, @AnalysisType,
                            @PreviousProgram, @CurrentProgram, @PreviousPartCount, @CurrentPartCount,
                            @PartCountDelta, @PreviousStatus, @CurrentStatus, @AnalysisSummary,
                            @AnalysisDetail, NOW());
                    SELECT LAST_INSERT_ID();";
                return conn.ExecuteScalar<long>(sql, new
                {
                    entity.AnalysisTime,
                    entity.RawLogId,
                    entity.CollectAddressId,
                    entity.MachineId,
                    entity.AnalysisType,
                    entity.PreviousProgram,
                    entity.CurrentProgram,
                    entity.PreviousPartCount,
                    entity.CurrentPartCount,
                    entity.PartCountDelta,
                    entity.PreviousStatus,
                    entity.CurrentStatus,
                    entity.AnalysisSummary,
                    entity.AnalysisDetail
                });
            }
        }

        public int DeleteBeforeDate(DateTime date)
        {
            using (var conn = CreateConnection())
            {
                return conn.Execute(
                    "DELETE FROM log_collect_analysis WHERE analysis_time < @Date",
                    new { Date = date });
            }
        }
    }
}
