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

namespace Ladaer.BackEnd.Infrastructures.Services.Finances
{
    public interface IWalletService
    {
        /// <summary>
        /// Tìm kiếm ví
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<SmartTableResult<WalletItem>> Search(SmartTableParam param);

        Task<WalletDetailModel> GetById(int id, int currentUserId);

        Task<WalletDetailModel> GetWalletByUserId(int userId, int currentUserId);

        Task<SmartTableResult<TransactionItem>> SearchTransactions(SmartTableParam param);

        /// <summary>
        /// Điều chỉnh số dư ví (cân ví)
        /// </summary>
        Task<BalanceAdjustmentResult> BalanceAdjustment(int walletId, BalanceAdjustmentModel model);

        /// <summary>
        /// Lấy danh sách ví cho suggestion (select control)
        /// </summary>
        /// <param name="keyword">Từ khóa tìm kiếm</param>
        /// <returns>Danh sách tối đa 20 ví</returns>
        Task<List<WalletItem>> GetSuggestions(string keyword);
    }

    public class WalletService : IWalletService
    {
        private readonly IRepository<Wallet> _walletRepository;
        private readonly IRepository<Transaction> _transactionRepository;
        private readonly IUserService _userService;

        public WalletService(
            IRepository<Wallet> walletRepository,
            IRepository<Transaction> transactionRepository,
            IUserService userService)
        {
            _walletRepository = walletRepository;
            _transactionRepository = transactionRepository;
            _userService = userService;
        }


        /// <summary>
        /// Tìm kiếm ví
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<SmartTableResult<WalletItem>> Search(SmartTableParam param)
        {
            var query = _walletRepository.Query();
            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;
                if (search.Keyword != null)
                {
                    string keyword = search.Keyword;
                    keyword = keyword.Trim().ToLower();
                    query = query.Where(x => x.User.FullName.ToLower().Contains(keyword)
                                    || (!string.IsNullOrEmpty(x.User.PhoneNumber) && x.User.PhoneNumber.ToLower().Contains(keyword))
                                    || (!string.IsNullOrEmpty(x.User.UserName) && x.User.UserName.ToLower().Contains(keyword))

                                    );
                }

                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(x => x.CreatedTime >= startParam && x.CreatedTime <= endParam);
                }

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

                if (search.WalletType != null)
                {
                    WalletType type = search.WalletType;
                    query = query.Where(x => x.WalletType == type);
                }

            }

            param.Sort = new Sort() { Predicate = "Id", Reverse = false };
            var gridData = await query.Include(w => w.User).ToSmartTableResultAsync(param, x => x.ToItem());

