/*
 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 {
  AbsoluteTime,
  AmountString,
  PaymentStatus,
  RefreshReason,
  TalerPreciseTimestamp,
  TalerProtocolTimestamp,
  TransactionCommon,
  TransactionDeposit,
  TransactionIdStr,
  TransactionMajorState,
  TransactionMinorState,
  TransactionPayment,
  TransactionPeerPullCredit,
  TransactionPeerPullDebit,
  TransactionPeerPushCredit,
  TransactionPeerPushDebit,
  TransactionRefresh,
  TransactionRefund,
  TransactionType,
  TransactionWithdrawal,
  WithdrawalDetails,
  WithdrawalType,
} from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import beer from "../../static-stories/beer.png";
import { TransactionView as TestedComponent } from "./Transaction.js";

export default {
  title: "transaction details",
  component: TestedComponent,
  argTypes: {
    onRetry: { action: "onRetry" },
    onDelete: { action: "onDelete" },
    onCancel: { action: "onCancel" },
    onBack: { action: "onBack" },
  },
};

const commonTransaction: TransactionCommon = {
  error: undefined,
  amountRaw: "KUDOS:11" as AmountString,
  scopes: [],
  amountEffective: "KUDOS:9.2" as AmountString,
  txState: {
    major: TransactionMajorState.Done,
  },
  txActions: [],
  timestamp: TalerProtocolTimestamp.now(),
  transactionId: "txn:deposit:12" as TransactionIdStr,
  type: TransactionType.Deposit,
  stId: 1,

} as Omit<
  Omit<Omit<TransactionCommon, "extendedStatus">, "frozen">,
  "pending"
> as TransactionCommon;

import merchantIcon from "../../static-stories/merchant-icon.jpeg";

const exampleData = {
  withdraw: {
    ...commonTransaction,
    type: TransactionType.Withdrawal,
    exchangeBaseUrl: "http://exchange.taler",
    withdrawalDetails: {
      reserveIsReady: false,
      confirmed: false,
      reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG",
      exchangePaytoUris: ["payto://x-taler-bank/bank.demo.taler.net/Exchange"],
      reserveClosingDelay: { d_us: "forever" },
      type: WithdrawalType.ManualTransfer,
    },
  } as TransactionWithdrawal,
  payment: {
    ...commonTransaction,
    amountEffective: "KUDOS:12" as AmountString,
    type: TransactionType.Payment,
    posConfirmation: undefined,
    info: {
      contractTermsHash: "ASDZXCASD",
      merchant: {
        name: "the merchant",
        logo: merchantIcon,
        website: "https://www.themerchant.taler",
        email: "contact@merchant.taler",
      },
      orderId: "2021.167-03NPY6MCYMVGT",
      products: [],
      summary: "Essay: Why the Devil's Advocate Doesn't Help Reach the Truth",
      fulfillmentMessage: "",
      // delivery_date: { t_s: 1 },
      // delivery_location: {
      //   address_lines: [""],
      // },
    },
    refunds: [],
    refundPending: undefined,
    totalRefundEffective: "KUDOS:0" as AmountString,
    totalRefundRaw: "KUDOS:0" as AmountString,
    status: PaymentStatus.Accepted,
    refundQueryActive: false,
  } as TransactionPayment,
  deposit: {
    ...commonTransaction,
    type: TransactionType.Deposit,
    wireTransferDeadline: {
      t_s: new Date().getTime() / 1000,
    },
    depositGroupId: "#groupId",
    targetPaytoUri: "payto://x-taler-bank/bank.demo.taler.net/Exchange",
  } as TransactionDeposit,
  refresh: {
    ...commonTransaction,
    type: TransactionType.Refresh,
    refreshInputAmount: "KUDOS:1" as AmountString,
    refreshOutputAmount: "KUDOS:0.5" as AmountString,
    exchangeBaseUrl: "http://exchange.taler",
    refreshReason: RefreshReason.Manual,
  } as TransactionRefresh,
  refund: {
    ...commonTransaction,
    type: TransactionType.Refund,
    refundedTransactionId:
      "payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
    paymentInfo: {
      merchant: {
        name: "The merchant",
      },
      summary: "Essay: Why the Devil's Advocate Doesn't Help Reach the Truth",
      summary_i18n: {},
    },
    refundPending: undefined,
  } as TransactionRefund,
  push_credit: {
    ...commonTransaction,
    type: TransactionType.PeerPushCredit,
    info: {
      iconId: "",
      expiration: {
        t_s: new Date().getTime() / 1000 + 2 * 60 * 60,
      },
      summary: "take this money",
      completed: true,
    },
    kycUrl: undefined,
    exchangeBaseUrl: "https://exchange.taler.net",
  } as TransactionPeerPushCredit,
  push_debit: {
    ...commonTransaction,
    type: TransactionType.PeerPushDebit,
    talerUri:
      "taler://pay-push/exchange.taler.ar/HS585JK0QCXHJ8Z8QWZA3EBAY5WY7XNC1RR2MHJXSH2Z4WP0YPJ0",
    info: {
      iconId: "",
      expiration: {
        t_s: new Date().getTime() / 1000 + 2 * 60 * 60,
      },
      summary: "take this money",
      completed: true,
    },
    exchangeBaseUrl: "https://exchange.taler.net",
  } as TransactionPeerPushDebit,
  pull_credit: {
    ...commonTransaction,
    type: TransactionType.PeerPullCredit,
    talerUri:
      "taler://pay-push/exchange.taler.ar/HS585JK0QCXHJ8Z8QWZA3EBAY5WY7XNC1RR2MHJXSH2Z4WP0YPJ0",
    info: {
      iconId: "",
      expiration: {
        t_s: new Date().getTime() / 1000 + 2 * 60 * 60,
      },
      summary: "pay me, please?",
      completed: true,
    },
    kycUrl: undefined,
    exchangeBaseUrl: "https://exchange.taler.net",
  } as TransactionPeerPullCredit,
  pull_debit: {
    ...commonTransaction,
    type: TransactionType.PeerPullDebit,
    info: {      iconId: "",

      expiration: {
        t_s: new Date().getTime() / 1000 + 2 * 60 * 60,
      },
      summary: "pay me, please?",
      completed: true,
    },
    exchangeBaseUrl: "https://exchange.taler.net",
  } as TransactionPeerPullDebit,
};

const transactionError = {
  code: 7005,
  details: {
    requestUrl:
      "http://merchant-backend.taler:9966/orders/2021.340-02AD5XCC97MQM/pay",
    httpStatusCode: 410,
    errorResponse: {
      code: 2161,
      hint: "The payment is too late, the offer has expired.",
    },
  },
  when: AbsoluteTime.now(),
  hint: "Error: WALLET_UNEXPECTED_REQUEST_ERROR",
  message: "Unexpected error code in response",
};

export const Withdraw = tests.createExample(TestedComponent, {
  transaction: exampleData.withdraw,
});

export const WithdrawFiveMinutesAgo = tests.createExample(
  TestedComponent,
  () => ({
    transaction: {
      ...exampleData.withdraw,
      timestamp: TalerPreciseTimestamp.fromSeconds(
        new Date().getTime() / 1000 - 60 * 5,
      ),
    },
  }),
);

export const WithdrawFiveMinutesAgoAndPending = tests.createExample(
  TestedComponent,
  () => ({
    transaction: {
      ...exampleData.withdraw,
      timestamp: TalerPreciseTimestamp.fromSeconds(
        new Date().getTime() / 1000 - 60 * 5,
      ),
      txState: {
        major: TransactionMajorState.Pending,
      },
    },
  }),
);

export const WithdrawError = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.withdraw,
    error: transactionError,
  },
});

export const WithdrawErrorKYC = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.withdraw,
    txState: {
      major: TransactionMajorState.Pending,
      minor: TransactionMinorState.KycRequired,
    },
    kycUrl:
      "http://localhost:6666/oauth/v2/login?client_id=taler-exchange&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2F%2Fkyc-proof%2F59WFS5VXXY3CEE25BM45XPB7ZCDQZNZ46PJCMNXK05P65T9M1X90%2FKYC-PROVIDER-MYPROV%2F1",
  },
});

export const WithdrawPendingManual = tests.createExample(
  TestedComponent,
  () => ({
    transaction: {
      ...exampleData.withdraw,
      withdrawalDetails: {
        type: WithdrawalType.ManualTransfer,
        exchangePaytoUris: ["payto://iban/ES8877998399652238"],
        reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG",
        reserveClosingDelay: {
          d_us: 111,
        },
        exchangeCreditAccountDetails: [
          {
            paytoUri: "payto://IBAN/1231231231",
          },
          {
            paytoUri: "payto://IBAN/2342342342",
          },
        ],
      } as WithdrawalDetails,
      txState: {
        major: TransactionMajorState.Pending,
      },
    },
  }),
);

export const WithdrawPendingTalerBankUnconfirmed = tests.createExample(
  TestedComponent,
  {
    transaction: {
      ...exampleData.withdraw,
      withdrawalDetails: {
        type: WithdrawalType.TalerBankIntegrationApi,
        confirmed: false,
        reserveIsReady: false,
        reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG",
        bankConfirmationUrl: "http://bank.demo.taler.net",
      },
      txState: {
        major: TransactionMajorState.Pending,
      },
    },
  },
);

export const WithdrawPendingTalerBankConfirmed = tests.createExample(
  TestedComponent,
  {
    transaction: {
      ...exampleData.withdraw,
      withdrawalDetails: {
        type: WithdrawalType.TalerBankIntegrationApi,
        confirmed: true,
        reserveIsReady: false,
        reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG",
      },
      txState: {
        major: TransactionMajorState.Pending,
      },
    },
  },
);

export const Payment = tests.createExample(TestedComponent, {
  transaction: exampleData.payment,
});

export const PaymentWithPosConfirmation = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    posConfirmation: "123123\n3345345\n567567",
  },
});

export const PaymentError = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    error: transactionError,
  },
});

export const PaymentWithRefund = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    amountRaw: "KUDOS:12" as AmountString,
    totalRefundEffective: "KUDOS:1" as AmountString,
    totalRefundRaw: "KUDOS:1" as AmountString,
    refunds: [
      {
        transactionId: "1123123",
        amountRaw: "KUDOS:1" as AmountString,
        amountEffective: "KUDOS:1" as AmountString,
        timestamp: TalerProtocolTimestamp.fromSeconds(1546546544),
      },
    ],
  },
});

export const PaymentWithDeliveryDate = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    amountRaw: "KUDOS:12" as AmountString,
    info: {
      ...exampleData.payment.info,
      // delivery_date: {
      //   t_s: new Date().getTime() / 1000,
      // },
    },
  },
});

export const PaymentWithDeliveryAddr = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    amountRaw: "KUDOS:12" as AmountString,
    info: {
      ...exampleData.payment.info,
      // delivery_location: {
      //   country: "Argentina",
      //   street: "Elm Street",
      //   district: "CABA",
      //   post_code: "1101",
      // },
    },
  },
});

export const PaymentWithDeliveryFull = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    amountRaw: "KUDOS:12" as AmountString,
    info: {
      ...exampleData.payment.info,
      // delivery_date: {
      //   t_s: new Date().getTime() / 1000,
      // },
      // delivery_location: {
      //   country: "Argentina",
      //   street: "Elm Street",
      //   district: "CABA",
      //   post_code: "1101",
      // },
    },
  },
});

export const PaymentWithRefundPending = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    amountRaw: "KUDOS:12" as AmountString,
    refundPending: "KUDOS:3" as AmountString,
    totalRefundEffective: "KUDOS:1" as AmountString,
    totalRefundRaw: "KUDOS:1" as AmountString,
  },
});

export const PaymentWithFeeAndRefund = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    amountRaw: "KUDOS:11" as AmountString,
    totalRefundEffective: "KUDOS:1" as AmountString,
    totalRefundRaw: "KUDOS:1" as AmountString,
  },
});

export const PaymentWithFeeAndRefundFee = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    amountRaw: "KUDOS:11" as AmountString,
    totalRefundEffective: "KUDOS:1" as AmountString,
    totalRefundRaw: "KUDOS:2" as AmountString,
  },
});

export const PaymentWithoutFee = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    amountRaw: "KUDOS:12" as AmountString,
  },
});

export const PaymentPending = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    txState: {
      major: TransactionMajorState.Pending,
    },
  },
});

export const PaymentWithProducts = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    info: {
      ...exampleData.payment.info,
      summary: "summary of 5 products",
      products: [
        {
          description: "t-shirt",
          unit: "shirts",
          quantity: 1,
        },
        {
          description: "t-shirt",
          unit: "shirts",
          quantity: 1,
        },
        {
          description: "e-book",
        },
        {
          description: "beer",
          unit: "pint",
          quantity: 15,
          image: beer,
        },
        {
          description: "beer",
          unit: "pint",
          quantity: 15,
          image: beer,
        },
      ],
    },
  } as TransactionPayment,
});

export const PaymentWithLongSummary = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.payment,
    info: {
      ...exampleData.payment.info,
      summary:
        "this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, ",
      products: [
        {
          description:
            "an xl sized t-shirt with some drawings on it, color pink",
          unit: "shirts",
          quantity: 1,
        },
        {
          description: "beer",
          unit: "pint",
          quantity: 15,
        },
      ],
    },
  } as TransactionPayment,
});

export const Deposit = tests.createExample(TestedComponent, {
  transaction: exampleData.deposit,
});
export const DepositTalerBank = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.deposit,
    targetPaytoUri: "payto://x-taler-bank/bank.demo.taler.net/Exchange",
  },
});
export const DepositBitcoin = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.deposit,
    amountRaw: "BITCOINBTC:0.0000011" as AmountString,
    amountEffective: "BITCOINBTC:0.00000092" as AmountString,
    targetPaytoUri:
      "payto://bitcoin/bcrt1q6ps8qs6v8tkqrnru4xqqqa6rfwcx5ufpdfqht4?amount=BTC:0.1&subject=0ZSX8SH0M30KHX8K3Y1DAMVGDQV82XEF9DG1HC4QMQ3QWYT4AF00",
  },
});
export const DepositIBAN = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.deposit,
    targetPaytoUri: "payto://iban/ES8877998399652238",
  },
});

export const DepositError = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.deposit,
    error: transactionError,
  },
});

export const DepositPending = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.deposit,
    txState: {
      major: TransactionMajorState.Pending,
    },
  },
});

export const Refresh = tests.createExample(TestedComponent, {
  transaction: exampleData.refresh,
});

export const RefreshError = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.refresh,
    error: transactionError,
  },
});

export const Refund = tests.createExample(TestedComponent, {
  transaction: exampleData.refund,
});

export const RefundError = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.refund,
    error: transactionError,
  },
});

export const RefundPending = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.refund,
    txState: {
      major: TransactionMajorState.Pending,
    },
  },
});

export const InvoiceCreditComplete = tests.createExample(TestedComponent, {
  transaction: { ...exampleData.pull_credit },
});

export const InvoiceCreditIncomplete = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.pull_credit,
    txState: {
      major: TransactionMajorState.Pending,
    },
  },
});

export const InvoiceDebit = tests.createExample(TestedComponent, {
  transaction: { ...exampleData.pull_debit },
});

export const TransferCredit = tests.createExample(TestedComponent, {
  transaction: { ...exampleData.push_credit },
});

export const TransferDebitComplete = tests.createExample(TestedComponent, {
  transaction: { ...exampleData.push_debit },
});
export const TransferDebitIncomplete = tests.createExample(TestedComponent, {
  transaction: {
    ...exampleData.push_debit,
    txState: {
      major: TransactionMajorState.Pending,
    },
  },
});
