using Lada.Framework.DTO;
using Lada.Framework.DTO.Models;
using Lada.Framework.DTO.Results;
using static Lada.Framework.Data.Enums.OrderFinEnum;

namespace Lada.Framework.Infrastructures.Services
{
    /// <summary>
    /// Interface cho service tính toán cước đơn hàng
    /// </summary>
    public interface IOrderFeeCalculationService
    {
        /// <summary>
        /// Tính toán cước vận chuyển cơ bản
        /// </summary>
        /// <param name="customerId">ID khách hàng</param>
        /// <param name="sourceWardId">ID phường/xã nguồn</param>
        /// <param name="destWardId">ID phường/xã đích</param>
        /// <param name="weight">Trọng lượng (gram)</param>
        /// <param name="apiKey">API key cho Google Maps</param>
        /// <returns>Kết quả tính cước</returns>
        Task<FeeCalculationResult> CalculateBaseFeeAsync(int customerId, int sourceWardId, int destWardId, decimal weight, string apiKey);

        /// <summary>
        /// Tính toán tổng cước đơn hàng bao gồm các phí phụ
        /// </summary>
        /// <param name="request">Thông tin yêu cầu tính cước</param>
        /// <returns>Kết quả tính cước chi tiết</returns>
        Task<OrderFeeCalculationResult> CalculateOrderFeeAsync(OrderFeeCalculationRequest request);

        /// <summary>
        /// Tính toán phí VAT từ tổng cước đã bao gồm VAT (8%)
        /// </summary>
        /// <param name="totalFeeAfterVat">Tổng cước đã bao gồm VAT</param>
        /// <returns>Phí VAT</returns>
        decimal CalculateVatFee(decimal totalFeeAfterVat);

        /// <summary>
        /// Phân bổ cước theo loại thanh toán
        /// </summary>
        /// <param name="totalFeeAfterVat">Tổng cước sau VAT</param>
        /// <param name="payFeeType">Loại thanh toán</param>
        /// <param name="sourceFee">Cước người gửi trả (dùng cho SplitPay)</param>
        /// <returns>Kết quả phân bổ cước</returns>
        FeeAllocationResult AllocateFeeByPaymentType(decimal totalFeeAfterVat, PayFeeType payFeeType, decimal sourceFee = 0);
    }

    /// <summary>
    /// Service tính toán cước đơn hàng tập trung
    /// </summary>
    public class OrderFeeCalculationService(IFeeService feeService) : IOrderFeeCalculationService
    {
        private readonly IFeeService _feeService = feeService;

        /// <summary>
        /// Tính toán cước vận chuyển cơ bản
        /// </summary>
        public async Task<FeeCalculationResult> CalculateBaseFeeAsync(int customerId, int sourceWardId, int destWardId, decimal weight, string apiKey)
        {
            var result = new FeeCalculationResult();

            try
            {
                var feeModel = new FeeByWardModel()
                {
                    CustomerId = customerId,
                    SourceWardId = sourceWardId,
                    DestWardId = destWardId,
                    Weight = weight
                };

                var feeResult = await _feeService.GetFeeByWard(feeModel, apiKey);

                result.Result = feeResult.Result;
                result.Message = feeResult.Message;
                result.BaseFee = feeResult.Fee;
                result.RouteName = feeResult.RouteName;
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi khi tính cước: {ex.Message}";
                result.BaseFee = 0;
            }

            return result;
        }

