using Lada.Framework.Data.Domains;
using Lada.Framework.Data.Domains.Crm;
using Lada.Framework.Data.Domains.Finance;
using Lada.Framework.Data.Domains.Finance.Wallets;
using Lada.Framework.Data.Domains.Identity;
using Lada.Framework.Data.Domains.Orders;
using Lada.Framework.Data.Enums;
using Lada.Framework.Data.Repositories;
using Lada.Framework.DTO;
using Lada.Framework.DTO.SmartTable;
using Lada.Framework.Infrastructures;
using Lada.Framework.Infrastructures.Helpers;
using Ladaer.BackEnd.Infrastructures.DTO;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Crm;
using Ladaer.BackEnd.Infrastructures.DTO.Items.Finances;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Finances;
using Ladaer.BackEnd.Infrastructures.DTO.Models.Orders;
using Ladaer.BackEnd.Infrastructures.DTO.Profiles;
using Ladaer.BackEnd.Infrastructures.DTO.Results.Finances;
using Ladaer.BackEnd.Infrastructures.Services.Identity;
using Ladaer.BackEnd.Infrastructures.Services.Orders;
using Microsoft.EntityFrameworkCore;
using static Lada.Framework.Data.Enums.OrderFinEnum;

namespace Ladaer.BackEnd.Infrastructures.Services.Finances
{
    /// <summary>
    /// Giao diện cho dịch vụ quản lý đối soát.
    /// </summary>
    public interface IReconciliationService
    {
        /// <summary>
        /// Tìm kiếm khách hàng cần đối soát với phân trang.
        /// </summary>
        /// <param name="param">Tham số tìm kiếm.</param>
        /// <param name="userId">ID người dùng hiện tại.</param>
        /// <returns>Kết quả tìm kiếm khách hàng cần đối soát.</returns>
        Task<SmartTableResult<CustomerReconciliationSummaryItem>> SearchCustomersForReconciliation(SmartTableParam param, int userId);

        /// <summary>
        /// Tìm kiếm đơn hàng có thể đối soát với phân trang.
        /// </summary>
        /// <param name="param">Tham số tìm kiếm.</param>
        /// <param name="reconciliationType">Loại đối soát (tùy chọn).</param>
        /// <returns>Kết quả tìm kiếm đơn hàng có thể đối soát.</returns>
        Task<SmartTableResult<ReconciliableOrderItem>> SearchReconciliableOrders(SmartTableParam param, ReconciliationType? reconciliationType = null);

        /// <summary>
        /// Tìm kiếm đối soát.
        /// </summary>
        /// <param name="param">Tham số tìm kiếm.</param>
        /// <param name="userId">ID người dùng hiện tại.</param>
        /// <returns>Kết quả tìm kiếm đối soát.</returns>
        Task<SmartTableResult<ReconciliationItem>> Search(SmartTableParam param, int userId);

        /// <summary>
        /// Lấy chi tiết đối soát.
        /// </summary>
        /// <param name="id">ID đối soát.</param>
        /// <returns>Chi tiết đối soát.</returns>
        Task<ReconciliationDetailModel?> GetById(int id, CurrentUser currentUser);

        /// <summary>
        /// Tạo đối soát mới.
        /// </summary>
        /// <param name="model">Thông tin đối soát.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<ReconciliationResult> Create(CreateReconciliationModel model);

        /// <summary>
        /// Xác nhận đối soát.
        /// </summary>
        /// <param name="id">ID đối soát.</param>
        /// <param name="currentUser">Thông tin người dùng hiện tại.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> Confirm(int id, CurrentUser currentUser);

        /// <summary>
        /// Cập nhật đã chuyển khoản.
        /// </summary>
        /// <param name="model">Thông tin chuyển khoản.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> UpdateTransferred(TransferReconciliationModel model);

        /// <summary>
        /// Hủy đối soát với thông tin chi tiết.
        /// </summary>
        /// <param name="model">Thông tin hủy đối soát.</param>
        /// <returns>Kết quả của thao tác.</returns>
        Task<BaseResult> Cancel(CancelReconciliationModel model);

        /// <summary>
        /// Hủy đối soát (phương thức cũ - deprecated).
        /// </summary>
        /// <param name="id">ID đối soát.</param>
        /// <param name="currentUser">Thông tin người dùng hiện tại.</param>
        /// <returns>Kết quả của thao tác.</returns>
        [Obsolete("Sử dụng Cancel(CancelReconciliationModel model) thay thế")]
        Task<BaseResult> Cancel(int id, CurrentUser currentUser);
    }

    /// <summary>
    /// Dịch vụ quản lý đối soát.
    /// </summary>
    public class ReconciliationService : IReconciliationService
    {
        private readonly IRepository<Reconciliation> _reconciliationRepository;
        private readonly IRepository<ReconciliationOrder> _reconciliationOrderRepository;
        private readonly IRepository<Order> _orderRepository;
        private readonly IRepository<OrderFin> _orderFinRepository;
        private readonly IRepository<Customer> _customerRepository;
        private readonly IRepository<Wallet> _walletRepository;
        private readonly IRepository<Transaction> _transactionRepository;
        private readonly IOrderTrackService _orderTrackService;
        private readonly IUserService _userService;

        /// <summary>
        /// Khởi tạo dịch vụ quản lý đối soát.
        /// </summary>
        public ReconciliationService(
            IRepository<Reconciliation> reconciliationRepository,
            IRepository<ReconciliationOrder> reconciliationOrderRepository,
            IRepository<Order> orderRepository,
            IRepository<OrderFin> orderFinRepository,
            IRepository<Customer> customerRepository,
            IRepository<Wallet> walletRepository,
            IRepository<Transaction> transactionRepository,
            IOrderTrackService orderTrackService,
            IUserService userService)
        {
            _reconciliationRepository = reconciliationRepository;
            _reconciliationOrderRepository = reconciliationOrderRepository;
            _orderRepository = orderRepository;
            _orderFinRepository = orderFinRepository;
            _customerRepository = customerRepository;
            _walletRepository = walletRepository;
            _transactionRepository = transactionRepository;
            _orderTrackService = orderTrackService;
            _userService = userService;
        }

        /// <summary>
        /// Tìm kiếm khách hàng cần đối soát với phân trang.
        /// </summary>
        public async Task<SmartTableResult<CustomerReconciliationSummaryItem>> SearchCustomersForReconciliation(SmartTableParam param, int userId)
        {
            // Kiểm tra quyền của user hiện tại
            var userRoles = await _userService.GetRolesAsync(userId);
            var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));
            var canConfirm = isFounder || userRoles.Any(r => r.Equals("Reconciliation.Confirm", StringComparison.OrdinalIgnoreCase));
            var canTransfer = isFounder || userRoles.Any(r => r.Equals("Reconciliation.Transfer", StringComparison.OrdinalIgnoreCase));

