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

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

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

        public ProductionSegment GetActiveSegment(int machineId)
        {
            using (var conn = CreateConnection())
            {
                string sql = "SELECT * FROM cnc_production_segment WHERE machine_id = @MachineId AND is_settled = 0 AND end_time IS NULL ORDER BY start_time DESC LIMIT 1";
                return conn.QuerySingleOrDefault<ProductionSegment>(sql, new { MachineId = machineId });
            }
        }

        public List<ProductionSegment> GetByMachineAndDate(int machineId, DateTime date)
        {
            using (var conn = CreateConnection())
            {
                string sql = "SELECT * FROM cnc_production_segment WHERE machine_id = @MachineId AND DATE(start_time) = DATE(@Date)";
                return conn.Query<ProductionSegment>(sql, new { MachineId = machineId, Date = date }).AsList();
            }
        }

        public int Create(ProductionSegment entity)
        {
            using (var conn = CreateConnection())
            {
                string sql = @"INSERT INTO cnc_production_segment (machine_id, program_name, production_date, start_time, start_part_count, end_part_count, quantity, is_settled, close_reason, end_time, created_at, updated_at)
                                VALUES (@MachineId, @ProgramName, @ProductionDate, @StartTime, @StartPartCount, @EndPartCount, @Quantity, @IsSettled, @CloseReason, @EndTime, @CreatedAt, @UpdatedAt); SELECT LAST_INSERT_ID();";
                return conn.ExecuteScalar<int>(sql, entity);
            }
        }

        public bool CloseSegment(long id, decimal? endPartCount, decimal? quantity, string closeReason, DateTime endTime)
        {
            using (var conn = CreateConnection())
            {
                string sql = @"UPDATE cnc_production_segment
                               SET end_part_count = @EndPartCount, quantity = @Quantity, close_reason = @CloseReason, end_time = @EndTime
                               WHERE id = @Id";
                int affected = conn.Execute(sql, new { Id = id, EndPartCount = endPartCount, Quantity = quantity, CloseReason = closeReason, EndTime = endTime });
                return affected > 0;
            }
        }

        public bool SettleByDate(DateTime date)
        {
            using (var conn = CreateConnection())
            {
                string sql = @"UPDATE cnc_production_segment SET is_settled = 1, close_reason = 'end_of_day' WHERE DATE(start_time) = DATE(@Date) AND is_settled = 0";
                int affected = conn.Execute(sql, new { Date = date });
                return affected > 0;
            }
        }

        /// <summary>
        /// 实时统计指定日期范围的产量（从分段表计算）
        /// </summary>
        public decimal GetTotalByDateRange(DateTime startDate, DateTime endDate, int? workshopId = null)
        {
            using (var conn = CreateConnection())
            {
                string sql = @"SELECT COALESCE(SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity 
                            ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END), 0)
                    FROM cnc_production_segment seg
                    LEFT JOIN cnc_machine m ON seg.machine_id = m.id
                    WHERE seg.production_date BETWEEN @Start AND @End";
                if (workshopId.HasValue)
                {
                    sql += " AND m.workshop_id = @WorkshopId";
                    return conn.ExecuteScalar<decimal>(sql, new { Start = startDate, End = endDate, WorkshopId = workshopId.Value });
                }
                return conn.ExecuteScalar<decimal>(sql, new { Start = startDate, End = endDate });
            }
        }

        /// <summary>
        /// 获取有产量记录的机床数量
        /// </summary>
        public int GetActiveMachineCount(DateTime date, int? workshopId = null)
        {
            using (var conn = CreateConnection())
            {
                string sql = @"SELECT COUNT(DISTINCT seg.machine_id)
                    FROM cnc_production_segment seg
                    LEFT JOIN cnc_machine m ON seg.machine_id = m.id
                    WHERE seg.production_date = @Date";
                if (workshopId.HasValue)
                {
                    sql += " AND m.workshop_id = @WorkshopId";
                    return conn.ExecuteScalar<int>(sql, new { Date = date, WorkshopId = workshopId.Value });
                }
                return conn.ExecuteScalar<int>(sql, new { Date = date });
            }
        }

        /// <summary>
        /// 获取今日切削总时间（小时），取每台机床最新-最早的cutting_time差值之和
        /// </summary>
        public decimal GetTotalCuttingTimeByDate(DateTime date)
        {
            using (var conn = CreateConnection())
            {
                string sql = @"SELECT COALESCE(ROUND(SUM(today_delta)/3600, 1), 0)
                    FROM (
                        SELECT MAX(cr.cutting_time) - MIN(cr.cutting_time) AS today_delta
                        FROM cnc_collect_record cr
                        WHERE DATE(cr.collect_time) = @Date
                        GROUP BY cr.machine_id
                    ) t";
                return conn.ExecuteScalar<decimal>(sql, new { Date = date });
            }
        }
    }
}
