using Books.Api.EventFlow.ReadModels;
using GraphQL.Types;

namespace Books.Api.GraphQL.Types;

/// <summary>
/// GraphQL type for bank transactions synced from Enable Banking.
/// Used in Hurtig Bogføring for quick booking of transactions.
/// </summary>
public class BankTransactionType : ObjectGraphType<BankTransactionDto>
{
    public BankTransactionType()
    {
        Name = "BankTransaction";
        Description = "A bank transaction from Enable Banking";

        Field(x => x.Id, type: typeof(IdGraphType))
            .Description("The transaction ID");

        Field(x => x.CompanyId)
            .Description("The company ID");

        Field(x => x.BankConnectionId)
            .Description("The bank connection ID");

        Field(x => x.BankAccountId)
            .Description("The bank account ID from Enable Banking");

        Field(x => x.ExternalId)
            .Description("External transaction ID from the bank (for deduplication)");

        Field(x => x.Amount)
            .Description("Transaction amount (positive = credit, negative = debit)");

        Field(x => x.Currency)
            .Description("Currency code (e.g., DKK)");

        Field(x => x.TransactionDate, type: typeof(DateTimeGraphType))
            .Description("The transaction date");

        Field(x => x.BookingDate, nullable: true)
            .Description("The booking date (when the bank processed it)");

        Field(x => x.ValueDate, nullable: true)
            .Description("The value date");

        Field(x => x.Description, nullable: true)
            .Description("Transaction description/remittance information");

        Field(x => x.CounterpartyName, nullable: true)
            .Description("Name of the counterparty");

        Field(x => x.CounterpartyAccount, nullable: true)
            .Description("Account number of the counterparty");

        Field(x => x.Reference, nullable: true)
            .Description("Payment reference (end-to-end ID)");

        Field(x => x.CreditorName, nullable: true)
            .Description("Creditor name (for outgoing payments)");

        Field(x => x.DebtorName, nullable: true)
            .Description("Debtor name (for incoming payments)");

        Field(x => x.Status)
            .Description("Status: pending | booked | ignored");

        Field(x => x.JournalEntryDraftId, nullable: true)
            .Description("Reference to journal entry draft when booked");

        Field(x => x.CreatedAt, type: typeof(DateTimeGraphType))
            .Description("When the transaction was synced");

        Field(x => x.UpdatedAt, type: typeof(DateTimeGraphType))
            .Description("When the transaction was last updated");

        Field(x => x.DisplayCounterparty)
            .Description("Display name for the counterparty");

        Field(x => x.IsIncome)
            .Description("True if this is an income (positive amount)");
    }
}

/// <summary>
/// GraphQL type for sync result.
/// </summary>
public class BankTransactionSyncResultType : ObjectGraphType<BankTransactionSyncResult>
{
    public BankTransactionSyncResultType()
    {
        Name = "BankTransactionSyncResult";
        Description = "Result of a bank transaction sync operation";

        Field(x => x.TotalConnections)
            .Description("Number of bank connections processed");

        Field(x => x.TotalAccounts)
            .Description("Number of bank accounts processed");

        Field(x => x.NewTransactions)
            .Description("Number of new transactions synced");

        Field(x => x.SkippedDuplicates)
            .Description("Number of duplicate transactions skipped");

        Field(x => x.Errors)
            .Description("Number of errors encountered");

        Field(x => x.ErrorMessages, type: typeof(ListGraphType<StringGraphType>))
            .Description("Error messages if any");
    }
}