            // Query đơn hàng có CodStage = Head (đã về tổng, chờ đối soát)
            // Bao gồm cả đơn có tiền thu hộ (CollectAmount > 0) và đơn không có tiền thu hộ (CollectAmount = 0)
            var orderQuery = _orderRepository.Query()
                .Include(o => o.OrderFin)
                .Include(o => o.Customer)
                .Where(o => o.OrderFin.CodStage == OrderCodStage.Head);

            // Filter theo ManagerId nếu không phải Founder
            if (!isFounder)
            {
                orderQuery = orderQuery.Where(o => o.Customer.ManagerId == userId);
            }

            // Apply filters from param.Search.PredicateObject
            if (param.Search?.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;

                // Filter theo keyword (tên khách hàng, số điện thoại, email)
                if (search.Keyword != null)
                {
                    string keyword = search.Keyword;
                    keyword = keyword.Trim().ToLower();
                    if (!string.IsNullOrEmpty(keyword))
                    {
                        orderQuery = orderQuery.Where(o =>
                            o.Customer.FullName.ToLower().Contains(keyword) ||
                            o.Customer.PhoneNumber.Contains(keyword) ||
                            (!string.IsNullOrEmpty(o.Customer.Email) && o.Customer.Email.ToLower().Contains(keyword)));
                    }
                }

                // Filter theo thời gian tạo đơn hàng
                if (search.CreatedStart != null && search.CreatedEnd != null)
                {
                    DateTimeOffset start = search.CreatedStart;
                    DateTimeOffset end = search.CreatedEnd;
                    DateTimeOffset startParam = start.StartOfDay();
                    DateTimeOffset endParam = end.EndOfDay();
                    orderQuery = orderQuery.Where(o => o.CreatedTime >= startParam && o.CreatedTime <= endParam);
                }

                // Filter theo ID khách hàng
                if (search.CustomerId != null)
                {
                    int customerId = (int)search.CustomerId;
                    if (customerId > 0)
                    {
                        orderQuery = orderQuery.Where(o => o.CustomerId == customerId);
                    }
                }

                // Filter theo số tiền COD tối thiểu
                if (search.MinCodAmount != null)
                {
                    decimal minAmount = search.MinCodAmount;
                    if (minAmount > 0)
                    {
                        orderQuery = orderQuery.Where(o => o.OrderFin.CollectAmount >= minAmount);
                    }
                }

                // Filter theo số tiền COD tối đa
                if (search.MaxCodAmount != null)
                {
                    decimal maxAmount = search.MaxCodAmount;
                    if (maxAmount > 0)
                    {
                        orderQuery = orderQuery.Where(o => o.OrderFin.CollectAmount <= maxAmount);
                    }
                }
            }

            // Load orders vào memory để tính toán ReconciliationAmount
            var ordersWithFin = await orderQuery.ToListAsync();

            // Group theo khách hàng và tạo summary
            var customerSummaryQuery = ordersWithFin
                .GroupBy(o => new
                {
                    o.CustomerId,
                    o.Customer.FullName,
                    o.Customer.PhoneNumber,
                    o.Customer.Email
                })
                .Select(g => new CustomerReconciliationSummaryItem
                {
                    CustomerId = g.Key.CustomerId,
                    CustomerName = g.Key.FullName,
                    CustomerPhone = g.Key.PhoneNumber,
                    CustomerEmail = g.Key.Email,
                    PendingOrderCount = g.Count(),
                    PendingCodAmount = g.Sum(o => o.OrderFin?.CollectAmount ?? 0),
                    EstimatedFeeAmount = g.Sum(o => o.OrderFin?.TotalFee ?? 0),
                    EstimatedReconciliationAmount = g.Sum(o => o.OrderFin?.ReconciliationAmount ?? 0),
                    OldestOrderDate = g.Min(o => o.CreatedTime),
                    LatestOrderDate = g.Max(o => o.CreatedTime)
                })
                .AsQueryable();

            // Apply sorting
            if (!string.IsNullOrEmpty(param.Sort?.Predicate))
            {
                if (param.Sort.Reverse)
                {
                    customerSummaryQuery = param.Sort.Predicate.ToLower() switch
                    {
                        "customername" => customerSummaryQuery.OrderByDescending(c => c.CustomerName),
                        "customerphone" => customerSummaryQuery.OrderByDescending(c => c.CustomerPhone),
                        "pendingordercount" => customerSummaryQuery.OrderByDescending(c => c.PendingOrderCount),
                        "pendingcodamount" => customerSummaryQuery.OrderByDescending(c => c.PendingCodAmount),
                        "estimatedfeeamount" => customerSummaryQuery.OrderByDescending(c => c.EstimatedFeeAmount),
                        "estimatedreconciliationamount" => customerSummaryQuery.OrderByDescending(c => c.EstimatedReconciliationAmount),
                        "estimatednetamount" => customerSummaryQuery.OrderByDescending(c => c.EstimatedNetAmount),
                        "oldestorderdate" => customerSummaryQuery.OrderByDescending(c => c.OldestOrderDate),
                        "latestorderdate" => customerSummaryQuery.OrderByDescending(c => c.LatestOrderDate),
                        _ => customerSummaryQuery.OrderByDescending(c => c.PendingCodAmount)
                    };
                }
                else
                {
                    customerSummaryQuery = param.Sort.Predicate.ToLower() switch
                    {
                        "customername" => customerSummaryQuery.OrderBy(c => c.CustomerName),
                        "customerphone" => customerSummaryQuery.OrderBy(c => c.CustomerPhone),
                        "pendingordercount" => customerSummaryQuery.OrderBy(c => c.PendingOrderCount),
                        "pendingcodamount" => customerSummaryQuery.OrderBy(c => c.PendingCodAmount),
                        "estimatedfeeamount" => customerSummaryQuery.OrderBy(c => c.EstimatedFeeAmount),
                        "estimatedreconciliationamount" => customerSummaryQuery.OrderBy(c => c.EstimatedReconciliationAmount),
                        "estimatednetamount" => customerSummaryQuery.OrderBy(c => c.EstimatedNetAmount),
                        "oldestorderdate" => customerSummaryQuery.OrderBy(c => c.OldestOrderDate),
                        "latestorderdate" => customerSummaryQuery.OrderBy(c => c.LatestOrderDate),
                        _ => customerSummaryQuery.OrderBy(c => c.PendingCodAmount)
                    };
                }
            }
            else
            {
                // Default sorting: theo số tiền COD giảm dần
                customerSummaryQuery = customerSummaryQuery.OrderByDescending(c => c.PendingCodAmount);
            }

