using AutoMapper;
using Lada.Framework.Data.Domains.Finance;
using Lada.Framework.Data.Domains.Finance.Wallets;

using Ladaer.BackEnd.Infrastructures.DTO.Items.Finances;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Finances;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Finance;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Finance;
using Lada.Framework.Infrastructures.Helpers;
using Lada.Framework.Data.Domains.Orders;
using static Lada.Framework.Data.Enums.OrderFinEnum;
using Lada.Framework.Data.Enums;

namespace Ladaer.BackEnd.Infrastructures.DTO.Profiles
{
    public class FinanceMappingProfile : Profile
    {
        public FinanceMappingProfile()
        {
            // ExpenseCategory mappings
            CreateMap<ExpenseCategory, ExpenseCategoryItem>()
                .ForMember(dest => dest.ParentName, opt => opt.MapFrom(src => src.Parent != null ? src.Parent.Name : null))
                .ForMember(dest => dest.Children, opt => opt.Ignore()) // Sẽ được set trong service
                .ForMember(dest => dest.Level, opt => opt.Ignore()); // Sẽ được set trong service
            CreateMap<ExpenseCategory, ExpenseCategoryModel>();
            CreateMap<ExpenseCategoryModel, ExpenseCategory>()
                .ForMember(dest => dest.CreatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.UpdatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.IsDeleted, opt => opt.Ignore())
                .ForMember(dest => dest.Parent, opt => opt.Ignore())
                .ForMember(dest => dest.Children, opt => opt.Ignore());

            // IncomeCategory mappings
            CreateMap<IncomeCategory, IncomeCategoryItem>()
                .ForMember(dest => dest.ParentName, opt => opt.MapFrom(src => src.Parent != null ? src.Parent.Name : null))
                .ForMember(dest => dest.Children, opt => opt.Ignore()) // Sẽ được set trong service
                .ForMember(dest => dest.Level, opt => opt.Ignore()); // Sẽ được set trong service
            CreateMap<IncomeCategory, IncomeCategoryModel>();
            CreateMap<IncomeCategoryModel, IncomeCategory>()
                .ForMember(dest => dest.CreatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.UpdatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.IsDeleted, opt => opt.Ignore())
                .ForMember(dest => dest.Parent, opt => opt.Ignore())
                .ForMember(dest => dest.Children, opt => opt.Ignore());

            CreateMap<Expense, ExpenseItem>()
                .ForMember(dest => dest.ExpenseCategoryName, opt => opt.MapFrom(src => src.ExpenseCategory != null ? src.ExpenseCategory.Name : string.Empty))
                .ForMember(dest => dest.UserBankAccountInfo, opt => opt.MapFrom(src =>
                    !string.IsNullOrEmpty(src.BankAccountNumber) && !string.IsNullOrEmpty(src.BankAccountHolderName)
                    ? $"{src.BankAccountHolderName} - {src.BankAccountNumber} ({src.BankName})"
                    : string.Empty));
            CreateMap<Expense, ExpenseModel>()
                .ForMember(dest => dest.ExpenseCategoryName, opt => opt.MapFrom(src => src.ExpenseCategory != null ? src.ExpenseCategory.Name : string.Empty))
                .ForMember(dest => dest.UserBankAccountInfo, opt => opt.MapFrom(src =>
                    !string.IsNullOrEmpty(src.BankAccountNumber) && !string.IsNullOrEmpty(src.BankAccountHolderName)
                    ? $"{src.BankAccountHolderName} - {src.BankAccountNumber} ({src.BankName})"
                    : string.Empty));
            CreateMap<ExpenseModel, Expense>()
                .ForMember(dest => dest.CreatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.UpdatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.IsDeleted, opt => opt.Ignore())
                .ForMember(dest => dest.ExpenseCategory, opt => opt.Ignore())
                .ForMember(dest => dest.Transaction, opt => opt.Ignore())
                .ForMember(dest => dest.Order, opt => opt.Ignore())
                .ForMember(dest => dest.UserBankAccount, opt => opt.Ignore())
                // UserBankAccountId được map bình thường
                .ForMember(dest => dest.UserBankAccountId, opt => opt.MapFrom(src => src.UserBankAccountId))
                // Bank account fields sẽ được set trong service khi copy từ UserBankAccount
                .ForMember(dest => dest.BankAccountNumber, opt => opt.Ignore())
                .ForMember(dest => dest.BankAccountHolderName, opt => opt.Ignore())
                .ForMember(dest => dest.BankCode, opt => opt.Ignore())
                .ForMember(dest => dest.BankName, opt => opt.Ignore())
                .ForMember(dest => dest.BankBranchName, opt => opt.Ignore());
            CreateMap<ExpenseHistory, ExpenseHistoryItem>()
                .ForMember(dest => dest.ActionByUserName, opt => opt.MapFrom(src => src.CreatedByUserName))
                .ForMember(dest => dest.OldStatus, opt => opt.MapFrom(src => src.OldStatus))
                .ForMember(dest => dest.OldStatusDisplay, opt => opt.MapFrom(src => GetExpenseStatusDisplay(src.OldStatus)))
                .ForMember(dest => dest.NewStatus, opt => opt.MapFrom(src => src.NewStatus))
                .ForMember(dest => dest.NewStatusDisplay, opt => opt.MapFrom(src => GetExpenseStatusDisplay(src.NewStatus)));

            // Income mappings
            CreateMap<Income, IncomeItem>()
                .ForMember(dest => dest.IncomeCategoryName, opt => opt.MapFrom(src => src.IncomeCategory != null ? src.IncomeCategory.Name : string.Empty));
            CreateMap<Income, IncomeModel>()
                .ForMember(dest => dest.IncomeCategoryName, opt => opt.MapFrom(src => src.IncomeCategory != null ? src.IncomeCategory.Name : string.Empty));
            CreateMap<IncomeModel, Income>()
                .ForMember(dest => dest.CreatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.UpdatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.IsDeleted, opt => opt.Ignore())
                .ForMember(dest => dest.IncomeCategory, opt => opt.Ignore())
                .ForMember(dest => dest.Transaction, opt => opt.Ignore())
                .ForMember(dest => dest.Order, opt => opt.Ignore());
            CreateMap<IncomeHistory, IncomeHistoryItem>()
                .ForMember(dest => dest.ActionByUserName, opt => opt.MapFrom(src => src.CreatedByUserName));

            // Transaction mappings
            CreateMap<Transaction, TransactionItem>()
                .ForMember(dest => dest.TransactionTypeName, opt => opt.MapFrom(src => src.TransactionType.GetDescription()))
                .ForMember(dest => dest.TransactionDirectionName, opt => opt.MapFrom(src => src.TransactionDirection.GetDescription()))
                .ForMember(dest => dest.WalletOwnerName, opt => opt.MapFrom(src => src.Wallet != null ? src.Wallet.User.UserName : "Unknown"))
                .ForMember(dest => dest.RelatedWalletOwnerName, opt => opt.MapFrom(src => src.RelatedWallet != null ? src.RelatedWallet.User.UserName : ""))
                .ForMember(dest => dest.OrderCount, opt => opt.MapFrom(src => src.TransactionOrders != null ? src.TransactionOrders.Count : 0))
                .ForMember(dest => dest.OrderCodes, opt => opt.MapFrom(src => src.TransactionOrders != null ? src.TransactionOrders.Select(to => to.Order.Code).ToList() : new List<string>()))
                .ForMember(dest => dest.TotalCodAmount, opt => opt.MapFrom(src => src.TransactionOrders != null ? src.TransactionOrders.Sum(to => to.CodAmount) : 0))
                .ForMember(dest => dest.TotalSourceFeeAmount, opt => opt.MapFrom(src => src.TransactionOrders != null ? src.TransactionOrders.Sum(to => to.SourceFeeAmount) : 0))
                .ForMember(dest => dest.TotalDestFeeAmount, opt => opt.MapFrom(src => src.TransactionOrders != null ? src.TransactionOrders.Sum(to => to.DestFeeAmount) : 0))
                // Các trường mới cho hiển thị tối ưu
                .ForMember(dest => dest.FormattedAmount, opt => opt.MapFrom(src => src.TransactionDirection == TransactionDirection.Income ? $"+{src.Amount:N0}" : $"-{src.Amount:N0}"))
                .ForMember(dest => dest.FormattedAmountWithCurrency, opt => opt.MapFrom(src => src.TransactionDirection == TransactionDirection.Income ? $"+{src.Amount:N0} VND" : $"-{src.Amount:N0} VND"))
                .ForMember(dest => dest.AmountColor, opt => opt.MapFrom(src => src.TransactionDirection == TransactionDirection.Income ? "green" : "red"))
                .ForMember(dest => dest.TransactionIcon, opt => opt.MapFrom(src => TransactionMappingHelpers.GetTransactionIcon(src.TransactionType)))
                .ForMember(dest => dest.FromUserName, opt => opt.Ignore()) // Sẽ được set trong service
                .ForMember(dest => dest.FromUserPhone, opt => opt.Ignore()) // Sẽ được set trong service
                .ForMember(dest => dest.FromUserFullName, opt => opt.Ignore()) // Sẽ được set trong service
                .ForMember(dest => dest.BalanceAfterTransaction, opt => opt.MapFrom(src => src.Wallet != null ? src.Wallet.Balance : 0))
                .ForMember(dest => dest.FormattedBalance, opt => opt.MapFrom(src => src.Wallet != null ? $"{src.Wallet.Balance:N0} VND" : "0 VND"))
                .ForMember(dest => dest.IsIncome, opt => opt.MapFrom(src => src.TransactionDirection == TransactionDirection.Income))
                .ForMember(dest => dest.IsOutcome, opt => opt.MapFrom(src => src.TransactionDirection == TransactionDirection.Outcome))
                .ForMember(dest => dest.ShortDescription, opt => opt.MapFrom(src => TransactionMappingHelpers.GetShortDescription(src)));

            CreateMap<TransactionOrder, TransactionOrderItem>()
                .ForMember(dest => dest.OrderCode, opt => opt.MapFrom(src => src.Order.Code))
                .ForMember(dest => dest.PartnerCode, opt => opt.MapFrom(src => src.Order.PartnerCode))
                .ForMember(dest => dest.OrderNote, opt => opt.MapFrom(src => src.Order.Note))
                .ForMember(dest => dest.CustomerId, opt => opt.MapFrom(src => src.Order.CustomerId))
                .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Order.Customer != null ? src.Order.Customer.FullName : ""))
                .ForMember(dest => dest.ChargeWeight, opt => opt.MapFrom(src => src.Order.OrderFin != null ? src.Order.OrderFin.ChargeWeight : 0))
                .ForMember(dest => dest.OrderCodAmount, opt => opt.MapFrom(src => src.Order.OrderFin != null ? src.Order.OrderFin.CollectAmount : 0))
                .ForMember(dest => dest.OrderFee, opt => opt.MapFrom(src => src.Order.OrderFin != null ? src.Order.OrderFin.Fee : 0))
                .ForMember(dest => dest.OrderTotalFee, opt => opt.MapFrom(src => src.Order.OrderFin != null ? src.Order.OrderFin.TotalFee : 0))
                .ForMember(dest => dest.PayFeeType, opt => opt.MapFrom(src => src.Order.OrderFin != null ? src.Order.OrderFin.PayFeeType : Lada.Framework.Data.Enums.OrderFinEnum.PayFeeType.SenderPay))
                .ForMember(dest => dest.PayFeeTypeName, opt => opt.MapFrom(src => src.Order.OrderFin != null ? src.Order.OrderFin.PayFeeType.GetDescription() : ""))
                .ForMember(dest => dest.OrderCreatedTime, opt => opt.MapFrom(src => src.Order.CreatedTime))
                .ForMember(dest => dest.OrderUpdatedTime, opt => opt.MapFrom(src => src.Order.UpdatedTime));

