/*
 This file is part of GNU Taler
 (C) 2021-2024 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/>
 */
import { useState } from "preact/hooks";

// FIX default import https://github.com/microsoft/TypeScript/issues/49189
import {
  AccessToken,
  OperationOk,
  opFixedSuccess,
  StatisticsAmount,
  StatisticsCounter,
  TalerHttpError,
  TalerMerchantManagementErrorsByMethod
} from "@gnu-taler/taler-util";
import _useSWR, { mutate, SWRHook } from "swr";
import { useSessionContext } from "../context/session.js";
const useSWR = _useSWR as unknown as SWRHook;

export type MerchantStatsSlug =
  | MerchantOrderStatsSlug
  | MerchantRevenueStatsSlug;
  
export const MERCHANT_ORDER_STATS_SLUG = [
  "orders-created",
  "orders-claimed",
  "orders-paid",
  "orders-settled",
] as const;

export const MERCHANT_REVENUE_STATS_SLUG = [
  "payments-received-after-deposit-fee",
  "total-wire-fees-paid",
  "refunds-granted",
  "total-deposit-fees-paid",
] as const;

export type MerchantOrderStatsSlug = (typeof MERCHANT_ORDER_STATS_SLUG)[number];
export type MerchantRevenueStatsSlug =
  (typeof MERCHANT_REVENUE_STATS_SLUG)[number];

export interface InstanceTemplateFilter {}

export function revalidateInstanceStatisticsCounter() {
  return mutate(
    (key) =>
      Array.isArray(key) && key[key.length - 1] === "getStatisticsCounter",
    undefined,
    { revalidate: true },
  );
}
export function useInstanceStatisticsCounter() {
  const { state, lib } = useSessionContext();

  const [offset] = useState<string | undefined>();

  async function fetcher([token]: [
    AccessToken,
    MerchantOrderStatsSlug,
    string,
  ]) {
    const resp = await Promise.all(
      MERCHANT_ORDER_STATS_SLUG.map((r) => {
        return lib.instance.getStatisticsCounter(token, r);
      }),
    );
    for (const r of resp) {
      // if one fail, all fail
      if (r.type === "fail") {
        return r;
      }
    }
    const result = new Map<MerchantOrderStatsSlug, StatisticsCounter>();

    MERCHANT_ORDER_STATS_SLUG.forEach((r, idx) => {
      if (resp[idx].type === "ok") {
        result.set(r, resp[idx].body);
      }
    });
    return opFixedSuccess(result);
  }

  const { data, error } = useSWR<
    | TalerMerchantManagementErrorsByMethod<"getStatisticsCounter">
    | OperationOk<Map<MerchantOrderStatsSlug, StatisticsCounter>>,
    TalerHttpError
  >([state.token, "ANY"], fetcher);

  if (error) return error;
  if (data === undefined) return undefined;
  if (data.type !== "ok") return data;

  return data;
}
export function revalidateInstanceStatisticsAmount() {
  return mutate(
    (key) =>
      Array.isArray(key) && key[key.length - 1] === "getStatisticsAmount",
    undefined,
    { revalidate: true },
  );
}
export function useInstanceStatisticsAmount() {
  const { state, lib } = useSessionContext();

  const [offset] = useState<string | undefined>();

  async function fetcher([token]: [AccessToken]) {
    const resp = await Promise.all(
      MERCHANT_REVENUE_STATS_SLUG.map((r) => {
        return lib.instance.getStatisticsAmount(token, r);
      }),
    );

    for (const r of resp) {
      // if one fail, all fail
      if (r.type === "fail") {
        return r;
      }
    }
    const result = new Map<MerchantRevenueStatsSlug, StatisticsAmount>();

    MERCHANT_REVENUE_STATS_SLUG.forEach((r, idx) => {
      if (resp[idx].type === "ok") {
        result.set(r, resp[idx].body);
      }
    });
    return opFixedSuccess(result);
  }

  const { data, error } = useSWR<
    | TalerMerchantManagementErrorsByMethod<"getStatisticsAmount">
    | OperationOk<Map<MerchantRevenueStatsSlug, StatisticsAmount>>,
    TalerHttpError
  >([state.token, undefined], fetcher);

  if (error) return error;
  if (data === undefined) return undefined;
  if (data.type !== "ok") return data;

  return data;
}
