using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Domain.Entities.Common.ValueObject;
using Domain.Entities.Wallets.ValueObject;

namespace Domain.Entities.Wallets
{
    public class WalletTransaction
    {
        [ForeignKey(nameof(WalletKey))]
        public virtual Wallet Wallet { get; private set; } = null!;

        [Key]
        public int ID { get; private set; }

        public Guid WalletKey { get; private set; }

        public WalletBalanceType BalanceType { get; private set; }

        public WalletTransactionType TxType { get; private set; }

        public Money Amount { get; private set; } = Money.KRW(0);

        public Money BalanceAfter { get; private set; } = Money.KRW(0);

        public string Reason { get; private set; } = default!;

        public string? RefID { get; private set; }

        public string? UserID { get; private set; }

        public string? Memo { get; private set; }

        public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;

        private WalletTransaction() { }

        private WalletTransaction(
            Guid walletKey,
            WalletBalanceType balanceType,
            WalletTransactionType txType,
            Money amount,
            Money balanceAfter,
            string reason,
            string? refID,
            string? userID,
            string? memo
        ) {
            WalletKey = walletKey;
            BalanceType = balanceType;
            TxType = txType;
            Amount = amount;
            BalanceAfter = balanceAfter;
            Reason = reason;
            RefID = refID;
            UserID = userID;
            Memo = memo;
        }

        public static WalletTransaction Create(
            Guid walletKey,
            WalletBalanceType balanceType,
            WalletTransactionType txType,
            Money amount,
            Money balanceAfter,
            string reason,
            string? refID = null,
            string? userID = null,
            string? memo = null
        ) {
            if (walletKey == Guid.Empty)
            {
                throw new ArgumentException("WalletKey is required.", nameof(walletKey));
            }

            if (amount.IsZero || amount.Value <= 0)
            {
                throw new ArgumentException("Transaction amount must be positive.", nameof(amount));
            }

            if (string.IsNullOrWhiteSpace(reason))
            {
                throw new ArgumentException("Reason is required.", nameof(reason));
            }

            return new WalletTransaction(walletKey, balanceType, txType, amount, balanceAfter, reason, refID, userID, memo);
        }
    }
}