using System.Data;
using Dapper;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Monitor;

namespace Ladaer.BackEnd.Infrastructures.Services.Monitor
{
    public interface IOrderRiskService
    {
        Task<OrderRiskResult> GetOrdersWithoutSourceCashierAsync(OrderRiskSearchParam param);
        Task<OrderRiskOverview> GetOrderRiskOverviewAsync(DateTime? fromDate = null, DateTime? toDate = null);
        Task<OrderRiskResult> GetOrdersWithoutDestCashierAsync(OrderRiskSearchParam param);
        Task<OrderRiskOverview> GetOrderRiskOverviewForDestCashierAsync(DateTime? fromDate = null, DateTime? toDate = null);
        Task<OrderRiskResult> GetOrdersBothPayWithoutCashierAsync(OrderRiskSearchParam param);
        Task<OrderRiskOverview> GetOrderRiskOverviewForBothPayAsync(DateTime? fromDate = null, DateTime? toDate = null);
    }

    public class OrderRiskService : IOrderRiskService
    {
        private readonly IDbConnection _connection;

        public OrderRiskService(IDbConnection connection)
        {
            _connection = connection;
        }

        public async Task<OrderRiskResult> GetOrdersWithoutSourceCashierAsync(OrderRiskSearchParam param)
        {
            var parameters = new DynamicParameters();

            if (param.FromDate.HasValue)
            {
                parameters.Add("@FromDate", param.FromDate.Value);
            }

            if (param.ToDate.HasValue)
            {
                parameters.Add("@ToDate", param.ToDate.Value);
            }

            parameters.Add("@PageNumber", param.PageNumber > 0 ? param.PageNumber : 1);
            parameters.Add("@PageSize", param.PageSize > 0 ? param.PageSize : 50);

            var multi = await _connection.QueryMultipleAsync(
                "[dbo].[sp_GetOrdersWithoutSourceCashier]",
                parameters,
                commandType: CommandType.StoredProcedure);

            var totalRecords = await multi.ReadFirstOrDefaultAsync<int>();
            var orders = (await multi.ReadAsync<OrderRiskItem>()).ToList();

            return new OrderRiskResult
            {
                TotalRecords = totalRecords,
                PageNumber = param.PageNumber > 0 ? param.PageNumber : 1,
                PageSize = param.PageSize > 0 ? param.PageSize : 50,
                TotalPages = (int)Math.Ceiling(totalRecords / (double)(param.PageSize > 0 ? param.PageSize : 50)),
                Orders = orders,
                RiskInfo = new RiskInfo
                {
                    Code = "NO_SOURCE_CASHIER",
                    Name = "Đơn thu người gửi thiếu thông tin Cashier",
                    Description = "Đơn hàng có PayFeeType = SenderPay (thu người gửi) nhưng không có SourceFeeCashierId",
                    Severity = "Critical",
                    Solution = "Cập nhật SourceFeeCashierId cho các đơn hàng này hoặc thay đổi PayFeeType"
                }
            };
        }

        public async Task<OrderRiskOverview> GetOrderRiskOverviewAsync(DateTime? fromDate = null, DateTime? toDate = null)
        {
            var parameters = new DynamicParameters();

            if (fromDate.HasValue)
            {
                parameters.Add("@FromDate", fromDate.Value);
            }

            if (toDate.HasValue)
            {
                parameters.Add("@ToDate", toDate.Value);
            }

            var result = await _connection.QueryFirstOrDefaultAsync<OrderRiskOverview>(
                "[dbo].[sp_GetOrdersWithoutSourceCashierOverview]",
                parameters,
                commandType: CommandType.StoredProcedure);

            if (result == null)
            {
                result = new OrderRiskOverview();
            }

            result.RiskInfo = new RiskInfo
            {
                Code = "NO_SOURCE_CASHIER",
                Name = "Đơn thu người gửi thiếu thông tin Cashier",
                Description = "Đơn hàng có PayFeeType = SenderPay (thu người gửi) nhưng không có SourceFeeCashierId",
                Severity = "Critical",
                Solution = "Cập nhật SourceFeeCashierId cho các đơn hàng này hoặc thay đổi PayFeeType"
            };

            return result;
        }

        public async Task<OrderRiskResult> GetOrdersWithoutDestCashierAsync(OrderRiskSearchParam param)
        {
            var parameters = new DynamicParameters();

            if (param.FromDate.HasValue)
            {
                parameters.Add("@FromDate", param.FromDate.Value);
            }

            if (param.ToDate.HasValue)
            {
                parameters.Add("@ToDate", param.ToDate.Value);
            }

            parameters.Add("@PageNumber", param.PageNumber > 0 ? param.PageNumber : 1);
            parameters.Add("@PageSize", param.PageSize > 0 ? param.PageSize : 50);

            var multi = await _connection.QueryMultipleAsync(
                "[dbo].[sp_GetOrdersWithoutDestCashier]",
                parameters,
                commandType: CommandType.StoredProcedure);

            var totalRecords = await multi.ReadFirstOrDefaultAsync<int>();
            var orders = (await multi.ReadAsync<OrderRiskItem>()).ToList();

            return new OrderRiskResult
            {
                TotalRecords = totalRecords,
                PageNumber = param.PageNumber > 0 ? param.PageNumber : 1,
                PageSize = param.PageSize > 0 ? param.PageSize : 50,
                TotalPages = (int)Math.Ceiling(totalRecords / (double)(param.PageSize > 0 ? param.PageSize : 50)),
                Orders = orders,
                RiskInfo = new RiskInfo
                {
                    Code = "NO_DEST_CASHIER",
                    Name = "Đơn thu người nhận thiếu thông tin Cashier",
                    Description = "Đơn hàng có PayFeeType = ReceiverPay (thu người nhận), đã thành công nhưng không có DestFeeCashierId",
                    Severity = "Critical",
                    Solution = "Cập nhật DestFeeCashierId cho các đơn hàng này hoặc thay đổi PayFeeType"
                }
            };
        }

