/*
 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/>
 */

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

import { TalerError, TalerMerchantApi } from "@gnu-taler/taler-util";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
import { AsyncButton } from "../../../../components/exception/AsyncButton.js";
import { FormProvider } from "../../../../components/form/FormProvider.js";
import { Input } from "../../../../components/form/Input.js";
import { InputArray } from "../../../../components/form/InputArray.js";
import { useSessionContext } from "../../../../context/session.js";
import { WithId } from "../../../../declaration.js";
import {
  useInstanceProducts
} from "../../../../hooks/product.js";

type Entity = TalerMerchantApi.CategoryProductList & WithId;

interface Props {
  onUpdate: (d: Entity) => Promise<void>;
  onBack?: () => void;
  category: Entity;
}
export function UpdatePage({ category, onUpdate, onBack }: Props): VNode {
  const { i18n } = useTranslationContext();
  const {
    state: { token },
    lib,
  } = useSessionContext();
  // FIXME: if the product list is big the will bring a lot of info
  const inventoryResult = useInstanceProducts();

  const inventory =
    !inventoryResult ||
    inventoryResult instanceof TalerError ||
    inventoryResult.type === "fail"
      ? []
      : inventoryResult.body;
  
  const [state, setState] = useState<
    Partial<Entity & { product_map: { id: string; description: string }[] }>
  >({
    ...category,
    product_map: [],
  });

  useEffect(() => {
    if (!category || !category?.products) return;
    console.log(category.products);
    const ps = category.products.map((prod) => {
      return lib.instance
        .getProductDetails(token, String(prod.product_id))
        .then((res) => {
          return res.type === "fail"
            ? undefined
            : { id: String(prod.product_id), description: res.body.description };
        });
    });
    Promise.all(ps).then((all) => {
      const product_map = all.filter(notEmpty);
      setState({ ...state, product_map });
    });
  }, []);

  const submitForm = () => {
    const pids = state.product_map?.map((p) => {
      return { product_id: p.id };
    });
    state.products = pids;
    delete state.product_map;
    return onUpdate(state as Entity);
  };

  return (
    <div>
      <section class="section">
        <section class="hero is-hero-bar">
          <div class="hero-body">
            <div class="level">
              <div class="level-left">
                <div class="level-item">
                  <span class="is-size-4">
                    <i18n.Translate>Id:</i18n.Translate>
                    &nbsp;
                    <b>{category.id}</b>
                  </span>
                </div>
              </div>
            </div>
          </div>
        </section>
        <hr />

        <section class="section is-main-section">
          <div class="columns">
            <div class="column is-four-fifths">
              <FormProvider object={state} valueHandler={setState}>
                <Input<Entity>
                  name="name"
                  label={i18n.str`Name`}
                  tooltip={i18n.str`Name of the category`}
                />
                <InputArray
                  name="product_map"
                  label={i18n.str`Products`}
                  getSuggestion={async () => {
                    return inventory.map((prod) => {
                      return {
                        description: prod.description,
                        id: prod.id,
                      };
                    });
                  }}
                  help={i18n.str`Search by product description or id`}
                  tooltip={i18n.str`Products that this category will list.`}
                  unique
                />
              </FormProvider>

              <div class="buttons is-right mt-5">
                {onBack && (
                  <button class="button" onClick={onBack}>
                    <i18n.Translate>Cancel</i18n.Translate>
                  </button>
                )}
                <AsyncButton
                  disabled={false}
                  data-tooltip={i18n.str`Confirm operation`}
                  onClick={submitForm}
                >
                  <i18n.Translate>Confirm</i18n.Translate>
                </AsyncButton>
              </div>
            </div>
          </div>
        </section>
      </section>
    </div>
  );
}
function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
  return value !== null && value !== undefined;
}
