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

namespace Ladaer.BackEnd.Infrastructures.DTO.Profiles
{
    /// <summary>
    /// Extension methods cho mapping Bank entities
    /// </summary>
    public static class BankMappingExtensions
    {
        /// <summary>
        /// Convert BankAccount entity sang BankAccountItem
        /// </summary>
        public static BankAccountItem ToItem(this BankAccount entity)
        {
            if (entity == null) return new BankAccountItem();

            return new BankAccountItem
            {
                Id = entity.Id,
                AccountName = entity.AccountName,
                AccountNumber = entity.AccountNumber,
                CreatedTime = entity.CreatedTime,
                UpdatedTime = entity.UpdatedTime,
                LastBalanceUpdate = entity.LastBalanceUpdate,
                ManagerUserName = entity.ManagerUser?.UserName ?? "",
                ManagerFullName = entity.ManagerUser?.FullName ?? "",
                LastTransactionDate = entity.LastTransactionDate,
                TransactionCount = entity.BankTransactions?.Count ?? 0,
            };
        }

        /// <summary>
        /// Convert BankTransaction entity sang BankTransactionItem
        /// </summary>
        public static BankTransactionItem ToItem(this BankTransaction entity)
        {
            if (entity == null) return new BankTransactionItem();

            return new BankTransactionItem
            {
                Id = entity.Id,
                BankAccountId = entity.BankAccountId,
                TransactionCode = entity.TransactionCode,
                TransactionDate = entity.TransactionDate,
                CreditAmount = entity.CreditAmount > 0 ? entity.CreditAmount.ToString("N0") : "",
                DebitAmount = entity.DebitAmount > 0 ? entity.DebitAmount.ToString("N0") : "",
                Balance = entity.Balance.ToString("N0"),
                Description = entity.Description,
                DetailedTime = entity.DetailedTime,
                ProcessStatus = entity.ProcessStatus.GetDescription(),
                TransactionType = entity.TransactionType?.GetDescription() ?? "",
                ReferenceNumber = entity.ReferenceNumber,
                CounterpartyName = entity.CounterpartyName,
                CounterpartyAccount = entity.CounterpartyAccount,
                CounterpartyBank = entity.CounterpartyBank,
                BankAccountName = entity.BankAccount?.AccountName ?? "",
                BankAccountNumber = entity.BankAccount?.AccountNumber ?? "",
                ImportId = entity.ImportId,
                ImportRowNumber = entity.ImportRowNumber,
                ProcessNote = entity.ProcessNote,
                CreatedTime = entity.CreatedTime,
                UpdatedTime = entity.UpdatedTime
            };
        }

        /// <summary>
        /// Convert BankStatementImport entity sang BankStatementImportItem
        /// </summary>
        public static BankStatementImportItem ToItem(this BankStatementImport entity)
        {
            if (entity == null) return new BankStatementImportItem();

            var processDuration = "";
            if (entity.ProcessStartTime.HasValue && entity.ProcessEndTime.HasValue)
            {
                var duration = entity.ProcessEndTime.Value - entity.ProcessStartTime.Value;
                if (duration.TotalMinutes < 1)
                    processDuration = $"{duration.TotalSeconds:F1} giây";
                else if (duration.TotalHours < 1)
                    processDuration = $"{duration.TotalMinutes:F1} phút";
                else
                    processDuration = $"{duration.TotalHours:F1} giờ";
            }

            var successRate = entity.TotalRows > 0 ?
                (decimal)entity.ProcessedRows / entity.TotalRows * 100 : 0;

            return new BankStatementImportItem
            {
                Id = entity.Id,
                BankAccountId = entity.BankAccountId,
                BankAccountName = entity.BankAccount?.AccountName ?? "",
                BankAccountNumber = entity.BankAccount?.AccountNumber ?? "",
                OriginalFileName = entity.OriginalFileName,
                FileSize = FormatFileSize(entity.FileSize),
                TotalRows = entity.TotalRows,
                ProcessedRows = entity.ProcessedRows,
                ErrorRows = entity.ErrorRows,
                SkippedRows = entity.SkippedRows,
                DuplicateRows = entity.DuplicateRows,
                ImportStatus = entity.ImportStatus.GetDescription(),
                ErrorMessage = entity.ErrorMessage,
                DataFromDate = entity.DataFromDate,
                DataToDate = entity.DataToDate,
                OverwriteExisting = entity.OverwriteExisting,
                ProcessStartTime = entity.ProcessStartTime,
                ProcessEndTime = entity.ProcessEndTime,
                ProcessDuration = processDuration,
                ImportedByUserName = entity.ImportedByUserName,
                SuccessRate = successRate,
                CreatedTime = entity.CreatedTime,
                UpdatedTime = entity.UpdatedTime
            };
        }

        /// <summary>
        /// Convert Bank entity sang BankItem
        /// </summary>
        public static BankItem ToItem(this Bank entity)
            => entity.MapTo<Bank, BankItem>();

        /// <summary>
        /// Convert Bank entity sang BankModel
        /// </summary>
        public static BankModel ToModel(this Bank entity)
            => entity.MapTo<Bank, BankModel>();

        /// <summary>
        /// Convert BankModel sang Bank entity
        /// </summary>
        public static Bank ToEntity(this BankModel model)
            => model.MapTo<BankModel, Bank>();

        /// <summary>
        /// Convert Bank entity sang BankOptionItem
        /// </summary>
        public static BankOptionItem ToOptionItem(this Bank entity)
            => entity.MapTo<Bank, BankOptionItem>();

        /// <summary>
        /// Format file size
        /// </summary>
        private static string FormatFileSize(long bytes)
        {
            string[] sizes = { "B", "KB", "MB", "GB", "TB" };
            double len = bytes;
            int order = 0;
            while (len >= 1024 && order < sizes.Length - 1)
            {
                order++;
                len = len / 1024;
            }
            return $"{len:0.##} {sizes[order]}";
        }
    }
}
