using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Domain.Entities.Donations.ValueObject;
using Domain.Entities.Members;

namespace Domain.Entities.Donations;

public class WithdrawalRequest
{
    [ForeignKey(nameof(ChannelID))]
    public virtual Channel? Channel { get; private set; }

    [ForeignKey(nameof(MemberID))]
    public virtual Member? Member { get; private set; }

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

    public int ChannelID { get; private set; }

    public int MemberID { get; private set; }

    public int RequestedAmount { get; private set; }

    public int IncomeTax { get; private set; }

    public int LocalTax { get; private set; }

    public int WithholdingTax { get; private set; }

    public int NetAmount { get; private set; }

    public WithdrawalStatus Status { get; private set; } = WithdrawalStatus.Pending;

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

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

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

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

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

    public DateTime? ProcessedAt { get; private set; }

    public string? RejectedReason { get; private set; }

    public string? AdminMemo { get; private set; }

    private WithdrawalRequest() { }

    public static WithdrawalRequest Create(
        int channelID,
        int memberID,
        int requestedAmount,
        string bankCode,
        string bankName,
        string accountNumber,
        string accountHolder
    ) {
        var incomeTax = (int)Math.Floor(requestedAmount * 3m / 100m);
        var localTax = (int)Math.Floor(requestedAmount * 3m / 1000m);
        var withholdingTax = incomeTax + localTax;

        return new WithdrawalRequest
        {
            ChannelID = channelID,
            MemberID = memberID,
            RequestedAmount = requestedAmount,
            IncomeTax = incomeTax,
            LocalTax = localTax,
            WithholdingTax = withholdingTax,
            NetAmount = requestedAmount - withholdingTax,
            BankCode = bankCode,
            BankName = bankName,
            AccountNumber = accountNumber,
            AccountHolder = accountHolder
        };
    }

    public void MarkProcessing(string? adminMemo = null)
    {
        Status = WithdrawalStatus.Processing;
        AdminMemo = adminMemo;
    }

    public void Complete(string? adminMemo = null)
    {
        Status = WithdrawalStatus.Completed;
        ProcessedAt = DateTime.UtcNow;
        AdminMemo = adminMemo;
    }

    public void Reject(string reason, string? adminMemo = null)
    {
        Status = WithdrawalStatus.Rejected;
        ProcessedAt = DateTime.UtcNow;
        RejectedReason = reason;
        AdminMemo = adminMemo;
    }
}