        public async Task<OrderRiskOverview> GetOrderRiskOverviewForDestCashierAsync(DateTime? fromDate = null, DateTime? toDate = null)
        {
            var parameters = new DynamicParameters();

            if (fromDate.HasValue)
            {
                parameters.Add("@FromDate", fromDate.Value);
            }

            if (toDate.HasValue)
            {
                parameters.Add("@ToDate", toDate.Value);
            }

            var result = await _connection.QueryFirstOrDefaultAsync<OrderRiskOverview>(
                "[dbo].[sp_GetOrdersWithoutDestCashierOverview]",
                parameters,
                commandType: CommandType.StoredProcedure);

            if (result == null)
            {
                result = new OrderRiskOverview();
            }

            result.RiskInfo = new RiskInfo
            {
                Code = "NO_DEST_CASHIER",
                Name = "Đơn thu người nhận thiếu thông tin Cashier",
                Description = "Đơn hàng có PayFeeType = ReceiverPay (thu người nhận), đã thành công nhưng không có DestFeeCashierId",
                Severity = "Critical",
                Solution = "Cập nhật DestFeeCashierId cho các đơn hàng này hoặc thay đổi PayFeeType"
            };

            return result;
        }

        public async Task<OrderRiskResult> GetOrdersBothPayWithoutCashierAsync(OrderRiskSearchParam param)
        {
            var parameters = new DynamicParameters();

            if (param.FromDate.HasValue)
            {
                parameters.Add("@FromDate", param.FromDate.Value);
            }

            if (param.ToDate.HasValue)
            {
                parameters.Add("@ToDate", param.ToDate.Value);
            }

            parameters.Add("@PageNumber", param.PageNumber > 0 ? param.PageNumber : 1);
            parameters.Add("@PageSize", param.PageSize > 0 ? param.PageSize : 50);

            var multi = await _connection.QueryMultipleAsync(
                "[dbo].[sp_GetOrdersBothPayWithoutCashier]",
                parameters,
                commandType: CommandType.StoredProcedure);

            var totalRecords = await multi.ReadFirstOrDefaultAsync<int>();
            var orders = (await multi.ReadAsync<OrderRiskItem>()).ToList();

            return new OrderRiskResult
            {
                TotalRecords = totalRecords,
                PageNumber = param.PageNumber > 0 ? param.PageNumber : 1,
                PageSize = param.PageSize > 0 ? param.PageSize : 50,
                TotalPages = (int)Math.Ceiling(totalRecords / (double)(param.PageSize > 0 ? param.PageSize : 50)),
                Orders = orders,
                RiskInfo = new RiskInfo
                {
                    Code = "BOTH_PAY_MISSING_CASHIER",
                    Name = "Đơn thu cả 2 đầu thiếu thông tin Cashier",
                    Description = "Đơn hàng có PayFeeType = BothPay (thu cả 2 đầu), đã thành công nhưng thiếu SourceFeeCashierId hoặc DestFeeCashierId",
                    Severity = "Critical",
                    Solution = "Cập nhật SourceFeeCashierId và/hoặc DestFeeCashierId cho các đơn hàng này"
                }
            };
        }

        public async Task<OrderRiskOverview> GetOrderRiskOverviewForBothPayAsync(DateTime? fromDate = null, DateTime? toDate = null)
        {
            var parameters = new DynamicParameters();

            if (fromDate.HasValue)
            {
                parameters.Add("@FromDate", fromDate.Value);
            }

            if (toDate.HasValue)
            {
                parameters.Add("@ToDate", toDate.Value);
            }

            var result = await _connection.QueryFirstOrDefaultAsync<OrderRiskOverview>(
                "[dbo].[sp_GetOrdersBothPayWithoutCashierOverview]",
                parameters,
                commandType: CommandType.StoredProcedure);

            if (result == null)
            {
                result = new OrderRiskOverview();
            }

            result.RiskInfo = new RiskInfo
            {
                Code = "BOTH_PAY_MISSING_CASHIER",
                Name = "Đơn thu cả 2 đầu thiếu thông tin Cashier",
                Description = "Đơn hàng có PayFeeType = BothPay (thu cả 2 đầu), đã thành công nhưng thiếu SourceFeeCashierId hoặc DestFeeCashierId",
                Severity = "Critical",
                Solution = "Cập nhật SourceFeeCashierId và/hoặc DestFeeCashierId cho các đơn hàng này"
            };

            return result;
        }

    }
}