            // Thực hiện query để lấy dữ liệu
            var allCustomerSummaries = customerSummaryQuery.ToList();

            // Lấy thông tin đối soát đã hoàn thành cho từng khách hàng
            foreach (var summary in allCustomerSummaries)
            {
                var completedReconciliations = await _reconciliationRepository.Query()
                    .Where(r => r.CustomerId == summary.CustomerId
                        && r.Status == ReconciliationStatus.Transferred)
                    .ToListAsync();

                summary.CompletedReconciliationCount = completedReconciliations.Count;
                summary.CompletedReconciliationAmount = completedReconciliations.Sum(r => r.NetAmount);

                // Set quyền cho từng khách hàng
                summary.CanConfirm = canConfirm;
                summary.CanTransfer = canTransfer;

                // TODO: Lấy thông tin tài khoản ngân hàng mặc định
                // summary.HasDefaultBankAccount = ...
                // summary.DefaultBankAccountInfo = ...
            }

            // Tính toán phân trang thủ công
            var totalRecord = allCustomerSummaries.Count;

            if (param.Pagination.PageIndex <= 0)
                param.Pagination.PageIndex = 1;
            if (param.Pagination.PageSize <= 0)
                param.Pagination.PageSize = 15;

            var pagedData = allCustomerSummaries
                .Skip(param.Pagination.Start)
                .Take(param.Pagination.PageSize)
                .ToList();

