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

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU 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 General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */

/**
 *
 * @author Sebastian Javier Marchano (sebasjm)
 */

import {
  AmountString,
  PaymentStatus,
  RefreshReason,
  ScopeType,
  TalerProtocolTimestamp,
  TransactionCommon,
  TransactionDeposit,
  TransactionMajorState,
  TransactionPayment,
  TransactionPeerPullCredit,
  TransactionPeerPullDebit,
  TransactionPeerPushCredit,
  TransactionPeerPushDebit,
  TransactionRefresh,
  TransactionRefund,
  TransactionType,
  TransactionWithdrawal,
  WithdrawalType,
} from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import { HistoryView as TestedComponent } from "./History.js";

export default {
  title: "history",
  component: TestedComponent,
};

let count = 0;
const commonTransaction = (): TransactionCommon =>
  ({
    amountRaw: "USD:10",
    amountEffective: "USD:9",
    txState: {
      major: TransactionMajorState.Done,
    },
    timestamp: TalerProtocolTimestamp.fromSeconds(
      new Date().getTime() / 1000 - count++ * 60 * 60 * 7,
    ),
    transactionId: String(count),
  }) as TransactionCommon;

const exampleData = {
  withdraw: {
    ...commonTransaction(),
    type: TransactionType.Withdrawal,
    exchangeBaseUrl: "http://exchange.demo.taler.net",
    withdrawalDetails: {
      reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG",
      confirmed: false,
      exchangePaytoUris: ["payto://x-taler-bank/bank/account"],
      reserveClosingDelay: { d_us: "forever" },
      type: WithdrawalType.ManualTransfer,
      reserveIsReady: false,
    },
  } as TransactionWithdrawal,
  payment: {
    ...commonTransaction(),
    amountEffective: "USD:11" as AmountString,
    type: TransactionType.Payment,
    posConfirmation: undefined,
    info: {
      contractTermsHash: "ASDZXCASD",
      merchant: {
        name: "Blog",
      },
      orderId: "2021.167-03NPY6MCYMVGT",
      products: [],
      summary: "the summary",
      fulfillmentMessage: "",
    },
    refunds: [],
    refundPending: undefined,
    totalRefundEffective: "USD:0" as AmountString,
    totalRefundRaw: "USD:0" as AmountString,
    status: PaymentStatus.Accepted,
    refundQueryActive: false,
  } as TransactionPayment,
  deposit: {
    ...commonTransaction(),
    type: TransactionType.Deposit,
    depositGroupId: "#groupId",
    targetPaytoUri: "payto://x-taler-bank/bank/account",
  } as TransactionDeposit,
  refresh: {
    ...commonTransaction(),
    type: TransactionType.Refresh,
    refreshInputAmount: "USD:1" as AmountString,
    refreshOutputAmount: "USD:0.5" as AmountString,
    exchangeBaseUrl: "http://exchange.taler",
    refreshReason: RefreshReason.PayMerchant,
  } as TransactionRefresh,
  refund: {
    ...commonTransaction(),
    type: TransactionType.Refund,
    refundedTransactionId:
      "payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
    paymentInfo: {
      merchant: {
        name: "the merchant",
      },
      summary: "the summary",
    },
    refundPending: undefined,
  } as TransactionRefund,
  push_credit: {
    ...commonTransaction(),
    type: TransactionType.PeerPushCredit,
    info: {
      summary: "take this cash",
    },
    exchangeBaseUrl: "https://exchange.taler.net",
  } as TransactionPeerPushCredit,
  push_debit: {
    ...commonTransaction(),
    type: TransactionType.PeerPushDebit,
    talerUri:
      "taler://pay-push/exchange.taler.ar/HS585JK0QCXHJ8Z8QWZA3EBAY5WY7XNC1RR2MHJXSH2Z4WP0YPJ0",
    info: {
      summary: "take this cash",
    },
    exchangeBaseUrl: "https://exchange.taler.net",
  } as TransactionPeerPushDebit,
  pull_credit: {
    ...commonTransaction(),
    type: TransactionType.PeerPullCredit,
    talerUri:
      "taler://pay-push/exchange.taler.ar/HS585JK0QCXHJ8Z8QWZA3EBAY5WY7XNC1RR2MHJXSH2Z4WP0YPJ0",
    info: {
      summary: "pay me",
    },
    exchangeBaseUrl: "https://exchange.taler.net",
  } as TransactionPeerPullCredit,
  pull_debit: {
    ...commonTransaction(),
    type: TransactionType.PeerPullDebit,
    info: {
      summary: "pay me",
    },
    exchangeBaseUrl: "https://exchange.taler.net",
  } as TransactionPeerPullDebit,
};

