import React, { useCallback } from "react";
import { useParams } from "react-router-dom";

import Card from "../../../components/Card";
import CardActions from "../../../components/Card/CardActions";
import CardCancelButton from "../../../components/Card/CardCancelButton";
import CardContent from "../../../components/Card/CardContent";
import CardFieldText from "../../../components/Card/CardFieldText";
import CardHeader from "../../../components/Card/CardHeader";
import CardRow from "../../../components/Card/CardRow";
import CardSaveButton from "../../../components/Card/CardSaveButton";
import { useApi } from "../../../contexts/ApiContext";
import { useI18n } from "../../../contexts/I18nContext";
import { useUser } from "../../../contexts/UserContext";
import { hasPermission } from "../../../util/has_permission";
import { ArticleCreated, ArticleDetail } from "../types/article";
import { PHYSICAL_ITEM_TYPES } from "../utils";

export type ArticleCardProps =
  | {
      create: true;
      article?: ArticleDetail;
      onCreated: (article: ArticleCreated) => void;
      onUpdated?: never;
    }
  | {
      create?: false;
      article: ArticleDetail;
      onCreated?: never;
      onUpdated: (article: ArticleDetail) => void;
    };

export const ArticleCard: React.FC<ArticleCardProps> = ({
  article,
  create,
  onCreated,
  onUpdated,
}) => {
  const params = useParams();
  const api = useApi();
  const { t } = useI18n();
  const { user } = useUser();

  article ??= {
    name: "",
    variant: "",
    item_type: "",
    code: "",
    model_number: "",
    product_number: "",
    gtin: "",
    tax_code: "",
  };

  const handleSave = useCallback(
    async (values: unknown) => {
      if (create != null) {
        const action = api.operations["catalog.article:create"];
        if (!action) {
          throw new Error('Invalid action "catalog.article:create".');
        }

        const response = await action.call({
          params,
          body: values,
        });

        if (response.ok) {
          const createdArticle = await response.json();
          onCreated?.(createdArticle);
          return t("Article created successfully.");
        } else {
          console.error("[ARTICLE_CARD]", response);
          throw new Error("creating article.");
        }
      } else {
        const action = api.operations["catalog.article:update"];
        if (!action) {
          throw new Error('Invalid action "catalog.article:update".');
        }

        const response = await action.call({
          params,
          body: values,
        });

        if (response.ok) {
          const updatedArticle = await response.json();
          onUpdated?.(updatedArticle);
          return t("Article updated successfully.");
        } else {
          console.error("[ARTICLE_CARD]", response);
          throw new Error("updating article fields.");
        }
      }
    },
    [api, params, create, onCreated, onUpdated, t],
  );

  return (
    <Card
      columns={3}
      defaultEditing={create}
      isEditable={hasPermission(user, "catalog.change_article")}
      onSubmit={handleSave}
    >
      <CardHeader title={t("Article")} />

      <CardContent>
        <CardRow>
          <CardFieldText
            formName="item_type"
            label={t("Type")}
            required={true}
            value={article.item_type}
          />
        </CardRow>

        <CardRow>
          <CardFieldText
            formName="name"
            label={t("Name")}
            required={true}
            size={1}
            value={article.name}
          />
          <CardFieldText formName="variant" label={t("Variant")} size={1} value={article.variant} />
        </CardRow>
        <CardRow>
          <CardFieldText
            formName="code"
            label={t("Article number")}
            required={true}
            value={article.code}
          />
          <CardFieldText
            formName="product_number"
            label={t("Product number")}
            value={article.product_number}
          />
          <CardFieldText
            formName="model_number"
            label={t("Model number")}
            value={article.model_number}
          />
        </CardRow>

        {(PHYSICAL_ITEM_TYPES.includes(article.item_type) || create) && (
          <>
            <CardRow>
              <CardFieldText formName="gtin" label="GTIN" required={false} value={article.gtin} />
            </CardRow>
            <CardRow>
              <CardFieldText
                formName="tax_code"
                label="Tax code"
                required={false}
                value={article.tax_code}
              />
            </CardRow>
          </>
        )}
      </CardContent>

      <CardActions>
        {!create && <CardCancelButton />}
        <CardSaveButton label={create ? "Create" : "Save"} />
      </CardActions>
    </Card>
  );
};
