import React 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 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 { ProductItemTypeOption, ProductPropertiesData } from "../types/product";

import { ProductPropertyField } from "./ProductPropertyField";

export interface ProductPropertiesCardProps {
  itemType: ProductItemTypeOption;
  productProperties: ProductPropertiesData;
  setProductProperties: (properties: ProductPropertiesData) => void;
}

export const ProductPropertiesCard: React.FC<ProductPropertiesCardProps> = ({
  itemType,
  productProperties,
  setProductProperties,
}) => {
  const params = useParams();
  const api = useApi();
  const { t } = useI18n();
  const { user } = useUser();

  const productPropertiesList = itemType ? itemType.product_properties : [];

  const productPropertiesRows = productPropertiesList.reduce<(typeof productPropertiesList)[]>(
    (rows, prop, index) => {
      if (index % 2 === 0) rows.push([prop]);
      else rows[rows.length - 1].push(prop);
      return rows;
    },
    [],
  );

  const handleSubmit = async (values: ProductPropertiesData) => {
    const action = api.operations["pim.product:update"];
    if (!action) {
      throw new Error('Invalid action "pim.product:update".');
    }

    productPropertiesList.map((prop) => {
      switch (prop.type) {
        case "string": {
          if (!prop.required && values[prop.name] == "") {
            delete values[prop.name];
          }
          break;
        }
        case "integer": {
          if (!prop.required && values[prop.name] == "") {
            delete values[prop.name];
          }
          break;
        }
        case "array": {
          values[prop.name] =
            typeof values[prop.name] === "string"
              ? [values[prop.name] as string]
              : ((values[prop.name] as string[]) ?? []);
          break;
        }
      }
    });

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

    if (response.ok) {
      const updatedProduct = await response.json();
      setProductProperties(updatedProduct.properties);
      return t("Product properties updated successfully.");
    } else {
      console.error("[PRODUCT_PROPERTIES_CARD]", response);
      throw new Error("updating product properties fields.");
    }
  };

  return (
    <>
      <Card<ProductPropertiesData>
        columns={2}
        isEditable={hasPermission(user, "pim.change_product")}
        onSubmit={handleSubmit}
      >
        <CardHeader title={t("Properties")} />

        <CardContent>
          {productPropertiesRows.map((row, index) => (
            <CardRow key={index}>
              {row.map((prop) => (
                <ProductPropertyField
                  key={prop.name}
                  property={prop}
                  value={productProperties[prop.name]}
                />
              ))}
            </CardRow>
          ))}
        </CardContent>

        <CardActions>
          <CardCancelButton />
          <CardSaveButton />
        </CardActions>
      </Card>
    </>
  );
};
