/*
 This file is part of GNU Taler
 (C) 2024 Taler Systems S.A.

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU Affero General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

 You should have received a copy of the GNU Affero General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>

 SPDX-License-Identifier: AGPL-3.0-or-later
 */

import { codecForAmountString } from "./amounts.js";
import {
  Codec,
  buildCodecForObject,
  codecForConstString,
  codecForList,
  codecForNumber,
  codecForString,
  codecOptional,
} from "./codec.js";
import { codecForPaytoString } from "./payto.js";
import { codecForTimestamp } from "./time.js";
import { AmountString, SafeUint64, Timestamp } from "./types-taler-common.js";

export interface RevenueConfig {
  // Name of the API.
  name: "taler-revenue";

  // libtool-style representation of the Bank protocol version, see
  // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
  // The format is "current:revision:age".
  version: string;

  // Currency used by this gateway.
  currency: string;

  // URN of the implementation (needed to interpret 'revision' in version).
  // @since v0, may become mandatory in the future.
  implementation?: string;
}

export interface RevenueIncomingHistory {
  // Array of incoming transactions.
  incoming_transactions: RevenueIncomingBankTransaction[];

  // Payto URI to identify the receiver of funds.
  // Credit account is shared by all incoming transactions
  // as per the nature of the request.
  credit_account: string;
}

export interface RevenueIncomingBankTransaction {
  // Opaque identifier of the returned record.
  row_id: SafeUint64;

  // Date of the transaction.
  date: Timestamp;

  // Amount transferred.
  amount: AmountString;

  // Payto URI to identify the sender of funds.
  debit_account: string;

  // The wire transfer subject.
  subject: string;
}

export const codecForRevenueConfig = (): Codec<RevenueConfig> =>
  buildCodecForObject<RevenueConfig>()
    .property("name", codecForConstString("taler-revenue"))
    .property("version", codecForString())
    .property("currency", codecForString())
    .property("implementation", codecOptional(codecForString()))
    .build("TalerRevenueApi.RevenueConfig");

export const codecForRevenueIncomingHistory =
  (): Codec<RevenueIncomingHistory> =>
    buildCodecForObject<RevenueIncomingHistory>()
      .property("credit_account", codecForPaytoString())
      .property(
        "incoming_transactions",
        codecForList(codecForRevenueIncomingBankTransaction()),
      )
      .build("TalerRevenueApi.MerchantIncomingHistory");

export const codecForRevenueIncomingBankTransaction =
  (): Codec<RevenueIncomingBankTransaction> =>
    buildCodecForObject<RevenueIncomingBankTransaction>()
      .property("row_id", codecForNumber())
      .property("date", codecForTimestamp)
      .property("amount", codecForAmountString())
      .property("debit_account", codecForPaytoString())
      .property("subject", codecForString())
      .build("TalerRevenueApi.RevenueIncomingBankTransaction");
