/*
 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 { TalerMerchantApi, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { Fragment, h } from "preact";
import { useLayoutEffect, useState } from "preact/hooks";
import { FormErrors, FormProvider } from "./FormProvider.js";
import { InputDate } from "./InputDate.js";
import { InputGroup } from "./InputGroup.js";
import { InputLocation } from "./InputLocation.js";
import { InputNumber } from "./InputNumber.js";
import { InputProps, useField } from "./useField.js";

export interface Props<T> extends InputProps<T> {
  alreadyExist?: boolean;
}

type Entity = Stock;

export interface Stock {
  current: number;
  lost: number;
  sold: number;
  address?: TalerMerchantApi.Location;
  nextRestock?: TalerProtocolTimestamp;
}

interface StockDelta {
  incoming: number;
  lost: number;
}

export function InputStock<T>({
  name,
  tooltip,
  label,
  alreadyExist,
}: Props<keyof T>) {
  const { error, value, onChange } = useField<T>(name);

  const [errors, setErrors] = useState<FormErrors<Entity>>({});

  const [formValue, valueHandler] = useState<Partial<Entity>>(value);
  const [addedStock, setAddedStock] = useState<StockDelta>({
    incoming: 0,
    lost: 0,
  });
  const { i18n } = useTranslationContext();

  useLayoutEffect(() => {
    if (!formValue) {
      onChange(undefined as any);
    } else {
      onChange({
        ...formValue,
        current: (formValue?.current || 0) + addedStock.incoming,
        lost: (formValue?.lost || 0) + addedStock.lost,
      } as any);
    }
  }, [formValue, addedStock]);

  if (!formValue) {
    return (
      <Fragment>
        <div class="field is-horizontal">
          <div class="field-label is-normal">
            <label class="label">
              {label}
              {tooltip && (
                <span class="icon has-tooltip-right" data-tooltip={tooltip}>
                  <i class="mdi mdi-information" />
                </span>
              )}
            </label>
          </div>
          <div class="field-body is-flex-grow-3">
            <div class="field has-addons">
              {!alreadyExist ? (
                <button
                  class="button"
                  data-tooltip={i18n.str`Click here to configure the product's stock. If left as is, the backend will not control stock.`}
                  onClick={(): void => {
                    valueHandler({
                      current: 0,
                      lost: 0,
                      sold: 0,
                    } as Stock as any);
                  }}
                >
                  <span>
                    <i18n.Translate>Manage stock</i18n.Translate>
                  </span>
                </button>
              ) : (
                <button
                  class="button"
                  data-tooltip={i18n.str`This product has been configured without stock control`}
                  disabled
                >
                  <span>
                    <i18n.Translate>Infinite</i18n.Translate>
                  </span>
                </button>
              )}
            </div>
          </div>
        </div>
      </Fragment>
    );
  }

  const currentStock =
    (formValue.current || 0) - (formValue.lost || 0) - (formValue.sold || 0);

  const stockAddedErrors: FormErrors<typeof addedStock> = {
    lost:
      currentStock + addedStock.incoming < addedStock.lost
        ? i18n.str`Shrinkage cannot exceed the current stock and incoming supplies (maximum ${currentStock + addedStock.incoming
          })`
        : undefined,
  };

  return (
    <Fragment>
      <div class="card">
        <header class="card-header">
          <p class="card-header-title">
            {label}
            {tooltip && (
              <span class="icon" data-tooltip={tooltip}>
                <i class="mdi mdi-information" />
              </span>
            )}
          </p>
        </header>
        <div class="card-content">
          <FormProvider<Entity>
            name="stock"
            errors={errors}
            object={formValue}
            valueHandler={valueHandler}
          >
            {alreadyExist ? (
              <Fragment>
                <FormProvider
                  name="added"
                  errors={stockAddedErrors}
                  object={addedStock}
                  valueHandler={setAddedStock as any}
                >
                  <InputNumber name="incoming" label={i18n.str`Incoming`} />
                  <InputNumber name="lost" label={i18n.str`Lost`} />
                </FormProvider>

                {/* <div class="field is-horizontal">
              <div class="field-label is-normal" />
              <div class="field-body is-flex-grow-3">
                <div class="field">
                  {stockUpdateDescription}
                </div>
              </div>
            </div> */}
              </Fragment>
            ) : (
              <InputNumber<Entity>
                name="current"
                label={i18n.str`Current`}
                side={
                  <button
                    class="button is-danger"
                    data-tooltip={i18n.str`Remove stock control for this product`}
                    onClick={(): void => {
                      valueHandler(undefined as any);
                    }}
                  >
                    <span>
                      <i18n.Translate>without stock</i18n.Translate>
                    </span>
                  </button>
                }
              />
            )}

            <InputDate<Entity>
              name="nextRestock"
              label={i18n.str`Next restock`}
              withTimestampSupport
            />

            <InputGroup<Entity> name="address" label={i18n.str`Warehouse address`}>
              <InputLocation name="address" />
            </InputGroup>
          </FormProvider>
        </div>
      </div>
    </Fragment>
  );
}
// (
