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

import CancelIcon from "@mui/icons-material/Cancel";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";

import Card from "../../../components/Card";
import CardActions from "../../../components/Card/CardActions";
import CardCancelButton from "../../../components/Card/CardCancelButton";
import CardContent from "../../../components/Card/CardContent";
import CardFieldCheckbox from "../../../components/Card/CardFieldCheckbox";
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 interface ArticleCardFormValues {
  code: string;
  item_type: string;
  is_active: string;
  name: string;
  description: string;
  product_number: string;
  model_number: string;
  tax_code: string;
  gtin: string;
  variant: string;
}

export const ArticleCard: React.FC<ArticleCardProps> = ({
  article,
  create,
  onCreated,
  onUpdated,
}) => {
  const params = useParams();
  const api = useApi();
  const { t } = useI18n();
  const { user } = useUser();
  const canCreate = useMemo(() => hasPermission(user, "catalog.add_article"), [user]);
  const canChange = useMemo(() => hasPermission(user, "catalog.change_article"), [user]);

  article ??= {
    id: 0,
    name: "",
    variant: "",
    item_type: "",
    code: "",
    model_number: "",
    product_number: "",
    gtin: "",
    tax_code: "",
    is_active: true,
    variants: [],
  };

  const handleSave = useCallback(
    async ({ is_active, ...values }: ArticleCardFormValues) => {
      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: {
            is_active: is_active == "on",
            ...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: {
            is_active: is_active == "on",
            ...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
      alwaysEditable={create && canCreate}
      columns={3}
      defaultEditing={create && canCreate}
      isEditable={(create && canCreate) || (!create && canChange)}
      onSubmit={handleSave}
    >
      <CardHeader title={t("Article")} />

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

        <CardRow>
          <CardFieldText
            formName="name"
            label={t("Name")}
            required={true}
            size={2}
            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="tax_code"
                label="Tax code"
                required={false}
                size={1}
                value={article.tax_code}
              />
              <CardFieldText
                formName="gtin"
                label="GTIN"
                required={false}
                size={1}
                value={article.gtin}
              />
              <CardFieldCheckbox
                formName="is_active"
                label={t("Active")}
                noValue={<CancelIcon color="error" fontSize="small" />}
                size={1}
                value={article.is_active}
                yesValue={<CheckCircleIcon color="success" fontSize="small" />}
              />
            </CardRow>
          </>
        )}
      </CardContent>

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