/*
 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 { useTranslationContext } from "@gnu-taler/web-util/browser";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import emptyImage from "../../assets/empty.png";
import { FormErrors, FormProvider } from "./FormProvider.js";
import { InputWithAddon } from "./InputWithAddon.js";
import { TranslatedString } from "@gnu-taler/taler-util";


const TALER_SCREEN_ID = 12;

type Entity = {
  id: string;
  description: string;
  image?: string;
  extra?: string;
};

export interface Props<T extends Entity> {
  selected?: T;
  onChange: (p?: T) => void;
  label: TranslatedString;
  list: T[];
  withImage?: boolean;
}

interface Search {
  name: string;
}

export function InputSearchOnList<T extends Entity>({
  selected,
  onChange,
  label,
  list,
  withImage,
}: Props<T>): VNode {
  const [nameForm, setNameForm] = useState<Partial<Search>>({
    name: "",
  });

  const errors: FormErrors<Search> = {
    name: undefined,
  };
  const { i18n } = useTranslationContext();

  if (selected) {
    return (
      <article class="media">
        {withImage && (
          <figure class="media-left">
            <p class="image is-128x128">
              <img src={selected.image ? selected.image : emptyImage} />
            </p>
          </figure>
        )}
        <div class="media-content">
          <div class="content">
            <p class="media-meta">
              <i18n.Translate>ID</i18n.Translate>: <b>{selected.id}</b>
            </p>
            <p>
              <i18n.Translate>Description</i18n.Translate>:{" "}
              {selected.description}
            </p>
            <div class="buttons is-right mt-5">
              <button type="button"                class="button is-info"
                onClick={() => onChange(undefined)}
              >
                <i18n.Translate>Clear</i18n.Translate>
              </button>
            </div>
          </div>
        </div>
      </article>
    );
  }

  return (
    <FormProvider<Search>
      errors={errors}
      object={nameForm}
      valueHandler={setNameForm}
    >
      <InputWithAddon<Search>
        name="name"
        label={label}
        tooltip={i18n.str`Enter description or id`}
        addonAfter={
          <span class="icon">
            <i class="mdi mdi-magnify" />
          </span>
        }
      >
        <div>
          <DropdownList
            name={nameForm.name}
            list={list}
            onSelect={(p) => {
              setNameForm({ name: "" });
              onChange(p);
            }}
            withImage={!!withImage}
          />
        </div>
      </InputWithAddon>
    </FormProvider>
  );
}

interface DropdownListProps<T extends Entity> {
  name?: string;
  onSelect: (p: T) => void;
  list: T[];
  withImage: boolean;
}

export function DropdownList<T extends Entity>({
  name,
  onSelect,
  list,
  withImage,
}: DropdownListProps<T>) {
  const { i18n } = useTranslationContext();
  if (!name) {
    /* FIXME
      this BR is added to occupy the space that will be added when the 
      dropdown appears
    */
    return (
      <div>
        <br />
      </div>
    );
  }

  const MATCH_NAME = new RegExp(name, "i");
  const filtered = list.filter(
    (p) => MATCH_NAME.test(p.id) || MATCH_NAME.test(p.description),
  );

  return (
    <div class="dropdown is-active">
      <div
        class="dropdown-menu"
        id="dropdown-menu"
        role="menu"
        style={{ minWidth: "20rem" }}
      >
        <div class="dropdown-content">
          {!filtered.length ? (
            <div class="dropdown-item">
              <i18n.Translate>
                No match found for that description or ID.
              </i18n.Translate>
            </div>
          ) : (
            filtered.map((p) => (
              <div
                key={p.id}
                class="dropdown-item"
                onClick={() => onSelect(p)}
                style={{ cursor: "pointer" }}
              >
                <article class="media">
                  {withImage && (
                    <div class="media-left">
                      <div class="image" style={{ minWidth: 64 }}>
                        <img
                          src={p.image ? p.image : emptyImage}
                          style={{ width: 64, height: 64 }}
                        />
                      </div>
                    </div>
                  )}
                  <div class="media-content">
                    <div class="content">
                      <p>
                        <strong>{p.id}</strong>{" "}
                        {p.extra !== undefined ? (
                          <small>{p.extra}</small>
                        ) : undefined}
                        <br />
                        {p.description}
                      </p>
                    </div>
                  </div>
                </article>
              </div>
            ))
          )}
        </div>
      </div>
    </div>
  );
}