            return new SmartTableResult<CustomerReconciliationSummaryItem>
            {
                Items = pagedData,
                TotalRecord = totalRecord,
                NumberOfPages = (int)Math.Ceiling((double)totalRecord / param.Pagination.PageSize)
            };
        }

        /// <summary>
        /// Tìm kiếm đơn hàng có thể đối soát với phân trang.
        /// </summary>
        /// <param name="param">Tham số tìm kiếm</param>
        /// <param name="reconciliationType">Loại đối soát (tùy chọn)</param>
        public async Task<SmartTableResult<ReconciliableOrderItem>> SearchReconciliableOrders(SmartTableParam param, ReconciliationType? reconciliationType = null)
        {
            var query = _orderRepository.Query()
                .Include(o => o.OrderFin)
                .Include(o => o.OrderOps)
                .Include(o => o.Customer)
                .Where(o => o.OrderFin.CodStage == OrderCodStage.Head);

            // Áp dụng filter theo loại đối soát
            if (reconciliationType.HasValue)
            {
                if (reconciliationType.Value == ReconciliationType.CollectMoney)
                {
                    // Đối soát tiền thu hộ: chỉ những đơn có CollectAmount > 0
                    query = query.Where(o => o.OrderFin.CollectAmount > 0);
                }
                else if (reconciliationType.Value == ReconciliationType.ShippingFee)
                {
                    // Đối soát cước: những đơn có CollectAmount = 0
                    query = query.Where(o => o.OrderFin.CollectAmount == 0);
                }
            }

            // Apply filters from param.Search.PredicateObject
            if (param.Search?.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;

                // Filter theo ID khách hàng (bắt buộc)
                if (search.CustomerId != null)
                {
                    int customerId = (int)search.CustomerId;
                    if (customerId > 0)
                    {
                        query = query.Where(o => o.CustomerId == customerId);
                    }
                    else
                    {
                        // Nếu không có customerId hợp lệ, trả về kết quả rỗng
                        return new SmartTableResult<ReconciliableOrderItem>
                        {
                            Items = new List<ReconciliableOrderItem>(),
                            TotalRecord = 0,
                            NumberOfPages = 0
                        };
                    }
                }
                else
                {
                    // Nếu không có customerId, trả về kết quả rỗng
                    return new SmartTableResult<ReconciliableOrderItem>
                    {
                        Items = new List<ReconciliableOrderItem>(),
                        TotalRecord = 0,
                        NumberOfPages = 0
                    };
                }

                // Filter theo keyword (mã đơn hàng, mã đối tác, tên khách hàng)
                if (search.Keyword != null)
                {
                    string keyword = search.Keyword;
                    keyword = keyword.Trim().ToLower();
                    if (!string.IsNullOrEmpty(keyword))
                    {
                        query = query.Where(o =>
                            o.Code.ToLower().Contains(keyword) ||
                            (!string.IsNullOrEmpty(o.PartnerCode) && o.PartnerCode.ToLower().Contains(keyword)) ||
                            (o.Customer != null && o.Customer.FullName.ToLower().Contains(keyword)));
                    }
                }

                // Filter theo thời gian tạo đơn hàng
                if (search.CreatedStart != null && search.CreatedEnd != null)
                {
                    DateTimeOffset start = search.CreatedStart;
                    DateTimeOffset end = search.CreatedEnd;
                    DateTimeOffset startParam = start.StartOfDay();
                    DateTimeOffset endParam = end.EndOfDay();
                    query = query.Where(o => o.CreatedTime >= startParam && o.CreatedTime <= endParam);
                }

                // Filter theo thời gian thu COD
                if (search.CodCollectedStart != null && search.CodCollectedEnd != null)
                {
                    DateTimeOffset start = search.CodCollectedStart;
                    DateTimeOffset end = search.CodCollectedEnd;
                    DateTimeOffset startParam = start.StartOfDay();
                    DateTimeOffset endParam = end.EndOfDay();
                    query = query.Where(o => o.OrderFin.CodCollectedTime >= startParam && o.OrderFin.CodCollectedTime <= endParam);
                }

                // Filter theo số tiền COD tối thiểu
                if (search.MinCodAmount != null)
                {
                    decimal minAmount = search.MinCodAmount;
                    if (minAmount > 0)
                    {
                        query = query.Where(o => o.OrderFin.CollectAmount >= minAmount);
                    }
                }

                // Filter theo số tiền COD tối đa
                if (search.MaxCodAmount != null)
                {
                    decimal maxAmount = search.MaxCodAmount;
                    if (maxAmount > 0)
                    {
                        query = query.Where(o => o.OrderFin.CollectAmount <= maxAmount);
                    }
                }

                // Filter theo trạng thái đơn hàng
                if (search.OrderStatus != null)
                {
                    OrderStatus status = search.OrderStatus;
                    query = query.Where(o => o.OrderOps.Status == status);
                }

                // Filter theo trọng lượng tính cước tối thiểu
                if (search.MinChargeWeight != null)
                {
                    decimal minWeight = search.MinChargeWeight;
                    if (minWeight > 0)
                    {
                        query = query.Where(o => o.OrderFin.ChargeWeight >= minWeight);
                    }
                }

                // Filter theo trọng lượng tính cước tối đa
                if (search.MaxChargeWeight != null)
                {
                    decimal maxWeight = search.MaxChargeWeight;
                    if (maxWeight > 0)
                    {
                        query = query.Where(o => o.OrderFin.ChargeWeight <= maxWeight);
                    }
                }
            }
            else
            {
                // Nếu không có search parameters, trả về kết quả rỗng vì cần customerId
                return new SmartTableResult<ReconciliableOrderItem>
                {
                    Items = new List<ReconciliableOrderItem>(),
                    TotalRecord = 0,
                    NumberOfPages = 0
                };
            }

            // Apply sorting
            if (!string.IsNullOrEmpty(param.Sort?.Predicate))
            {
                if (param.Sort.Reverse)
                {
                    query = param.Sort.Predicate.ToLower() switch
                    {
                        "code" => query.OrderByDescending(o => o.Code),
                        "partnercode" => query.OrderByDescending(o => o.PartnerCode),
                        "customername" => query.OrderByDescending(o => o.Customer.FullName),
                        "codamount" => query.OrderByDescending(o => o.OrderFin.CollectAmount),
                        "servicefee" => query.OrderByDescending(o => o.OrderFin.Fee + o.OrderFin.PickupSubFee + o.OrderFin.DeliverySubFee + o.OrderFin.CodFee + o.OrderFin.VatFee + o.OrderFin.InsuranceFee + o.OrderFin.ReturnFee - o.OrderFin.Discount),
                        "chargeweight" => query.OrderByDescending(o => o.OrderFin.ChargeWeight),
                        "shippingfee" => query.OrderByDescending(o => o.OrderFin.Fee),
                        "orderstatus" => query.OrderByDescending(o => o.OrderOps.Status),
                        "codcollecteddate" => query.OrderByDescending(o => o.OrderFin.CodCollectedTime),
                        "createdtime" => query.OrderByDescending(o => o.CreatedTime),
                        "updatedtime" => query.OrderByDescending(o => o.UpdatedTime),
                        _ => query.OrderByDescending(o => o.CreatedTime)
                    };
                }
                else
                {
                    query = param.Sort.Predicate.ToLower() switch
                    {
                        "code" => query.OrderBy(o => o.Code),
                        "partnercode" => query.OrderBy(o => o.PartnerCode),
                        "customername" => query.OrderBy(o => o.Customer.FullName),
                        "codamount" => query.OrderBy(o => o.OrderFin.CollectAmount),
                        "servicefee" => query.OrderBy(o => o.OrderFin.Fee + o.OrderFin.PickupSubFee + o.OrderFin.DeliverySubFee + o.OrderFin.CodFee + o.OrderFin.VatFee + o.OrderFin.InsuranceFee + o.OrderFin.ReturnFee - o.OrderFin.Discount),
                        "chargeweight" => query.OrderBy(o => o.OrderFin.ChargeWeight),
                        "shippingfee" => query.OrderBy(o => o.OrderFin.Fee),
                        "orderstatus" => query.OrderBy(o => o.OrderOps.Status),
                        "codcollecteddate" => query.OrderBy(o => o.OrderFin.CodCollectedTime),
                        "createdtime" => query.OrderBy(o => o.CreatedTime),
                        "updatedtime" => query.OrderBy(o => o.UpdatedTime),
                        _ => query.OrderBy(o => o.CreatedTime)
                    };
                }
            }
            else
            {
                // Default sorting: theo thời gian tạo giảm dần
                query = query.OrderByDescending(o => o.CreatedTime);
            }

            // Convert to SmartTableResult với phân trang sử dụng AutoMapper
            var result = await query.ToSmartTableResultAsync(param, o => o.MapTo<Order, ReconciliableOrderItem>());

            return result;
        }

        /// <summary>
        /// Tìm kiếm đối soát.
        /// </summary>
        public async Task<SmartTableResult<ReconciliationItem>> Search(SmartTableParam param, int userId)
        {
            // Kiểm tra quyền của user hiện tại
            var userRoles = await _userService.GetRolesAsync(userId);
            var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));
            var isAccountant = userRoles.Any(r => r.Equals("Accountant", StringComparison.OrdinalIgnoreCase));
            var canConfirm = isFounder || userRoles.Any(r => r.Equals("Reconciliation.Confirm", StringComparison.OrdinalIgnoreCase));
            var canTransfer = isFounder || userRoles.Any(r => r.Equals("Reconciliation.Transfer", StringComparison.OrdinalIgnoreCase));

            IQueryable<Reconciliation> query = _reconciliationRepository.Query()
                .Include(r => r.Customer);

            // Filter theo quyền: Founder xem tất cả, user thường chỉ xem phiếu do mình tạo hoặc của khách hàng do mình quản lý
            if (!isFounder && !isAccountant)
            {
                query = query.Where(r => r.CreatedBy == userId || r.Customer.ManagerId == userId);
            }

            // Apply filters from param.Search.PredicateObject
            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;

                if (search.Keyword != null)
                {
                    string keyword = search.Keyword;
                    keyword = keyword.Trim().ToLower();
                    if (!string.IsNullOrEmpty(keyword))
                    {
                        query = query.Where(r => r.Code.ToLower().Contains(keyword) ||
                                               (r.Customer != null && r.Customer.FullName.ToLower().Contains(keyword)));
                    }
                }

                if (search.CustomerId != null)
                {
                    int customerId = (int)search.CustomerId;
                    if (customerId > 0)
                    {
                        query = query.Where(r => r.CustomerId == customerId);
                    }
                }

                if (search.Status != null)
                {
                    ReconciliationStatus status = (ReconciliationStatus)search.Status;
                    query = query.Where(r => r.Status == status);
                }

                if (search.CreatedStart != null && search.CreatedEnd != null)
                {
                    DateTimeOffset start = search.CreatedStart;
                    DateTimeOffset end = search.CreatedEnd;
                    DateTimeOffset startParam = start.StartOfDay();
                    DateTimeOffset endParam = end.EndOfDay();
                    query = query.Where(r => r.CreatedTime >= startParam && r.CreatedTime <= endParam);
                }
            }

            // Apply sorting
            if (!string.IsNullOrEmpty(param.Sort.Predicate))
            {
                if (param.Sort.Reverse)
                {
                    query = param.Sort.Predicate.ToLower() switch
                    {
                        "code" => query.OrderByDescending(r => r.Code),
                        "customername" => query.OrderByDescending(r => r.Customer.FullName),
                        "netamount" => query.OrderByDescending(r => r.NetAmount),
                        "status" => query.OrderByDescending(r => r.Status),
                        "createdtime" => query.OrderByDescending(r => r.CreatedTime),
                        _ => query.OrderByDescending(r => r.CreatedTime)
                    };
                }
                else
                {
                    query = param.Sort.Predicate.ToLower() switch
                    {
                        "code" => query.OrderBy(r => r.Code),
                        "customername" => query.OrderBy(r => r.Customer.FullName),
                        "netamount" => query.OrderBy(r => r.NetAmount),
                        "status" => query.OrderBy(r => r.Status),
                        "createdtime" => query.OrderBy(r => r.CreatedTime),
                        _ => query.OrderBy(r => r.CreatedTime)
                    };
                }
            }
            else
            {
                query = query.OrderByDescending(r => r.CreatedTime);
            }

            // Apply default sorting
            param.Sort = new Sort() { Predicate = "CreatedTime", Reverse = true };
            var result = await query.ToSmartTableResultAsync(param, r => r.ToItem());

            // Set quyền cho từng item
            if (result.Items != null)
            {
                foreach (var item in result.Items)
                {
                    item.HasConfirmPermission = canConfirm;
                    item.HasTransferPermission = canTransfer;
                }
            }

            return result;
        }

        /// <summary>
        /// Lấy chi tiết đối soát.
        /// </summary>
        public async Task<ReconciliationDetailModel?> GetById(int id, CurrentUser currentUser)
        {
            var userRoles = await _userService.GetRolesAsync(currentUser.UserId);
            var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));
            var canConfirm = isFounder || userRoles.Any(r => r.Equals("Reconciliation.Confirm", StringComparison.OrdinalIgnoreCase));
            var canTransfer = isFounder || userRoles.Any(r => r.Equals("Reconciliation.Transfer", StringComparison.OrdinalIgnoreCase));


            var reconciliation = await _reconciliationRepository.Query()
                .Include(r => r.Customer)
                .Include(r => r.VatInfo)
                .Include(r => r.Orders)
                .ThenInclude(ro => ro.Order)
                .FirstOrDefaultAsync(r => r.Id == id);

            if (reconciliation == null)
                return null;

            var model = reconciliation.ToDetailModel();
            model.CanConfirm = canConfirm && model.Status == ReconciliationStatus.Draft;
            model.CanTransfer = canTransfer && model.Status == ReconciliationStatus.Confirmed;
            return model;
        }

        /// <summary>
        /// Tạo đối soát mới.
        /// </summary>
        public async Task<ReconciliationResult> Create(CreateReconciliationModel model)
        {
            var result = new ReconciliationResult { Result = Result.Success };

            try
            {
                // Validate
                var validationErrors = model.Validate();
                if (validationErrors.Any())
                {
                    result.Result = Result.Failed;
                    result.Message = string.Join("; ", validationErrors);
                    return result;
                }

                // Kiểm tra khách hàng
                var customer = await _customerRepository.Query()
                    .FirstOrDefaultAsync(c => c.Id == model.CustomerId);
                if (customer == null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Không tìm thấy khách hàng";
                    return result;
                }

                // Kiểm tra quyền tạo đối soát với khách hàng
                var userRoles = await _userService.GetRolesAsync(model.CreatedBy);
                var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));

                if (!isFounder && customer.ManagerId != model.CreatedBy)
                {
                    result.Result = Result.Failed;
                    result.Message = "Bạn chỉ được phép tạo đối soát với khách hàng do mình quản lý";
                    return result;
                }

                // Kiểm tra VatInfo nếu có
                if (model.VatInfoId.HasValue)
                {
                    var vatInfo = await _customerRepository.Query()
                        .Where(c => c.Id == model.CustomerId)
                        .SelectMany(c => c.VatInfos)
                        .FirstOrDefaultAsync(v => v.Id == model.VatInfoId.Value);

                    if (vatInfo == null)
                    {
                        result.Result = Result.Failed;
                        result.Message = "Không tìm thấy thông tin xuất hóa đơn VAT";
                        return result;
                    }
                }

                // Kiểm tra đơn hàng dựa trên loại đối soát
                var orderQuery = _orderRepository.Query()
                    .Include(o => o.OrderFin)
                    .Include(o => o.OrderOps)
                    .Where(o => model.OrderIds.Contains(o.Id)
                        && o.CustomerId == model.CustomerId
                        && o.OrderFin.CodStage == OrderCodStage.Head);

                // Áp dụng filter theo loại đối soát
                if (model.Type == ReconciliationType.CollectMoney)
                {
                    // Đối soát tiền thu hộ: chỉ những đơn có CollectAmount > 0
                    orderQuery = orderQuery.Where(o => o.OrderFin.CollectAmount > 0);
                }
                else if (model.Type == ReconciliationType.ShippingFee)
                {
                    // Đối soát cước: những đơn có CollectAmount = 0
                    orderQuery = orderQuery.Where(o => o.OrderFin.CollectAmount == 0);
                }

                var orders = await orderQuery.ToListAsync();

                if (orders.Count != model.OrderIds.Count)
                {
                    result.Result = Result.Failed;
                    result.Message = "Một số đơn hàng không hợp lệ hoặc không thể đối soát";
                    return result;
                }

                // Tạo mã đối soát
                var reconciliationCode = await GenerateReconciliationCode();

                // Tính toán số tiền theo logic mới dựa trên PayFeeType
                var totalCodAmount = orders.Sum(o => o.OrderFin?.CollectAmount ?? 0);
                var totalFeeAmount = orders.Sum(o => o.OrderFin?.TotalFee ?? 0);
                var netAmount = orders.Sum(o => o.OrderFin?.ReconciliationAmount ?? 0);

                // Tạo đối soát
                var reconciliation = new Reconciliation
                {
                    Code = reconciliationCode,
                    CustomerId = model.CustomerId,
                    FromDate = model.FromDate,
                    ToDate = model.ToDate,
                    TotalCodAmount = totalCodAmount,
                    TotalFeeAmount = totalFeeAmount,
                    NetAmount = netAmount,
                    OrderCount = orders.Count,
                    Status = model.AutoConfirm ? ReconciliationStatus.Confirmed : ReconciliationStatus.Draft,
                    Type = model.Type,
                    VatInfoId = model.VatInfoId,
                    BankAccountNumber = model.BankAccountNumber,
                    BankAccountHolderName = model.BankAccountHolderName,
                    BankCode = model.BankCode,
                    BankName = model.BankName,
                    BankBranchName = model.BankBranchName,
                    BankBranchAddress = model.BankBranchAddress,
                    Note = model.Note,
                    TransferInfo = model.TransferInfo,
                    CreatedBy = model.CreatedBy,
                    CreatedByUserName = model.CreatedByUsername
                };

                reconciliation = reconciliation.UpdateCommonInt(model.CreatedBy, model.CreatedByUsername);

                if (model.AutoConfirm)
                {
                    reconciliation.ApprovedBy = model.CreatedBy;
                    reconciliation.ApprovedByUsername = model.CreatedByUsername;
                }

                await _reconciliationRepository.InsertAsync(reconciliation);

                // Tạo chi tiết đơn hàng
                foreach (var order in orders)
                {
                    var reconciliationOrder = new ReconciliationOrder
                    {
                        ReconciliationId = reconciliation.Id,
                        OrderId = order.Id,
                        OrderCode = order.Code,
                        PartnerCode = order.PartnerCode,
                        CodAmount = order.OrderFin?.CollectAmount ?? 0,
                        FeeAmount = order.OrderFin?.TotalFee ?? 0,
                        NetAmount = order.OrderFin?.ReconciliationAmount ?? 0,
                        DeliveredDate = null, // TODO: Lấy từ OrderTimeTrack
                        CodCollectedDate = order.OrderFin?.CodCollectedTime,
                        ChargeWeight = order.OrderFin?.ChargeWeight ?? 0,
                        ShippingFee = order.OrderFin?.Fee ?? 0,
                        DeliveryAddress = "", // TODO: Lấy từ OrderAddress
                        ReceiverName = "", // TODO: Lấy từ OrderAddress
                        ReceiverPhone = "" // TODO: Lấy từ OrderAddress
                    };

                    reconciliationOrder = reconciliationOrder.UpdateCommonInt(model.CreatedBy, model.CreatedByUsername);
                    await _reconciliationOrderRepository.InsertAsync(reconciliationOrder);
                }

                // Cập nhật CodStage của đơn hàng
                foreach (var order in orders)
                {
                    if (order.OrderFin != null)
                    {
                        order.OrderFin.CodStage = OrderCodStage.WaitToTransfer;
                        order.OrderFin.UpdateCommonInt(model.CreatedBy, model.CreatedByUsername);
                        await _orderFinRepository.UpdateAsync(order.OrderFin);
                    }
                }

                // Tạo hành trình cho các đơn hàng
                var trackModels = new List<OrderTrackModel>();
                foreach (var order in orders)
                {
                    var trackModel = new OrderTrackModel()
                    {
                        OrderId = order.Id,
                        OrderCode = order.Code,
                        Name = $"Đơn hàng được đưa vào đối soát {reconciliationCode}",
                        OrderTrackType = OrderTrackType.ForInternal,
                        TrackActionType = TrackActionType.ReconciliationCreate,
                        PicId = model.CreatedBy,
                        PicUserName = model.CreatedByUsername,
                        UpdatedBy = model.CreatedBy,
                        UpdatedByUserName = model.CreatedByUsername,
                        ActionSource = ActionSource.InternalWeb,
                        PhoneContact = ""
                    };
                    trackModels.Add(trackModel);
                }

                if (trackModels.Any())
                {
                    await _orderTrackService.CreateAsync(trackModels);
                }

                result.Message = "Tạo đối soát thành công";

                // Load customer để mapping
                reconciliation.Customer = customer;
                result.Data = reconciliation.ToItem();
            }
            catch (Exception ex)
            {
                result.Result = Result.Failed;
                result.Message = $"Lỗi khi tạo đối soát: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Xác nhận đối soát.
        /// </summary>
        public async Task<BaseResult> Confirm(int id, CurrentUser currentUser)
        {
            var result = new BaseResult { Result = Result.Success };
            var userRoles = await _userService.GetRolesAsync(currentUser.UserId);
            var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));

            var canConfirm = isFounder || userRoles.Any(r => r.Equals("Reconciliation.Confirm", StringComparison.OrdinalIgnoreCase));
            if (!isFounder && !canConfirm)
            {
                result.Result = Result.Failed;
                result.Message = "Bạn không thể xác nhận đối soát do không có quyền";
                return result;
            }
            try
            {
                var reconciliation = await _reconciliationRepository.Query()
                    .FirstOrDefaultAsync(r => r.Id == id);

                if (reconciliation == null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Không tìm thấy đối soát";
                    return result;
                }

                if (reconciliation.Status != ReconciliationStatus.Draft)
                {
                    result.Result = Result.Failed;
                    result.Message = "Chỉ có thể xác nhận đối soát ở trạng thái Nháp";
                    return result;
                }

                reconciliation.Status = ReconciliationStatus.Confirmed;
                reconciliation.ApprovedBy = currentUser.UserId;
                reconciliation.ApprovedByUsername = currentUser.UserName;
                reconciliation = reconciliation.UpdateCommonInt(currentUser.UserId, currentUser.UserName);

                await _reconciliationRepository.UpdateAsync(reconciliation);

                // Tạo hành trình cho các đơn hàng trong đối soát
                var reconciliationOrders = await _reconciliationOrderRepository.Query()
                    .Where(ro => ro.ReconciliationId == id)
                    .ToListAsync();

                var trackModels = new List<OrderTrackModel>();
                foreach (var reconciliationOrder in reconciliationOrders)
                {
                    var trackModel = new OrderTrackModel()
                    {
                        OrderId = reconciliationOrder.OrderId,
                        OrderCode = reconciliationOrder.OrderCode,
                        Name = $"Đối soát {reconciliation.Code} được duyệt bởi {currentUser.UserName}",
                        OrderTrackType = OrderTrackType.ForInternal,
                        TrackActionType = TrackActionType.ReconciliationApprove,
                        PicId = currentUser.UserId,
                        PicUserName = currentUser.UserName,
                        UpdatedBy = currentUser.UserId,
                        UpdatedByUserName = currentUser.UserName,
                        ActionSource = ActionSource.InternalWeb,
                        PhoneContact = ""
                    };
                    trackModels.Add(trackModel);
                }

                if (trackModels.Any())
                {
                    await _orderTrackService.CreateAsync(trackModels);
                }

                result.Message = "Xác nhận đối soát thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.Failed;
                result.Message = $"Lỗi khi xác nhận đối soát: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Cập nhật đã chuyển khoản.
        /// </summary>
        public async Task<BaseResult> UpdateTransferred(TransferReconciliationModel model)
        {
            var result = new BaseResult { Result = Result.Success };
            var userRoles = await _userService.GetRolesAsync(model.TransferredBy);
            var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));
            var canTransfer = isFounder || userRoles.Any(r => r.Equals("Reconciliation.Transfer", StringComparison.OrdinalIgnoreCase));
            if (!isFounder && !canTransfer)
            {
                result.Result = Result.Failed;
                result.Message = "Bạn không thể cập nhật chuyển tiền do chưa có quyền";
                return result;
            }
            try
            {
                // Validate
                var validationErrors = model.Validate();
                if (validationErrors.Any())
                {
                    result.Result = Result.Failed;
                    result.Message = string.Join("; ", validationErrors);
                    return result;
                }

                var reconciliation = await _reconciliationRepository.Query()
                    .Include(r => r.Orders)
                    .FirstOrDefaultAsync(r => r.Id == model.ReconciliationId);

                if (reconciliation == null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Không tìm thấy đối soát";
                    return result;
                }

                if (reconciliation.Status != ReconciliationStatus.Confirmed)
                {
                    result.Result = Result.Failed;
                    result.Message = "Chỉ có thể cập nhật chuyển khoản cho đối soát đã xác nhận";
                    return result;
                }

                // Cập nhật thông tin chuyển khoản
                reconciliation.Status = ReconciliationStatus.Transferred;
                reconciliation.TransferDate = DateTimeOffset.Now;
                reconciliation.TransferredBy = model.TransferredBy;
                reconciliation.TransferredByUsername = model.TransferredByUsername;

                // Cập nhật thông tin bổ sung
                var transferInfo = new
                {
                    TransferMethod = model.TransferMethod.ToString(),
                    Note = model.Note,
                    AdditionalInfo = model.AdditionalInfo
                };
                reconciliation.TransferInfo = System.Text.Json.JsonSerializer.Serialize(transferInfo);

                reconciliation = reconciliation.UpdateCommonInt(model.TransferredBy, model.TransferredByUsername);
                await _reconciliationRepository.UpdateAsync(reconciliation);

                // Cập nhật CodStage của các đơn hàng
                var orderIds = reconciliation.Orders.Select(ro => ro.OrderId).ToList();
                var orderFins = await _orderFinRepository.Query()
                    .Where(of => orderIds.Contains(of.Id))
                    .ToListAsync();

                foreach (var orderFin in orderFins)
                {
                    orderFin.CodStage = OrderCodStage.Transfered;
                    orderFin.UpdateCommonInt(model.TransferredBy, model.TransferredByUsername);
                    await _orderFinRepository.UpdateAsync(orderFin);
                }

                // Tạo hành trình cho các đơn hàng trong đối soát
                var trackModels = new List<OrderTrackModel>();
                foreach (var reconciliationOrder in reconciliation.Orders)
                {
                    var trackModel = new OrderTrackModel()
                    {
                        OrderId = reconciliationOrder.OrderId,
                        OrderCode = reconciliationOrder.OrderCode,
                        Name = $"Đối soát {reconciliation.Code} đã chuyển tiền bởi {model.TransferredByUsername}",
                        OrderTrackType = OrderTrackType.ForInternal,
                        TrackActionType = TrackActionType.ReconciliationTransfer,
                        PicId = model.TransferredBy,
                        PicUserName = model.TransferredByUsername,
                        UpdatedBy = model.TransferredBy,
                        UpdatedByUserName = model.TransferredByUsername,
                        ActionSource = ActionSource.InternalWeb,
                        PhoneContact = ""
                    };
                    trackModels.Add(trackModel);
                }

                if (trackModels.Any())
                {
                    await _orderTrackService.CreateAsync(trackModels);
                }

                // Tạo Transaction nếu cần
                await CreateReconciliationTransaction(reconciliation, model);

                // TODO: Gửi thông báo nếu cần
                if (model.SendNotification)
                {
                    // Implement gửi thông báo
                }

                result.Message = "Cập nhật chuyển khoản thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.Failed;
                result.Message = $"Lỗi khi cập nhật chuyển khoản: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Hủy đối soát với thông tin chi tiết.
        /// </summary>
        public async Task<BaseResult> Cancel(CancelReconciliationModel model)
        {
            var result = new BaseResult { Result = Result.Success };
            var userRoles = await _userService.GetRolesAsync(model.CancelledBy);
            var isFounder = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));
            var isAccountant = userRoles.Any(r => r.Equals("Accountant", StringComparison.OrdinalIgnoreCase));

            try
            {
                // Validate model
                var validationErrors = model.Validate();
                if (validationErrors.Any())
                {
                    result.Result = Result.Failed;
                    result.Message = string.Join("; ", validationErrors);
                    return result;
                }

                var reconciliation = await _reconciliationRepository.Query()
                    .Include(r => r.Orders)
                    .Include(r => r.Customer)
                    .FirstOrDefaultAsync(r => r.Id == model.ReconciliationId);

                if (reconciliation == null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Không tìm thấy đối soát";
                    return result;
                }

                if (reconciliation.Status == ReconciliationStatus.Transferred)
                {
                    result.Result = Result.Failed;
                    result.Message = "Không thể hủy đối soát đã chuyển tiền";
                    return result;
                }

                if (reconciliation.Status == ReconciliationStatus.Cancelled)
                {
                    result.Result = Result.Failed;
                    result.Message = "Đối soát đã được hủy trước đó";
                    return result;
                }

                if (!isFounder && !isAccountant)
                {
                    if (reconciliation.Customer.ManagerId != model.CancelledBy)
                    {
                        result.Result = Result.Failed;
                        result.Message = "Bạn không thể hủy đối soát do khách hàng này không phải do bạn quản lý";
                        return result;
                    }
                }

                // Cập nhật trạng thái đối soát
                reconciliation.Status = ReconciliationStatus.Cancelled;
                reconciliation.Note = string.IsNullOrEmpty(reconciliation.Note)
                    ? $"Hủy: {model.CancelReason}"
                    : $"{reconciliation.Note}\nHủy: {model.CancelReason}";

                if (!string.IsNullOrEmpty(model.Note))
                {
                    reconciliation.Note += $"\nGhi chú: {model.Note}";
                }

                reconciliation = reconciliation.UpdateCommonInt(model.CancelledBy, model.CancelledByUsername);
                await _reconciliationRepository.UpdateAsync(reconciliation);

                // Khôi phục CodStage của các đơn hàng về Head
                var orderIds = reconciliation.Orders.Select(ro => ro.OrderId).ToList();
                var orderFins = await _orderFinRepository.Query()
                    .Where(of => orderIds.Contains(of.Id))
                    .ToListAsync();

                foreach (var orderFin in orderFins)
                {
                    orderFin.CodStage = OrderCodStage.Head;
                    orderFin.UpdateCommonInt(model.CancelledBy, model.CancelledByUsername);
                    await _orderFinRepository.UpdateAsync(orderFin);
                }

                // Tạo hành trình cho các đơn hàng trong đối soát
                var trackModels = new List<OrderTrackModel>();
                foreach (var reconciliationOrder in reconciliation.Orders)
                {
                    var trackModel = new OrderTrackModel()
                    {
                        OrderId = reconciliationOrder.OrderId,
                        OrderCode = reconciliationOrder.OrderCode,
                        Name = $"Đối soát {reconciliation.Code} bị hủy bởi {model.CancelledByUsername}" +
                        $"\nLý do hủy: {model.CancelReason}" + (!string.IsNullOrEmpty(model.Note) ? $"\nGhi chú: {model.Note}" : ""),
                        OrderTrackType = OrderTrackType.ForInternal,
                        TrackActionType = TrackActionType.ReconciliationReject,
                        PicId = model.CancelledBy,
                        PicUserName = model.CancelledByUsername,
                        UpdatedBy = model.CancelledBy,
                        UpdatedByUserName = model.CancelledByUsername,
                        ActionSource = ActionSource.InternalWeb,
                        PhoneContact = ""
                    };
                    trackModels.Add(trackModel);
                }

                if (trackModels.Count > 0)
                {
                    await _orderTrackService.CreateAsync(trackModels);
                }

                // TODO: Gửi thông báo nếu cần
                if (model.SendNotification)
                {
                    // Implement gửi thông báo
                }

                result.Message = "Hủy đối soát thành công";
            }
            catch (Exception ex)
            {
                result.Result = Result.Failed;
                result.Message = $"Lỗi khi hủy đối soát: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Hủy đối soát (phương thức cũ - deprecated).
        /// </summary>
        [Obsolete("Sử dụng Cancel(CancelReconciliationModel model) thay thế")]
        public async Task<BaseResult> Cancel(int id, CurrentUser currentUser)
        {
            // Gọi method mới với model được tạo từ tham số cũ
            var model = new CancelReconciliationModel
            {
                ReconciliationId = id,
                CancelReason = "Hủy đối soát từ hệ thống",
                Note = "",
                CancelledBy = currentUser.UserId,
                CancelledByUsername = currentUser.UserName,
                CancelledTime = DateTimeOffset.UtcNow,
                CreateOrderTrack = true,
                SendNotification = false
            };

            return await Cancel(model);
        }

        #region Private Methods

        /// <summary>
        /// Tạo mã đối soát tự động
        /// </summary>
        private async Task<string> GenerateReconciliationCode()
        {
            var today = DateTimeOffset.Now;
            var prefix = $"RC{today:yyMMdd}";

            var lastCode = await _reconciliationRepository.Query()
                .Where(r => r.Code.StartsWith(prefix))
                .OrderByDescending(r => r.Code)
                .Select(r => r.Code)
                .FirstOrDefaultAsync();

            int sequence = 1;
            if (!string.IsNullOrEmpty(lastCode) && lastCode.Length >= prefix.Length + 3)
            {
                var sequenceStr = lastCode.Substring(prefix.Length);
                if (int.TryParse(sequenceStr, out int lastSequence))
                {
                    sequence = lastSequence + 1;
                }
            }

            return $"{prefix}{sequence:D3}";
        }

        /// <summary>
        /// Tạo giao dịch trừ tiền cho đối soát
        /// </summary>
        /// <param name="reconciliation">Thông tin đối soát</param>
        /// <param name="model">Model chuyển tiền</param>
        /// <returns></returns>
        private async Task CreateReconciliationTransaction(Reconciliation reconciliation, TransferReconciliationModel model)
        {
            try
            {
                // Lấy hoặc tạo ví cho user hiện tại
                var wallet = await _walletRepository.Query()
                    .FirstOrDefaultAsync(w => w.UserId == model.TransferredBy && w.WalletType == WalletType.Personal);

                if (wallet == null)
                {
                    // Tạo ví mới nếu chưa có
                    wallet = new Wallet
                    {
                        UserId = model.TransferredBy,
                        Balance = 0,
                        WalletType = WalletType.Personal,
                        WalletStatus = WalletStatus.Active
                    };
                    wallet = wallet.UpdateCommonInt(model.TransferredBy, model.TransferredByUsername);
                    await _walletRepository.InsertAsync(wallet);
                }

                // Tạo giao dịch trừ tiền
                var transaction = new Transaction
                {
                    Description = $"Chuyển tiền đối soát {reconciliation.Code} cho khách hàng {reconciliation.Customer?.FullName ?? ""}",
                    WalletId = wallet.Id,
                    Amount = reconciliation.NetAmount,
                    CashAmount = 0,
                    TransferAmount = reconciliation.NetAmount,
                    Note = $"Đối soát: {reconciliation.Code}. {model.Note}",
                    TransactionType = TransactionType.Reconciliation,
                    TransactionDate = DateTimeOffset.Now,
                    TransactionDirection = TransactionDirection.Outcome
                };
                transaction = transaction.UpdateCommonGuid(model.TransferredBy, model.TransferredByUsername);

                await _transactionRepository.InsertAsync(transaction);

                // Cập nhật số dư ví (trừ tiền)
                wallet.Balance -= reconciliation.NetAmount;
                await _walletRepository.UpdateAsync(wallet);

                // Cập nhật TransactionId vào reconciliation
                reconciliation.TransactionId = transaction.Id;
                await _reconciliationRepository.UpdateAsync(reconciliation);
            }
            catch (Exception ex)
            {
                // Log error nhưng không throw để không ảnh hưởng đến flow chính
                // TODO: Add logging
                throw new Exception($"Lỗi khi tạo giao dịch: {ex.Message}");
            }
        }

        #endregion
    }
}