        /// <summary>
        /// Tính toán tổng cước đơn hàng bao gồm các phí phụ
        /// </summary>
        public async Task<OrderFeeCalculationResult> CalculateOrderFeeAsync(OrderFeeCalculationRequest request)
        {
            var result = new OrderFeeCalculationResult();

            try
            {
                // 1. Tính cước vận chuyển cơ bản
                var baseFeeResult = await CalculateBaseFeeAsync(
                    request.CustomerId,
                    request.SourceWardId,
                    request.DestWardId,
                    request.Weight,
                    request.ApiKey);

                if (baseFeeResult.Result != Result.Success)
                {
                    result.Result = baseFeeResult.Result;
                    result.Message = baseFeeResult.Message;
                    return result;
                }

                result.BaseFee = baseFeeResult.BaseFee;
                result.RouteName = baseFeeResult.RouteName;

                // 2. Tính phí COD (1% nếu thu hộ > 1,000,000)
                result.CodFee = request.CollectAmount > 1000000 ? request.CollectAmount / 100 : 0;

                // 3. Gán các phí khác
                result.PickupSubFee = request.PickupSubFee;
                result.DeliverySubFee = request.DeliverySubFee;
                result.InsuranceFee = request.InsuranceFee;
                result.ReturnFee = request.ReturnFee;
                result.Discount = request.Discount;

                // 4. Tính tổng cước đã bao gồm VAT (giả định đầu vào đã bao gồm VAT)
                result.TotalFeeAfterVat = result.BaseFee + result.CodFee + result.PickupSubFee +
                                        result.DeliverySubFee + result.InsuranceFee + result.ReturnFee - result.Discount;

                // 5. Tính phí VAT từ tổng cước đã bao gồm VAT
                result.VatFee = CalculateVatFee(result.TotalFeeAfterVat);

                // 6. Tính tổng cước trước VAT
                result.TotalFeeBeforeVat = result.TotalFeeAfterVat - result.VatFee;

                // 7. Phân bổ cước theo loại thanh toán
                var allocation = AllocateFeeByPaymentType(result.TotalFeeAfterVat, request.PayFeeType, request.SourceFee);
                result.SourceFee = allocation.SourceFee;
                result.DestFee = allocation.DestFee;
                result.TransferFee = allocation.TransferFee;
                result.DeductCodFee = allocation.DeductCodFee;

                result.Result = Result.Success;
                result.Message = "Tính cước thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi khi tính tổng cước: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Tính toán phí VAT từ tổng cước đã bao gồm VAT (8%)
        /// </summary>
        public decimal CalculateVatFee(decimal totalFeeAfterVat)
        {
            if (totalFeeAfterVat <= 0)
                return 0;

            // Tính VAT từ tổng cước đã bao gồm VAT: VAT = totalFeeAfterVat * 0.08 / 1.08
            return Math.Round(totalFeeAfterVat * 0.08m / 1.08m, 0);
        }

        /// <summary>
        /// Phân bổ cước theo loại thanh toán
        /// </summary>
        public FeeAllocationResult AllocateFeeByPaymentType(decimal totalFeeAfterVat, PayFeeType payFeeType, decimal sourceFee = 0)
        {
            var result = new FeeAllocationResult();

            switch (payFeeType)
            {
                case PayFeeType.SenderPay:
                    result.SourceFee = totalFeeAfterVat;
                    result.DestFee = 0;
                    result.TransferFee = 0;
                    result.DeductCodFee = 0;
                    break;

                case PayFeeType.ConsigneePay:
                    result.SourceFee = 0;
                    result.DestFee = totalFeeAfterVat;
                    result.TransferFee = 0;
                    result.DeductCodFee = 0;
                    break;

                case PayFeeType.BankTransfer:
                    result.SourceFee = 0;
                    result.DestFee = 0;
                    result.TransferFee = totalFeeAfterVat;
                    result.DeductCodFee = 0;
                    break;

                case PayFeeType.SplitPay:
                    result.SourceFee = sourceFee;
                    result.DestFee = totalFeeAfterVat - sourceFee;
                    if (result.DestFee < 0) result.DestFee = 0;
                    result.TransferFee = 0;
                    result.DeductCodFee = 0;
                    break;

                case PayFeeType.COD:
                    result.SourceFee = 0;
                    result.DestFee = 0;
                    result.TransferFee = 0;
                    result.DeductCodFee = totalFeeAfterVat;
                    break;

                default:
                    result.SourceFee = 0;
                    result.DestFee = totalFeeAfterVat;
                    result.TransferFee = 0;
                    result.DeductCodFee = 0;
                    break;
            }

            return result;
        }
    }
}