            return gridData;
        }




        public async Task<WalletDetailModel> GetById(int id, int currentUserId)
        {
            var result = new WalletDetailModel();
            if (id <= 0)
            {
                return result;
            }
            var wallet = await _walletRepository.Query().Include(w => w.User).FirstOrDefaultAsync(c => c.Id == id);
            if (wallet == null || wallet.Id <= 0)
            {
                return result;
            }
            result = wallet.ToModel();

            // Kiểm tra quyền cân ví (chỉ Founder)
            if (currentUserId > 0)
            {
                var userRoles = await _userService.GetRolesAsync(currentUserId);
                result.CanAdjustBalance = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));
            }

            return result;
        }

        public async Task<WalletDetailModel> GetWalletByUserId(int userId, int currentUserId)
        {
            var result = new WalletDetailModel();
            if (userId <= 0)
            {
                return result;
            }
            var wallet = await _walletRepository.Query().Include(w => w.User).FirstOrDefaultAsync(c => c.UserId == userId);
            if (wallet == null || wallet.Id <= 0)
            {
                return result;
            }
            result = wallet.ToModel();

            // Kiểm tra quyền cân ví (chỉ Founder)
            if (currentUserId > 0)
            {
                var userRoles = await _userService.GetRolesAsync(currentUserId);
                result.CanAdjustBalance = userRoles.Any(r => r.Equals("Founder", StringComparison.OrdinalIgnoreCase));
            }

            return result;
        }

        /// <summary>
        /// Tìm kiếm giao dịch của ví
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<SmartTableResult<TransactionItem>> SearchTransactions(SmartTableParam param)
        {
            var query = _transactionRepository.Query();
            if (param.Search.PredicateObject != null)
            {
                dynamic search = param.Search.PredicateObject;

                if (search.WalletId != null && search.WalletId > 0)
                {
                    int walletId = search.WalletId;
                    query = query.Where(x => x.WalletId == walletId);
                }
                else
                {
                    return new SmartTableResult<TransactionItem>();
                }



                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(x => x.CreatedTime >= startParam && x.CreatedTime <= endParam);
                }


                if (search.TransactionType != null)
                {
                    TransactionType type = search.TransactionType;
                    query = query.Where(x => x.TransactionType == type);
                }

            }

            param.Sort = new Sort() { Predicate = "CreatedTime", Reverse = true };
            var gridData = await query.ToSmartTableResultAsync(param, x => x.ToItem());

            return gridData;
        }

        /// <summary>
        /// Điều chỉnh số dư ví bằng cách tạo giao dịch Income hoặc Outcome
        /// </summary>
        public async Task<BalanceAdjustmentResult> BalanceAdjustment(int walletId, BalanceAdjustmentModel model)
        {
            var result = new BalanceAdjustmentResult();

            try
            {
                // Lấy ví và lock để tránh race condition
                var wallet = await _walletRepository.Query()
                    .Include(w => w.User)
                    .FirstOrDefaultAsync(w => w.Id == walletId);

                if (wallet == null)
                {
                    result.Result = Result.Failed;
                    result.Message = "Không tìm thấy ví";
                    return result;
                }

                if (wallet.WalletStatus != WalletStatus.Active)
                {
                    result.Result = Result.Failed;
                    result.Message = "Ví không ở trạng thái hoạt động";
                    return result;
                }

                var currentBalance = wallet.Balance;
                var desiredBalance = model.DesiredBalance;
                var difference = desiredBalance - currentBalance;

                if (difference == 0)
                {
                    result.Result = Result.Success;
                    result.Message = "Số dư hiện tại đã khớp với số dư mong muốn";
                    result.OldBalance = currentBalance;
                    result.NewBalance = currentBalance;
                    result.AdjustmentAmount = 0;
                    return result;
                }

                // Xác định loại giao dịch
                var transactionDirection = difference > 0 ? TransactionDirection.Income : TransactionDirection.Outcome;
                var adjustmentAmount = Math.Abs(difference);

                // Tạo giao dịch điều chỉnh
                var transaction = new Transaction
                {
                    Id = Guid.NewGuid(),
                    WalletId = walletId,
                    Amount = adjustmentAmount,
                    TransactionType = TransactionType.BalanceAdjustment,
                    TransactionDirection = transactionDirection,
                    Description = $"Điều chỉnh số dư ví: {model.Reason}",
                    Note = $"Số dư cũ: {currentBalance:N0} VND, Số dư mới: {desiredBalance:N0} VND. Lý do: {model.Reason}",
                    CashAmount = 0,
                    TransferAmount = adjustmentAmount,
                    CreatedTime = DateTimeOffset.Now,
                    CreatedBy = model.UpdatedBy,
                    CreatedByUserName = model.UpdatedByUserName,
                    UpdatedTime = DateTimeOffset.Now,
                    UpdatedBy = model.UpdatedBy,
                    UpdatedByUserName = model.UpdatedByUserName
                };

                await _transactionRepository.InsertAsync(transaction);

                // Cập nhật số dư ví
                wallet.Balance = desiredBalance;
                wallet.UpdatedTime = DateTimeOffset.Now;
                wallet.UpdatedBy = model.UpdatedBy;
                wallet.UpdatedByUserName = model.UpdatedByUserName;

                await _walletRepository.UpdateAsync(wallet);

                result.Result = Result.Success;
                result.Message = $"Điều chỉnh số dư thành công. {(difference > 0 ? "Cộng" : "Trừ")} {adjustmentAmount:N0} VND";
                result.OldBalance = currentBalance;
                result.NewBalance = desiredBalance;
                result.AdjustmentAmount = difference;
                result.TransactionId = transaction.Id;
                result.TransactionDirection = transactionDirection.GetDescription();
            }
            catch (Exception ex)
            {
                result.Result = Result.SystemError;
                result.Message = $"Lỗi hệ thống: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// Lấy danh sách ví cho suggestion (select control)
        /// </summary>
        /// <param name="keyword">Từ khóa tìm kiếm</param>
        /// <returns>Danh sách tối đa 20 ví</returns>
        public async Task<List<WalletItem>> GetSuggestions(string keyword)
        {
            var query = _walletRepository.Query();

            // Áp dụng filter theo keyword nếu có
            if (!string.IsNullOrEmpty(keyword))
            {
                keyword = keyword.Trim().ToLower();
                query = query.Where(x => x.User.FullName.ToLower().Contains(keyword)
                                || (!string.IsNullOrEmpty(x.User.PhoneNumber) && x.User.PhoneNumber.ToLower().Contains(keyword))
                                || (!string.IsNullOrEmpty(x.User.UserName) && x.User.UserName.ToLower().Contains(keyword))
                                );
            }

            // Lấy tối đa 20 kết quả
            var wallets = await query
                .Include(w => w.User)
                .OrderBy(x => x.Id)
                .Take(20)
                .ToListAsync();

            // Chuyển đổi sang WalletItem
            var result = wallets.Select(x => x.ToItem()).ToList();

            return result;
        }
    }
}
