using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Domain.Entities.Members;
using Domain.Entities.Payments.Danal.ValueObject;
using Domain.Entities.Payments.ValueObject;

namespace Domain.Entities.Payments.Danal;

/// <summary>
/// 다날 결제 취소 요청 + 응답 통합
/// 전체 취소 / 부분 취소 모두 지원
/// </summary>
public class DanalCancel
{
    [ForeignKey(nameof(MemberID))]
    public virtual Member? Member { get; private set; }

    [ForeignKey(nameof(PaymentOrderID))]
    public virtual PaymentOrder? PaymentOrder { get; private set; }

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

    public int MemberID { get; private set; }

    public int PaymentOrderID { get; private set; }

    public PaymentMethod Method { get; private set; }

    /// <summary>원거래 번호</summary>
    public string TransactionID { get; private set; } = default!;

    /// <summary>가맹점 주문번호</summary>
    public string OrderID { get; private set; } = default!;

    /// <summary>취소 금액</summary>
    public int Amount { get; private set; }

    /// <summary>CPID</summary>
    public string MerchantID { get; private set; } = default!;

    /// <summary>전체/부분 취소</summary>
    public DanalCancelType CancelType { get; private set; }

    /// <summary>취소 요청자 (admin / system / member)</summary>
    public string? CancelRequester { get; private set; }

    /// <summary>취소 사유</summary>
    public string? CancelReason { get; private set; }

    // ── 응답 필드 ────────────────────────────────────────────────────

    /// <summary>응답 코드 (0000 = 성공)</summary>
    public string? ResponseCode { get; private set; }

    /// <summary>응답 메시지</summary>
    public string? ResponseMessage { get; private set; }

    /// <summary>원거래 ID (다날 응답)</summary>
    public string? OriginalTransactionID { get; private set; }

    /// <summary>취소된 금액 (다날 응답)</summary>
    public int? CancelledAmount { get; private set; }

    /// <summary>원거래 승인일자</summary>
    public string? TransDate { get; private set; }

    /// <summary>원거래 승인시간</summary>
    public string? TransTime { get; private set; }

    /// <summary>부분취소 후 남은 금액 (Balance)</summary>
    public int? Balance { get; private set; }

    /// <summary>부분취소 후 남은 결제 잔액 (RemainedAmount)</summary>
    public int? RemainedAmount { get; private set; }

    /// <summary>승인 발생 일시</summary>
    public string? ApprovalDateTime { get; private set; }

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

    public DateTime? UpdatedAt { get; private set; }

    private DanalCancel() { }

    public static DanalCancel CreateRequest(
        int memberID,
        int paymentOrderID,
        PaymentMethod method,
        string transactionID,
        string orderID,
        int amount,
        string merchantID,
        DanalCancelType cancelType,
        string? cancelRequester = null,
        string? cancelReason = null
    ) {
        return new DanalCancel
        {
            MemberID = memberID,
            PaymentOrderID = paymentOrderID,
            Method = method,
            TransactionID = transactionID,
            OrderID = orderID,
            Amount = amount,
            MerchantID = merchantID,
            CancelType = cancelType,
            CancelRequester = cancelRequester,
            CancelReason = cancelReason
        };
    }

    public void SetResponse(
        string code, string message,
        string? originalTransactionID = null,
        int? cancelledAmount = null,
        string? transDate = null, string? transTime = null,
        int? balance = null, int? remainedAmount = null,
        string? approvalDateTime = null
    ) {
        ResponseCode = code;
        ResponseMessage = message;
        OriginalTransactionID = originalTransactionID;
        CancelledAmount = cancelledAmount;
        TransDate = transDate;
        TransTime = transTime;
        Balance = balance;
        RemainedAmount = remainedAmount;
        ApprovalDateTime = approvalDateTime;
        UpdatedAt = DateTime.UtcNow;
    }

    public bool IsSuccess => ResponseCode == "0000";
}