/*
 This file is part of GNU Taler
 (C) 2022-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 {
  AbsoluteTime,
  AmountJson,
  TalerExchangeApi,
  TranslatedString,
} from "@gnu-taler/taler-util";
import {
  DefaultForm,
  FormConfiguration,
  UIFormElementConfig,
  UIHandlerId,
  useTranslationContext
} from "@gnu-taler/web-util/browser";
import { format } from "date-fns";
import { Fragment, VNode, h } from "preact";
import { AmlEvent } from "./CaseDetails.js";

export function ShowConsolidated({
  history,
  until,
}: {
  history: AmlEvent[];
  until: AbsoluteTime;
}): VNode {
  const { i18n } = useTranslationContext();

  const cons = getConsolidated(history, until);

  const form: FormConfiguration = {
    type: "double-column",
    design: [
      {
        title: i18n.str`AML`,
        fields: [
          {
            type: "amount",
            id: ".aml.threshold" as UIHandlerId,
            currency: "NETZBON",
            label: i18n.str`Threshold`,
            name: "aml.threshold",
          },
          {
            type: "choiceHorizontal",
            label: i18n.str`State`,
            name: "aml.state",
            id: ".aml.state" as UIHandlerId,
            choices: [
              {
                label: i18n.str`Frozen`,
                value: "frozen",
              },
              {
                label: i18n.str`Pending`,
                value: "pending",
              },
              {
                label: i18n.str`Normal`,
                value: "normal",
              },
            ],
          },
        ],
      },
      Object.entries(cons.kyc).length > 0
        ? {
            title: i18n.str`KYC`,
            fields: Object.entries(cons.kyc).map(([key, field]) => {
              const result: UIFormElementConfig = {
                type: "text",
                label: key as TranslatedString,
                id: `kyc.${key}.value` as UIHandlerId,
                name: `kyc.${key}.value`,
                help: `${field.provider} since ${
                  field.since.t_ms === "never"
                    ? "never"
                    : format(field.since.t_ms, "dd/MM/yyyy")
                }` as TranslatedString,
              };
              return result;
            }),
          }
        : undefined!,
    ],
  };
  return (
    <Fragment>
      <h1 class="text-base font-semibold leading-7 text-black">
        Consolidated information{" "}
        {until.t_ms === "never"
          ? ""
          : `after ${format(until.t_ms, "dd MMMM yyyy")}`}
      </h1>
      <DefaultForm
        key={`${String(Date.now())}`}
        form={form as any}
        initial={cons}
        readOnly
        onUpdate={() => {}}
      />
    </Fragment>
  );
}

interface Consolidated {
  aml: {
    state: TalerExchangeApi.AmlState;
    threshold: AmountJson;
    since: AbsoluteTime;
  };
  kyc: {
    [field: string]: {
      value: unknown;
      provider: string;
      since: AbsoluteTime;
    };
  };
}

function getConsolidated(
  history: AmlEvent[],
  when: AbsoluteTime,
): Consolidated {
  const initial: Consolidated = {
    aml: {
      state: TalerExchangeApi.AmlState.normal,
      threshold: {
        currency: "ARS",
        value: 1000,
        fraction: 0,
      },
      since: AbsoluteTime.never(),
    },
    kyc: {},
  };
  return history.reduce((prev, cur) => {
    if (AbsoluteTime.cmp(when, cur.when) < 0) {
      return prev;
    }
    switch (cur.type) {
      case "kyc-expiration": {
        cur.fields.forEach((field) => {
          delete prev.kyc[field];
        });
        break;
      }
      case "aml-form": {
        prev.aml = {
          since: cur.when,
          state: cur.state,
          threshold: cur.threshold,
        };
        break;
      }
      case "kyc-collection": {
        Object.keys(cur.values).forEach((field) => {
          const value = (cur.values as Record<string, unknown>)[field];
          prev.kyc[field] = {
            value,
            provider: cur.provider,
            since: cur.when,
          };
        });
        break;
      }
    }
    return prev;
  }, initial);
}
