using System.Text.Json.Nodes;

namespace Csob.Models;

// Reusable building blocks shared by the typed PISP request bodies. Field names follow the COBS
// JSON contract (camelCase via System.Text.Json web defaults). Deeply variable sub-trees (party
// identification, structured remittance) are typed as JsonNode so any valid COBS payload passes
// through unchanged.

/// <summary>Monetary amount with ISO 4217 currency.</summary>
public sealed class Amount
{
    public decimal Value { get; set; }
    public string Currency { get; set; } = "CZK";
}

/// <summary>Wrapper matching the <c>amount</c> object whose <c>instructedAmount</c> holds the value/currency.</summary>
public sealed class AmountContainer
{
    public Amount InstructedAmount { get; set; } = new();
}

/// <summary>Account number identification. For domestic/SEPA writes only <c>iban</c> is required.</summary>
public sealed class AccountIdentification
{
    public string? Iban { get; set; }
    public string? Other { get; set; }
}

/// <summary>Account reference with optional currency (<c>debtorAccount</c>/<c>creditorAccount</c>).</summary>
public sealed class AccountReference
{
    public AccountIdentification Identification { get; set; } = new();
    public string? Currency { get; set; }
}

public sealed class ServiceLevel
{
    /// <summary>Payment scheme: DMCT (domestic), ESCT (SEPA), XBCT (cross-border), EXCT, NXCT.</summary>
    public string? Code { get; set; }
}

public sealed class PaymentTypeInformation
{
    /// <summary>NORM (default), HIGH (express) or INST (instant).</summary>
    public string? InstructionPriority { get; set; }
    public ServiceLevel? ServiceLevel { get; set; }
}

public sealed class FinancialInstitutionIdentification
{
    public string? Bic { get; set; }
}

public sealed class Agent
{
    public FinancialInstitutionIdentification? FinancialInstitutionIdentification { get; set; }
}

public sealed class PostalAddress
{
    public string? StreetName { get; set; }
    public string? BuildingNumber { get; set; }
    public string? PostCode { get; set; }
    public string? TownName { get; set; }
    public string? Country { get; set; }
}

/// <summary>A party (debtor/creditor/ultimate*). Identification is variable, so kept as raw JSON.</summary>
public sealed class Party
{
    public string? Name { get; set; }
    public PostalAddress? PostalAddress { get; set; }
    public JsonNode? Identification { get; set; }
}

/// <summary>
/// Remittance information. <c>unstructured</c> is free text (Czech symbols may be encoded as
/// <c>/VS/.../SS/.../KS/...</c>); <c>structured</c> varies (its <c>reference</c> may be a string or
/// an array) so it is passed through as raw JSON.
/// </summary>
public sealed class RemittanceInformation
{
    public string? Unstructured { get; set; }
    public JsonNode? Structured { get; set; }
}

public sealed class Purpose
{
    public string? Proprietary { get; set; }
}
