using Dapper;
using Lada.Framework.Data.Enums;
using Lada.Framework.DTO;
using System.Data;
using static Lada.Framework.Data.Enums.OrderFinEnum;

namespace Ladaer.BackEnd.Infrastructures.Services.Finances
{
    /// <summary>
    /// Interface cho service quản lý thời gian nhận tiền trong OrderTimeTrack
    /// </summary>
    public interface IOrderTimeTrackService
    {
        /// <summary>
        /// Cập nhật thời gian nhận tiền trong OrderTimeTrack
        /// </summary>
        /// <param name="orderId">ID đơn hàng</param>
        /// <param name="sourceFeeStage">Stage của SourceFee (3=Branch, 9=Head)</param>
        /// <param name="destFeeStage">Stage của DestFee (3=Branch, 9=Head)</param>
        /// <param name="transferFeeStage">Stage của TransferFee (3=Branch, 9=Head)</param>
        /// <param name="codStage">Stage của COD (3=Branch, 9=Head)</param>
        /// <param name="deductCodFeeStage">Stage của DeductCodFee (3=Branch, 9=Head) - chỉ khi PayFeeType = COD</param>
        /// <param name="updatedBy">ID người cập nhật</param>
        /// <param name="updatedByUserName">Tên người cập nhật</param>
        /// <param name="currentTime">Thời gian hiện tại (null = SYSDATETIMEOFFSET())</param>
        /// <returns>Kết quả cập nhật</returns>
        Task<BaseResult> UpdateFinancialTimesAsync(
            int orderId,
            OrderFeeStage? sourceFeeStage = null,
            OrderFeeStage? destFeeStage = null,
            OrderFeeStage? transferFeeStage = null,
            OrderCodStage? codStage = null,
            OrderFeeStage? deductCodFeeStage = null,
            int? updatedBy = null,
            string? updatedByUserName = null,
            DateTimeOffset? currentTime = null);

        /// <summary>
        /// Cập nhật thời gian nhận tiền cho nhiều đơn hàng
        /// </summary>
        /// <param name="orderUpdates">Danh sách cập nhật cho các đơn hàng</param>
        /// <param name="updatedBy">ID người cập nhật</param>
        /// <param name="updatedByUserName">Tên người cập nhật</param>
        /// <param name="currentTime">Thời gian hiện tại (null = SYSDATETIMEOFFSET())</param>
        /// <returns>Kết quả cập nhật</returns>
        Task<BaseResult> UpdateFinancialTimesBatchAsync(
            List<OrderTimeTrackUpdateModel> orderUpdates,
            int updatedBy,
            string updatedByUserName,
            DateTimeOffset? currentTime = null);
    }

    /// <summary>
    /// Model cho việc cập nhật thời gian nhận tiền của một đơn hàng
    /// </summary>
    public class OrderTimeTrackUpdateModel
    {
        public int OrderId { get; set; }
        public OrderFeeStage? SourceFeeStage { get; set; }
        public OrderFeeStage? DestFeeStage { get; set; }
        public OrderFeeStage? TransferFeeStage { get; set; }
        public OrderCodStage? CodStage { get; set; }
        public OrderFeeStage? DeductCodFeeStage { get; set; }
    }

    /// <summary>
    /// Service quản lý thời gian nhận tiền trong OrderTimeTrack
    /// </summary>
    public class OrderTimeTrackService : IOrderTimeTrackService
    {
        private readonly IDbConnection _dbConnection;

        /// <summary>
        /// Khởi tạo một thể hiện của <see cref="OrderTimeTrackService"/>.
        /// </summary>
        /// <param name="dbConnection">Database connection.</param>
        public OrderTimeTrackService(IDbConnection dbConnection)
        {
            _dbConnection = dbConnection;
        }

        /// <summary>
        /// Cập nhật thời gian nhận tiền trong OrderTimeTrack
        /// </summary>
        public async Task<BaseResult> UpdateFinancialTimesAsync(
            int orderId,
            OrderFeeStage? sourceFeeStage = null,
            OrderFeeStage? destFeeStage = null,
            OrderFeeStage? transferFeeStage = null,
            OrderCodStage? codStage = null,
            OrderFeeStage? deductCodFeeStage = null,
            int? updatedBy = null,
            string? updatedByUserName = null,
            DateTimeOffset? currentTime = null)
        {
            var result = new BaseResult();

            try
            {
                var parameters = new DynamicParameters();
                parameters.Add("@OrderId", orderId);
                parameters.Add("@SourceFeeStage", sourceFeeStage.HasValue ? (int)sourceFeeStage.Value : (int?)null);
                parameters.Add("@DestFeeStage", destFeeStage.HasValue ? (int)destFeeStage.Value : (int?)null);
                parameters.Add("@TransferFeeStage", transferFeeStage.HasValue ? (int)transferFeeStage.Value : (int?)null);
                parameters.Add("@CodStage", codStage.HasValue ? (int)codStage.Value : (int?)null);
                parameters.Add("@DeductCodFeeStage", deductCodFeeStage.HasValue ? (int)deductCodFeeStage.Value : (int?)null);
                parameters.Add("@CurrentTime", currentTime);
                parameters.Add("@UpdatedBy", updatedBy);
                parameters.Add("@UpdatedByUserName", updatedByUserName);
                parameters.Add("@Result", dbType: DbType.Int32, direction: ParameterDirection.Output);
                parameters.Add("@Message", dbType: DbType.String, direction: ParameterDirection.Output, size: 500);

                await _dbConnection.ExecuteAsync("SP_UpdateOrderTimeTrackFinancialTimes", parameters, commandType: CommandType.StoredProcedure);

                var spResult = parameters.Get<int>("@Result");
                var spMessage = parameters.Get<string>("@Message");

                result.Result = (Result)spResult;
                result.Message = spMessage;
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi hệ thống: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Cập nhật thời gian nhận tiền cho nhiều đơn hàng
        /// </summary>
        public async Task<BaseResult> UpdateFinancialTimesBatchAsync(
            List<OrderTimeTrackUpdateModel> orderUpdates,
            int updatedBy,
            string updatedByUserName,
            DateTimeOffset? currentTime = null)
        {
            var result = new BaseResult();
            var errors = new List<string>();

            try
            {
                foreach (var orderUpdate in orderUpdates)
                {
                    var updateResult = await UpdateFinancialTimesAsync(
                        orderUpdate.OrderId,
                        orderUpdate.SourceFeeStage,
                        orderUpdate.DestFeeStage,
                        orderUpdate.TransferFeeStage,
                        orderUpdate.CodStage,
                        orderUpdate.DeductCodFeeStage,
                        updatedBy,
                        updatedByUserName,
                        currentTime);

                    if (updateResult.Result != Result.Success)
                    {
                        errors.Add($"Đơn hàng {orderUpdate.OrderId}: {updateResult.Message}");
                    }
                }

                if (errors.Any())
                {
                    result.Result = Result.Failed;
                    result.Message = $"Có lỗi khi cập nhật: {string.Join("; ", errors)}";
                }
                else
                {
                    result.Result = Result.Success;
                    result.Message = $"Cập nhật thành công {orderUpdates.Count} đơn hàng";
                }
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi hệ thống: {ex.Message}";
            }

            return result;
        }
    }
}