export const SomeBalanceWithNoTransactions = tests.createExample(
  TestedComponent,
  {
    transactionsByDate: {
      "11/11/11": [],
    },
    scope: {
      currency: "Ásd",
      type: ScopeType.Auditor,
      url: "http://auditor.taler.ar",
    },
    balances: [
      {
        available: "TESTKUDOS:10" as AmountString,
        flags: [],
        pendingIncoming: "TESTKUDOS:0" as AmountString,
        pendingOutgoing: "TESTKUDOS:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
          url: "http://auditor.taler.ar",
        },
      },
    ],
  },
);

export const OneSimpleTransaction = tests.createExample(TestedComponent, {
  transactionsByDate: {
    "11/11/11": [exampleData.withdraw],
  },
  scope: {
    currency: "Ásd",
    type: ScopeType.Auditor,
    url: "http://auditor.taler.ar",
  },
  balances: [
    {
      flags: [],
      available: "USD:10" as AmountString,
      pendingIncoming: "USD:0" as AmountString,
      pendingOutgoing: "USD:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
  ],
});

export const TwoTransactionsAndZeroBalance = tests.createExample(
  TestedComponent,
  {
    transactionsByDate: {
      "11/11/11": [exampleData.withdraw, exampleData.deposit],
    },
    scope: {
      currency: "Ásd",
      type: ScopeType.Auditor,
       url: "http://auditor.taler.ar",

    },
    balances: [
      {
        flags: [],
        available: "USD:0" as AmountString,
        pendingIncoming: "USD:0" as AmountString,
        pendingOutgoing: "USD:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
      },
    ],
  },
);

export const OneTransactionPending = tests.createExample(TestedComponent, {
  transactionsByDate: {
    "11/11/11": [
      {
        ...exampleData.withdraw,
        txState: {
          major: TransactionMajorState.Pending,
        },
      },
    ],
  },
  scope: {
    currency: "Ásd",
    type: ScopeType.Auditor,
     url: "http://auditor.taler.ar",

  },
  balances: [
    {
      flags: [],
      available: "USD:10" as AmountString,
      pendingIncoming: "USD:0" as AmountString,
      pendingOutgoing: "USD:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
  ],
});

export const SomeTransactions = tests.createExample(TestedComponent, {
  transactionsByDate: {
    "11/11/11": [
      exampleData.withdraw,
      exampleData.payment,
      exampleData.withdraw,
      exampleData.payment,
      {
        ...exampleData.payment,
        info: {
          ...exampleData.payment.info,
          summary:
            "this is a long summary that may be cropped because its too long",
        },
      },
      exampleData.refund,
      exampleData.deposit,
    ],
  },
  scope: {
    currency: "Ásd",
    type: ScopeType.Auditor,
     url: "http://auditor.taler.ar",

  },
  balances: [
    {
      flags: [],
      available: "USD:10" as AmountString,
      pendingIncoming: "USD:0" as AmountString,
      pendingOutgoing: "USD:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
  ],
});

export const SomeTransactionsInDifferentStates = tests.createExample(
  TestedComponent,
  {
    transactionsByDate: {
      "11/11/11": [
        exampleData.withdraw,
        {
          ...exampleData.withdraw,
          exchangeBaseUrl: "https://aborted/withdrawal",
          txState: {
            major: TransactionMajorState.Aborted,
          },
        },
        {
          ...exampleData.withdraw,
          exchangeBaseUrl: "https://pending/withdrawal",
          txState: {
            major: TransactionMajorState.Pending,
          },
        },
        {
          ...exampleData.withdraw,
          exchangeBaseUrl: "https://failed/withdrawal",
          txState: {
            major: TransactionMajorState.Failed,
          },
        },
        {
          ...exampleData.payment,
          info: {
            ...exampleData.payment.info,
            summary: "normal payment",
          },
        },
        {
          ...exampleData.payment,
          info: {
            ...exampleData.payment.info,
            summary: "aborting in progress",
          },
          txState: {
            major: TransactionMajorState.Aborting,
          },
        },
        {
          ...exampleData.payment,
          info: {
            ...exampleData.payment.info,
            summary: "aborted payment",
          },
          txState: {
            major: TransactionMajorState.Aborted,
          },
        },
        {
          ...exampleData.payment,
          info: {
            ...exampleData.payment.info,
            summary: "pending payment",
          },
          txState: {
            major: TransactionMajorState.Pending,
          },
        },
        {
          ...exampleData.payment,
          info: {
            ...exampleData.payment.info,
            summary: "failed payment",
          },
          txState: {
            major: TransactionMajorState.Failed,
          },
        },
        exampleData.refund,
        exampleData.deposit,
      ],
    },
    scope: {
      currency: "Ásd",
      type: ScopeType.Auditor,
       url: "http://auditor.taler.ar",

    },
    balances: [
      {
        flags: [],
        available: "USD:10" as AmountString,
        pendingIncoming: "USD:0" as AmountString,
        pendingOutgoing: "USD:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
      },
    ],
  },
);

export const SomeTransactionsWithTwoCurrencies = tests.createExample(
  TestedComponent,
  {
    transactionsByDate: {
      "11/11/11": [
        exampleData.withdraw,
        exampleData.payment,
        exampleData.withdraw,
        exampleData.payment,
        exampleData.refresh,
        exampleData.refund,
        exampleData.deposit,
      ],
    },
    scope: {
      currency: "Ásd",
      type: ScopeType.Auditor,
       url: "http://auditor.taler.ar",

    },
    balances: [
      {
        flags: [],
        available: "USD:0" as AmountString,
        pendingIncoming: "USD:0" as AmountString,
        pendingOutgoing: "USD:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
      },
      {
        flags: [],
        available: "TESTKUDOS:10" as AmountString,
        pendingIncoming: "TESTKUDOS:0" as AmountString,
        pendingOutgoing: "TESTKUDOS:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
      },
    ],
  },
);

export const FiveOfficialCurrencies = tests.createExample(TestedComponent, {
  transactionsByDate: {
    "11/11/11": [exampleData.withdraw],
  },
  scope: {
    currency: "Ásd",
    type: ScopeType.Auditor,
     url: "http://auditor.taler.ar",

  },
  balances: [
    {
      flags: [],
      available: "USD:1000" as AmountString,
      pendingIncoming: "USD:0" as AmountString,
      pendingOutgoing: "USD:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
    {
      flags: [],
      available: "EUR:881" as AmountString,
      pendingIncoming: "TESTKUDOS:0" as AmountString,
      pendingOutgoing: "TESTKUDOS:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
    {
      flags: [],
      available: "COL:4043000.5" as AmountString,
      pendingIncoming: "TESTKUDOS:0" as AmountString,
      pendingOutgoing: "TESTKUDOS:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
    {
      flags: [],
      available: "JPY:11564450.6" as AmountString,
      pendingIncoming: "TESTKUDOS:0" as AmountString,
      pendingOutgoing: "TESTKUDOS:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
    {
      flags: [],
      available: "GBP:736" as AmountString,
      pendingIncoming: "TESTKUDOS:0" as AmountString,
      pendingOutgoing: "TESTKUDOS:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
  ],
});

export const FiveOfficialCurrenciesWithHighValue = tests.createExample(
  TestedComponent,
  {
    transactionsByDate: {
      "11/11/11": [exampleData.withdraw],
    },
    scope: {
      currency: "Ásd",
      type: ScopeType.Auditor,
       url: "http://auditor.taler.ar",

    },
    balances: [
      {
        flags: [],
        available: "USD:881001321230000" as AmountString,
        pendingIncoming: "USD:0" as AmountString,
        pendingOutgoing: "USD:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
      },
      {
        flags: [],
        available: "EUR:10" as AmountString,
        pendingIncoming: "TESTKUDOS:0" as AmountString,
        pendingOutgoing: "TESTKUDOS:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
      },
      {
        flags: [],
        available: "COL:443000123123000.5123123" as AmountString,
        pendingIncoming: "TESTKUDOS:0" as AmountString,
        pendingOutgoing: "TESTKUDOS:0" as AmountString,
        hasPendingTransactions: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
        requiresUserInput: false,
      },
      {
        flags: [],
        available: "JPY:1564450000000.6123123" as AmountString,
        pendingIncoming: "TESTKUDOS:0" as AmountString,
        pendingOutgoing: "TESTKUDOS:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
      },
      {
        flags: [],
        available: "GBP:736001231231200.23123" as AmountString,
        pendingIncoming: "TESTKUDOS:0" as AmountString,
        pendingOutgoing: "TESTKUDOS:0" as AmountString,
        hasPendingTransactions: false,
        requiresUserInput: false,
        scopeInfo: {
          currency: "Ásd",
          type: ScopeType.Auditor,
           url: "http://auditor.taler.ar",

        },
      },
    ],
  },
);

export const PeerToPeer = tests.createExample(TestedComponent, {
  transactionsByDate: {
    "11/11/11": [
      exampleData.pull_credit,
      exampleData.pull_debit,
      exampleData.push_credit,
      exampleData.push_debit,
    ],
  },
  scope: {
    currency: "Ásd",
    type: ScopeType.Auditor,
     url: "http://auditor.taler.ar",

  },
  balances: [
    {
      flags: [],
      available: "USD:10" as AmountString,
      pendingIncoming: "USD:0" as AmountString,
      pendingOutgoing: "USD:0" as AmountString,
      hasPendingTransactions: false,
      requiresUserInput: false,
      scopeInfo: {
        currency: "Ásd",
        type: ScopeType.Auditor,
         url: "http://auditor.taler.ar",

      },
    },
  ],
});
