/*
 This file is part of GNU Taler
 (C) 2021-2023 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 {
  Amounts,
  parsePaytoUri,
  stringifyPaytoUri,
} from "@gnu-taler/taler-util";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { format } from "date-fns";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { QR } from "../../../../components/exception/QR.js";
import { FormProvider } from "../../../../components/form/FormProvider.js";
import { Input } from "../../../../components/form/Input.js";
import { InputCurrency } from "../../../../components/form/InputCurrency.js";
import { InputDate } from "../../../../components/form/InputDate.js";
import { TextField } from "../../../../components/form/TextField.js";
import { SimpleModal } from "../../../../components/modal/index.js";
import { MerchantBackend } from "../../../../declaration.js";
import { useRewardDetails } from "../../../../hooks/reserves.js";
import { RewardInfo } from "./RewardInfo.js";
import { ShowAccountsOfReserveAsQRWithLink } from "../create/CreatedSuccessfully.js";
import { datetimeFormatForSettings, useSettings } from "../../../../hooks/useSettings.js";

type Entity = MerchantBackend.Rewards.ReserveDetail;
type CT = MerchantBackend.ContractTerms;

interface Props {
  onBack: () => void;
  selected: Entity;
  id: string;
}

export function DetailPage({ id, selected, onBack }: Props): VNode {
  const { i18n } = useTranslationContext();
  const didExchangeAckTransfer = Amounts.isNonZero(
    Amounts.parseOrThrow(selected.exchange_initial_amount),
  );

  return (
    <div class="columns">
      <div class="column" />
      <div class="column is-four-fifths">
        <div class="section main-section">
          <FormProvider object={{ ...selected, id }} valueHandler={null}>
            <InputDate<Entity>
              name="creation_time"
              label={i18n.str`Created at`}
              readonly
            />
            <InputDate<Entity>
              name="expiration_time"
              label={i18n.str`Valid until`}
              readonly
            />
            <InputCurrency<Entity>
              name="merchant_initial_amount"
              label={i18n.str`Created balance`}
              readonly
            />
            <TextField<Entity>
              name="exchange_url"
              label={i18n.str`Exchange URL`}
              readonly
            >
              <a target="_blank" rel="noreferrer" href={selected.exchange_url}>
                {selected.exchange_url}
              </a>
            </TextField>

            {didExchangeAckTransfer && (
              <Fragment>
                <InputCurrency<Entity>
                  name="exchange_initial_amount"
                  label={i18n.str`Exchange balance`}
                  readonly
                />
                <InputCurrency<Entity>
                  name="pickup_amount"
                  label={i18n.str`Picked up`}
                  readonly
                />
                <InputCurrency<Entity>
                  name="committed_amount"
                  label={i18n.str`Committed`}
                  readonly
                />
              </Fragment>
            )}
            <Input name="id" label={i18n.str`Subject`} readonly />
          </FormProvider>

          {didExchangeAckTransfer ? (
            <Fragment>
              <div class="card has-table">
                <header class="card-header">
                  <p class="card-header-title">
                    <span class="icon">
                      <i class="mdi mdi-cash-register" />
                    </span>
                    <i18n.Translate>Rewards</i18n.Translate>
                  </p>
                </header>
                <div class="card-content">
                  <div class="b-table has-pagination">
                    <div class="table-wrapper has-mobile-cards">
                      {selected.rewards && selected.rewards.length > 0 ? (
                        <Table rewards={selected.rewards} />
                      ) : (
                        <EmptyTable />
                      )}
                    </div>
                  </div>
                </div>
              </div>
            </Fragment>
          ) : selected.accounts ? (
            <ShowAccountsOfReserveAsQRWithLink
              accounts={selected.accounts}
              amount={selected.merchant_initial_amount}
              message={id}
            />
          ) : undefined}

          <div class="buttons is-right mt-5">
            <button class="button" onClick={onBack}>
              <i18n.Translate>Back</i18n.Translate>
            </button>
          </div>
        </div>
      </div>
      <div class="column" />
    </div>
  );
}

function EmptyTable(): VNode {
  const { i18n } = useTranslationContext();
  return (
    <div class="content has-text-grey has-text-centered">
      <p>
        <span class="icon is-large">
          <i class="mdi mdi-emoticon-sad mdi-48px" />
        </span>
      </p>
      <p>
        <i18n.Translate>
          No reward has been authorized from this reserve
        </i18n.Translate>
      </p>
    </div>
  );
}

interface TableProps {
  rewards: MerchantBackend.Rewards.RewardStatusEntry[];
}

function Table({ rewards }: TableProps): VNode {
  const { i18n } = useTranslationContext();
  return (
    <div class="table-container">
      <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
        <thead>
          <tr>
            <th>
              <i18n.Translate>Authorized</i18n.Translate>
            </th>
            <th>
              <i18n.Translate>Picked up</i18n.Translate>
            </th>
            <th>
              <i18n.Translate>Reason</i18n.Translate>
            </th>
            <th>
              <i18n.Translate>Expiration</i18n.Translate>
            </th>
          </tr>
        </thead>
        <tbody>
          {rewards.map((t, i) => {
            return <RewardRow id={t.reward_id} key={i} entry={t} />;
          })}
        </tbody>
      </table>
    </div>
  );
}

function RewardRow({
  id,
  entry,
}: {
  id: string;
  entry: MerchantBackend.Rewards.RewardStatusEntry;
}) {
  const [selected, setSelected] = useState(false);
  const result = useRewardDetails(id);
  const [settings] = useSettings();
  if (result.loading) {
    return (
      <tr>
        <td>...</td>
        <td>...</td>
        <td>...</td>
        <td>...</td>
      </tr>
    );
  }
  if (!result.ok) {
    return (
      <tr>
        <td>...</td> {/* authorized */}
        <td>{entry.total_amount}</td>
        <td>{entry.reason}</td>
        <td>...</td> {/* expired */}
      </tr>
    );
  }
  const info = result.data;
  function onSelect() {
    setSelected(true);
  }
  return (
    <Fragment>
      {selected && (
        <SimpleModal
          description="reward"
          active
          onCancel={() => setSelected(false)}
        >
          <RewardInfo id={id} amount={info.total_authorized} entity={info} />
        </SimpleModal>
      )}
      <tr>
        <td onClick={onSelect}>{info.total_authorized}</td>
        <td onClick={onSelect}>{info.total_picked_up}</td>
        <td onClick={onSelect}>{info.reason}</td>
        <td onClick={onSelect}>
          {info.expiration.t_s === "never"
            ? "never"
            : format(info.expiration.t_s * 1000, datetimeFormatForSettings(settings))}
        </td>
      </tr>
    </Fragment>
  );
}