            // Reconciliation mappings
            CreateMap<Reconciliation, ReconciliationItem>()
                .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.FullName : ""))
                .ForMember(dest => dest.CustomerPhone, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.PhoneNumber : ""))
                .ForMember(dest => dest.StatusStr, opt => opt.MapFrom(src => src.Status.GetDescription()));

            CreateMap<Reconciliation, ReconciliationDetailModel>()
                .ForMember(dest => dest.Customer, opt => opt.MapFrom(src => src.Customer != null ? new DTO.Items.Crm.CustomerItem
                {
                    Id = src.Customer.Id,
                    FullName = src.Customer.FullName,
                    PhoneNumber = src.Customer.PhoneNumber,
                    Email = src.Customer.Email
                } : null))
                .ForMember(dest => dest.StatusStr, opt => opt.MapFrom(src => src.Status.GetDescription()))
                .ForMember(dest => dest.TypeStr, opt => opt.MapFrom(src => src.Type.GetDescription()))
                .ForMember(dest => dest.VatInfo, opt => opt.MapFrom(src => src.VatInfo != null ? new DTO.Items.Crm.VatInfoItem
                {
                    Id = src.VatInfo.Id,
                    CustomerId = src.VatInfo.CustomerId,
                    CompanyName = src.VatInfo.CompanyName,
                    TaxCode = src.VatInfo.TaxCode,
                    Address = src.VatInfo.Address,
                    InvoiceEmail = src.VatInfo.InvoiceEmail,
                    ContactName = src.VatInfo.ContactName,
                    ContactPhone = src.VatInfo.ContactPhone,
                    Note = src.VatInfo.Note,
                    IsDefault = src.VatInfo.IsDefault
                } : null))
                .ForMember(dest => dest.BankAccount, opt => opt.MapFrom(src => !string.IsNullOrEmpty(src.BankAccountNumber) ? new BankAccountInfo
                {
                    AccountNumber = src.BankAccountNumber,
                    AccountHolderName = src.BankAccountHolderName,
                    BankCode = src.BankCode,
                    BankName = src.BankName,
                    BranchName = src.BankBranchName,
                    BranchAddress = src.BankBranchAddress
                } : null))
                .ForMember(dest => dest.CreatedTime, opt => opt.MapFrom(src => src.CreatedTime ?? DateTimeOffset.Now))
                .ForMember(dest => dest.Orders, opt => opt.MapFrom(src => src.Orders != null ? src.Orders.Select(ro => new ReconciliationOrderItem
                {
                    Id = ro.Id,
                    ReconciliationId = ro.ReconciliationId,
                    OrderId = ro.OrderId,
                    OrderCode = ro.OrderCode,
                    PartnerCode = ro.PartnerCode,
                    CodAmount = ro.CodAmount,
                    FeeAmount = ro.FeeAmount,
                    NetAmount = ro.NetAmount,
                    DeliveredDate = ro.DeliveredDate,
                    CodCollectedDate = ro.CodCollectedDate,
                    ChargeWeight = ro.ChargeWeight,
                    ShippingFee = ro.ShippingFee,
                    DeliveryAddress = ro.DeliveryAddress,
                    ReceiverName = ro.ReceiverName,
                    ReceiverPhone = ro.ReceiverPhone,
                    Note = ro.Note
                }).ToList() : new List<ReconciliationOrderItem>()));

            CreateMap<ReconciliationOrder, ReconciliationOrderItem>();

            // Reconciliation to ReconciliationItem mapping
            CreateMap<Reconciliation, ReconciliationItem>()
                .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.FullName : ""))
                .ForMember(dest => dest.CustomerPhone, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.PhoneNumber : ""))
                .ForMember(dest => dest.VatCompanyName, opt => opt.MapFrom(src => src.VatInfo != null ? src.VatInfo.CompanyName : ""));

            // Order to ReconciliableOrderItem mapping
            CreateMap<Order, ReconciliableOrderItem>()
                .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.FullName : ""))
                .ForMember(dest => dest.CodAmount, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.CollectAmount : 0))
                .ForMember(dest => dest.ServiceFee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.TotalFee : 0))
                .ForMember(dest => dest.ReconciliationAmount, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.ReconciliationAmount : 0))
                .ForMember(dest => dest.CodStage, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.CodStage : OrderCodStage.NotCollected))
                .ForMember(dest => dest.OrderStatus, opt => opt.MapFrom(src => src.OrderOps != null ? src.OrderOps.Status : OrderStatus.New))
                .ForMember(dest => dest.DeliveredDate, opt => opt.Ignore()) // TODO: Lấy từ OrderTimeTrack
                .ForMember(dest => dest.CodCollectedDate, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.CodCollectedTime : null))
                .ForMember(dest => dest.ChargeWeight, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.ChargeWeight : 0))
                .ForMember(dest => dest.ShippingFee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.Fee : 0))
                .ForMember(dest => dest.DeliveryAddress, opt => opt.Ignore()) // TODO: Lấy từ OrderAddress
                .ForMember(dest => dest.ReceiverName, opt => opt.Ignore()); // TODO: Lấy từ OrderAddress

            // Order to TransferPaymentBillExportOrderItem mapping
            CreateMap<Order, TransferPaymentBillExportOrderItem>()
                // Thông tin chung
                .ForMember(dest => dest.OrderId, opt => opt.MapFrom(src => src.Id))
                .ForMember(dest => dest.OrderCode, opt => opt.MapFrom(src => src.Code))
                .ForMember(dest => dest.PartnerCode, opt => opt.MapFrom(src => src.PartnerCode))
                .ForMember(dest => dest.Note, opt => opt.MapFrom(src => src.Note))
                .ForMember(dest => dest.CustomerId, opt => opt.MapFrom(src => src.CustomerId))
                .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.FullName : ""))
                .ForMember(dest => dest.SaleId, opt => opt.MapFrom(src => src.SaleId))
                .ForMember(dest => dest.SaleName, opt => opt.Ignore()) // Sẽ được set trong service

                // Thông tin địa chỉ - sẽ được set trong service từ OrderAddress
                .ForMember(dest => dest.SenderName, opt => opt.Ignore())
                .ForMember(dest => dest.SenderAddress, opt => opt.Ignore())
                .ForMember(dest => dest.SenderPhone, opt => opt.Ignore())
                .ForMember(dest => dest.ReceiverName, opt => opt.Ignore())
                .ForMember(dest => dest.ReceiverAddress, opt => opt.Ignore())
                .ForMember(dest => dest.ReceiverPhone, opt => opt.Ignore())

                // Thông tin trạng thái
                .ForMember(dest => dest.OrderStatus, opt => opt.MapFrom(src => src.OrderOps != null ? src.OrderOps.Status.GetDescription() : ""))
                .ForMember(dest => dest.OrderPhysicalStatus, opt => opt.MapFrom(src => src.OrderOps != null ? src.OrderOps.PhysicalStatus.GetDescription() : ""))

                // Thông tin cước phí
                .ForMember(dest => dest.ChargeWeight, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.ChargeWeight : 0))
                .ForMember(dest => dest.Fee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.Fee : 0))
                .ForMember(dest => dest.CodFee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.CodFee : 0))
                .ForMember(dest => dest.PickupSubFee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.PickupSubFee : 0))
                .ForMember(dest => dest.DeliverySubFee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.DeliverySubFee : 0))
                .ForMember(dest => dest.Discount, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.Discount : 0))
                .ForMember(dest => dest.TotalFee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.TotalFee : 0))
                .ForMember(dest => dest.PayFeeType, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.PayFeeType.GetDescription() : ""))

                // Thông tin thu hộ
                .ForMember(dest => dest.CollectAmount, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.CollectAmount : 0))
                .ForMember(dest => dest.CodIncludeFee, opt => opt.MapFrom(src => src.OrderFin != null && src.OrderFin.PayFeeType == Lada.Framework.Data.Enums.OrderFinEnum.PayFeeType.COD))
                .ForMember(dest => dest.CodStage, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.CodStage.GetDescription() : ""))

                // Thông tin tài chính
                .ForMember(dest => dest.TransferFeeAmount, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.TransferFee : 0))
                .ForMember(dest => dest.TransferFeeStage, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.TransferFeeStage.GetDescription() : ""))
                .ForMember(dest => dest.SourceFee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.SourceFee : 0))
                .ForMember(dest => dest.SourceFeeStage, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.SourceFeeStage.GetDescription() : ""))
                .ForMember(dest => dest.DestFee, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.DestFee : 0))
                .ForMember(dest => dest.DestFeeStage, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.DestFeeStage.GetDescription() : ""))
                .ForMember(dest => dest.ReconciliationAmount, opt => opt.MapFrom(src => src.OrderFin != null ? src.OrderFin.ReconciliationAmount : 0))

                // Thông tin thời gian
                .ForMember(dest => dest.OrderCreatedTime, opt => opt.MapFrom(src => src.CreatedTime))
                .ForMember(dest => dest.PickupTime, opt => opt.MapFrom(src => src.OrderTimeTrack != null ? src.OrderTimeTrack.PickupTime : null))
                .ForMember(dest => dest.DeliveryTime, opt => opt.MapFrom(src => src.OrderTimeTrack != null ? src.OrderTimeTrack.DeliveryDate : null))

                // Thông tin hàng hóa - sẽ được set trong service từ OrderPackage
                .ForMember(dest => dest.TotalPackages, opt => opt.Ignore())
                .ForMember(dest => dest.TotalWeight, opt => opt.Ignore())
                .ForMember(dest => dest.PackageContent, opt => opt.Ignore())

                // Các field kế thừa từ BaseItem
                .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
                .ForMember(dest => dest.CreatedBy, opt => opt.MapFrom(src => src.CreatedBy))
                .ForMember(dest => dest.CreatedByUserName, opt => opt.MapFrom(src => src.CreatedByUserName))
                .ForMember(dest => dest.CreatedTime, opt => opt.MapFrom(src => src.CreatedTime))
                .ForMember(dest => dest.UpdatedBy, opt => opt.MapFrom(src => src.UpdatedBy))
                .ForMember(dest => dest.UpdatedByUserName, opt => opt.MapFrom(src => src.UpdatedByUserName))
                .ForMember(dest => dest.UpdatedTime, opt => opt.MapFrom(src => src.UpdatedTime));

            // TransferPaymentBill mappings
            CreateMap<TransferPaymentBill, TransferPaymentBillItem>()
                .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.FullName : ""))
                .ForMember(dest => dest.CustomerPhone, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.PhoneNumber : ""))
                .ForMember(dest => dest.CanCancel, opt => opt.Ignore()) // Sẽ được set trong service
                .ForMember(dest => dest.CanApprove, opt => opt.Ignore()); // Sẽ được set trong service

            CreateMap<TransferPaymentBill, TransferPaymentBillDetailModel>()
                .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.FullName : ""))
                .ForMember(dest => dest.CustomerPhone, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.PhoneNumber : ""))
                .ForMember(dest => dest.CustomerEmail, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.Email : ""))
                .ForMember(dest => dest.CustomerAddress, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.Address : ""))
                .ForMember(dest => dest.Orders, opt => opt.MapFrom(src => src.Orders))
                .ForMember(dest => dest.CanCancel, opt => opt.Ignore()) // Sẽ được set trong service
                .ForMember(dest => dest.CanApprove, opt => opt.Ignore()); // Sẽ được set trong service

            CreateMap<TransferPaymentBillOrder, TransferPaymentBillOrderItem>()
                .ForMember(dest => dest.SenderName, opt => opt.Ignore()) // Được mapping thủ công trong service từ OrderAddress
                .ForMember(dest => dest.SenderAddress, opt => opt.Ignore()) // Được mapping thủ công trong service từ OrderAddress
                .ForMember(dest => dest.ReceiverName, opt => opt.Ignore()) // Được mapping thủ công trong service từ OrderAddress
                .ForMember(dest => dest.ReceiverAddress, opt => opt.Ignore()) // Được mapping thủ công trong service từ OrderAddress
                .ForMember(dest => dest.OrderCreatedTime, opt => opt.MapFrom(src => src.Order != null ? src.Order.CreatedTime : DateTimeOffset.MinValue))
                .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.Order != null && src.Order.OrderOps != null ? src.Order.OrderOps.Status : OrderStatus.Unknown))
                .ForMember(dest => dest.PhysicalStatus, opt => opt.MapFrom(src => src.Order != null && src.Order.OrderOps != null ? src.Order.OrderOps.PhysicalStatus : OrderPhysicalStatus.Unknown));

            CreateMap<CreateTransferPaymentBillModel, TransferPaymentBill>()
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.Note, opt => opt.MapFrom(src => !string.IsNullOrEmpty(src.Note) ? src.Note.Trim() : ""))
                .ForMember(dest => dest.TransferInfo, opt => opt.MapFrom(src => !string.IsNullOrEmpty(src.TransferInfo) ? src.TransferInfo.Trim() : ""))
                .ForMember(dest => dest.Code, opt => opt.Ignore()) // Sẽ được generate trong service
                .ForMember(dest => dest.TotalAmount, opt => opt.Ignore()) // Sẽ được tính trong service
                .ForMember(dest => dest.OrderCount, opt => opt.Ignore()) // Sẽ được tính trong service
                .ForMember(dest => dest.Status, opt => opt.Ignore()) // Sẽ được set trong service
                .ForMember(dest => dest.Priority, opt => opt.Ignore()) // Sẽ được tính trong service
                .ForMember(dest => dest.Customer, opt => opt.Ignore())
                .ForMember(dest => dest.Orders, opt => opt.Ignore())
                .ForMember(dest => dest.Transaction, opt => opt.Ignore())
                .ForMember(dest => dest.ApprovedBy, opt => opt.Ignore())
                .ForMember(dest => dest.ApprovedByUsername, opt => opt.Ignore())
                .ForMember(dest => dest.ApprovedDate, opt => opt.Ignore())
                .ForMember(dest => dest.TransactionId, opt => opt.Ignore());

            // Bank mappings
            CreateMap<Bank, BankItem>();
            CreateMap<BankModel, Bank>();
            CreateMap<Bank, BankModel>();
            CreateMap<Bank, BankOptionItem>();

            // UserBankAccount mappings
            CreateMap<UserBankAccount, UserBankAccountItem>()
                .ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.User != null ? src.User.UserName : ""))
                .ForMember(dest => dest.BankCode, opt => opt.MapFrom(src => src.Bank != null ? src.Bank.BankCode : ""))
                .ForMember(dest => dest.BankName, opt => opt.MapFrom(src => src.Bank != null ? src.Bank.BrandName : ""))
                .ForMember(dest => dest.ExpenseCount, opt => opt.MapFrom(src => src.Expenses.Count(e => !e.IsDeleted)));
            CreateMap<UserBankAccount, UserBankAccountModel>();
            CreateMap<UserBankAccountModel, UserBankAccount>()
                .ForMember(dest => dest.CreatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.UpdatedTime, opt => opt.Ignore())
                .ForMember(dest => dest.IsDeleted, opt => opt.Ignore())
                .ForMember(dest => dest.User, opt => opt.Ignore())
                .ForMember(dest => dest.Bank, opt => opt.Ignore())
                .ForMember(dest => dest.Expenses, opt => opt.Ignore());

            // TaxInvoice mappings
            CreateMap<TaxInvoice, TaxInvoiceItem>()
                .ForMember(dest => dest.ReconciliationSlipCode, opt => opt.MapFrom(src => src.CustomerReconciliationSlip != null ? src.CustomerReconciliationSlip.Code : ""))
                .ForMember(dest => dest.TaxCode, opt => opt.MapFrom(src => src.VatInfo != null ? src.VatInfo.TaxCode : ""))
                .ForMember(dest => dest.CompanyName, opt => opt.MapFrom(src => src.VatInfo != null ? src.VatInfo.CompanyName : ""))
                .ForMember(dest => dest.Address, opt => opt.MapFrom(src => src.VatInfo != null ? src.VatInfo.Address : ""))
                .ForMember(dest => dest.InvoiceEmail, opt => opt.MapFrom(src => src.VatInfo != null ? src.VatInfo.InvoiceEmail : ""))
                .ForMember(dest => dest.Status, opt => opt.MapFrom(src => (int)src.Status))
                .ForMember(dest => dest.StatusName, opt => opt.MapFrom(src => src.Status.GetDescription()))
                .ForMember(dest => dest.PdfUrl, opt => opt.MapFrom(src => src.Media != null ? src.Media.SystemPath : ""));

            // VatInvoice mappings
            CreateMap<VatInvoice, VatInvoiceItem>();
            CreateMap<VatInvoiceModel, VatInvoice>();
            CreateMap<VatInvoice, VatInvoiceModel>();
        }

        /// <summary>
        /// Lấy tên hiển thị của trạng thái chi phí
        /// </summary>
        private static string GetExpenseStatusDisplay(ExpenseStatus? status)
        {
            if (!status.HasValue)
            {
                return "Tạo mới";
            }

            return status.Value switch
            {
                ExpenseStatus.Pending => "Chờ duyệt",
                ExpenseStatus.Approved => "Đã duyệt",
                ExpenseStatus.Rejected => "Đã từ chối",
                ExpenseStatus.Paid => "Đã thanh toán",
                _ => status.Value.ToString()
            };
        }
    }

    public static class FinanceMappingExtensions
    {
        // ExpenseCategory mapping extensions
        public static ExpenseCategoryItem ToItem(this ExpenseCategory entity)
            => entity.MapTo<ExpenseCategory, ExpenseCategoryItem>();

        public static ExpenseCategoryModel ToModel(this ExpenseCategory entity)
            => entity.MapTo<ExpenseCategory, ExpenseCategoryModel>();

        public static ExpenseCategory ToEntity(this ExpenseCategoryModel model)
            => model.MapTo<ExpenseCategoryModel, ExpenseCategory>();

        public static ExpenseItem ToItem(this Expense entity)
            => entity.MapTo<Expense, ExpenseItem>();

        public static ExpenseModel ToModel(this Expense entity)
            => entity.MapTo<Expense, ExpenseModel>();

        public static Expense ToEntity(this ExpenseModel model)
            => model.MapTo<ExpenseModel, Expense>();

        public static ExpenseHistoryItem ToItem(this ExpenseHistory entity)
            => entity.MapTo<ExpenseHistory, ExpenseHistoryItem>();

        public static ExpenseHistoryModel ToModel(this ExpenseHistory entity)
            => entity.MapTo<ExpenseHistory, ExpenseHistoryModel>();

        // IncomeCategory mapping extensions
        public static IncomeCategoryItem ToItem(this IncomeCategory entity)
            => entity.MapTo<IncomeCategory, IncomeCategoryItem>();

        public static IncomeCategoryModel ToModel(this IncomeCategory entity)
            => entity.MapTo<IncomeCategory, IncomeCategoryModel>();

        public static IncomeCategory ToEntity(this IncomeCategoryModel model)
            => model.MapTo<IncomeCategoryModel, IncomeCategory>();

        public static IncomeItem ToItem(this Income entity)
            => entity.MapTo<Income, IncomeItem>();

        public static IncomeModel ToModel(this Income entity)
            => entity.MapTo<Income, IncomeModel>();

        public static Income ToEntity(this IncomeModel model)
            => model.MapTo<IncomeModel, Income>();

        public static IncomeHistoryItem ToItem(this IncomeHistory entity)
            => entity.MapTo<IncomeHistory, IncomeHistoryItem>();

        public static IncomeHistoryModel ToModel(this IncomeHistory entity)
            => entity.MapTo<IncomeHistory, IncomeHistoryModel>();

        // Transaction mapping extensions
        public static TransactionItem ToItem(this Transaction entity)
            => entity.MapTo<Transaction, TransactionItem>();

        // Bank Management mapping extensions
        public static BankAccountItem ToItem(this BankAccount entity)
            => entity.MapTo<BankAccount, BankAccountItem>();

        public static BankTransactionItem ToItem(this BankTransaction entity)
            => entity.MapTo<BankTransaction, BankTransactionItem>();

        public static BankStatementImportItem ToItem(this BankStatementImport entity)
            => entity.MapTo<BankStatementImport, BankStatementImportItem>();

        public static TransactionOrderItem ToItem(this TransactionOrder entity)
            => entity.MapTo<TransactionOrder, TransactionOrderItem>();

        // Reconciliation mapping extensions
        public static ReconciliationItem ToItem(this Reconciliation entity)
            => entity.MapTo<Reconciliation, ReconciliationItem>();

        public static ReconciliationDetailModel ToDetailModel(this Reconciliation entity)
            => entity.MapTo<Reconciliation, ReconciliationDetailModel>();

        public static ReconciliationOrderItem ToItem(this ReconciliationOrder entity)
            => entity.MapTo<ReconciliationOrder, ReconciliationOrderItem>();

        // TransferPaymentBill mapping extensions
        public static TransferPaymentBillItem ToItem(this TransferPaymentBill entity)
            => entity.MapTo<TransferPaymentBill, TransferPaymentBillItem>();

        public static TransferPaymentBillDetailModel ToDetailModel(this TransferPaymentBill entity)
            => entity.MapTo<TransferPaymentBill, TransferPaymentBillDetailModel>();

        public static TransferPaymentBillOrderItem ToItem(this TransferPaymentBillOrder entity)
            => entity.MapTo<TransferPaymentBillOrder, TransferPaymentBillOrderItem>();

        public static TransferPaymentBill ToEntity(this CreateTransferPaymentBillModel model)
            => model.MapTo<CreateTransferPaymentBillModel, TransferPaymentBill>();

        // UserBankAccount mapping extensions
        public static UserBankAccountItem ToItem(this UserBankAccount entity)
            => entity.MapTo<UserBankAccount, UserBankAccountItem>();

        public static UserBankAccountModel ToModel(this UserBankAccount entity)
            => entity.MapTo<UserBankAccount, UserBankAccountModel>();

        public static UserBankAccount ToEntity(this UserBankAccountModel model)
            => model.MapTo<UserBankAccountModel, UserBankAccount>();

        // TaxInvoice mapping extensions
        public static TaxInvoiceItem ToItem(this TaxInvoice entity)
            => entity.MapTo<TaxInvoice, TaxInvoiceItem>();
    }

    /// <summary>
    /// Helper methods cho Transaction mapping
    /// </summary>
    public static class TransactionMappingHelpers
    {
        /// <summary>
        /// Lấy icon cho loại giao dịch
        /// </summary>
        public static string GetTransactionIcon(TransactionType transactionType)
        {
            return transactionType switch
            {
                TransactionType.Recharge => "💰", // Nạp tiền
                TransactionType.Withdraw => "💸", // Rút tiền
                TransactionType.OrderFee => "📦", // Cước đơn hàng
                TransactionType.CollectFromDriver => "🚛", // Thu tiền từ lái xe
                TransactionType.Reconciliation => "📊", // Đối soát
                TransactionType.CollectFromCustomer => "👤", // Thu tiền từ khách hàng
                TransactionType.Transfer => "🔄", // Chuyển tiền giữa các ví
                _ => "💳" // Mặc định
            };
        }

        /// <summary>
        /// Tạo mô tả ngắn gọn cho giao dịch
        /// </summary>
        public static string GetShortDescription(Transaction transaction)
        {
            if (!string.IsNullOrEmpty(transaction.Description))
            {
                return transaction.Description.Length > 50
                    ? transaction.Description.Substring(0, 47) + "..."
                    : transaction.Description;
            }

            return transaction.TransactionType switch
            {
                TransactionType.Recharge => "Nạp tiền vào ví",
                TransactionType.Withdraw => "Rút tiền từ ví",
                TransactionType.OrderFee => "Cước phí đơn hàng",
                TransactionType.CollectFromDriver => "Thu tiền từ lái xe",
                TransactionType.Reconciliation => "Đối soát với khách hàng",
                TransactionType.CollectFromCustomer => "Thu tiền từ khách hàng",
                TransactionType.Transfer => "Chuyển tiền giữa ví",
                _ => "Giao dịch ví"
            };
        }
    }
}