import clsx from "clsx";
import { FC, HTMLAttributes, MouseEvent } from "react";

import {
  characterActions,
  Item,
  ItemPlan,
  ItemPlanUtils,
  ItemUtils,
} from "@dndbeyond/character-rules-engine";

import { Button } from "~/components/Button";
import { useSidebar } from "~/contexts/Sidebar";
import { useCharacterEngine } from "~/hooks/useCharacterEngine";
import { useDispatch } from "~/hooks/useDispatch";
import { PaneIdentifierUtils } from "~/tools/js/Shared/utils";
import ItemPreview from "~/tools/js/smartComponents/ItemPreview";

import { PaneComponentEnum } from "../Sidebar/types";
import styles from "./styles.module.css";

export interface MagicItemPlansProps extends HTMLAttributes<HTMLDivElement> {}

export const MagicItemPlans: FC<MagicItemPlansProps> = ({
  className,
  ...props
}) => {
  const { characterTheme, itemPlans, maxReplicatedItemsCount } =
    useCharacterEngine();
  const {
    pane: { paneHistoryStart },
  } = useSidebar();
  const dispatch = useDispatch();

  const itemPlanWithMappingsCount = itemPlans.filter((plan) =>
    ItemPlanUtils.getItem(plan)
  ).length;

  const atMax =
    maxReplicatedItemsCount !== null &&
    itemPlanWithMappingsCount >= maxReplicatedItemsCount;

  const handleItemPlansManagePaneShow = (
    e: MouseEvent<HTMLButtonElement>
  ): void => {
    e.preventDefault();
    e.stopPropagation();

    paneHistoryStart(PaneComponentEnum.ITEM_PLANS_MANAGE);
  };

  const handleItemClick = (item: Item): void => {
    const inventoryMappingId = ItemUtils.getMappingId(item);

    if (inventoryMappingId) {
      paneHistoryStart(
        PaneComponentEnum.ITEM_DETAIL,
        PaneIdentifierUtils.generateItem(inventoryMappingId)
      );
    }
  };

  const handleReplicateItem = (itemPlan: ItemPlan): void => {
    const itemDefinitionKey = ItemPlanUtils.getItemDefinitionKey(itemPlan);
    const itemPlanOriginDefinitionKey =
      ItemPlanUtils.getOriginDefinitionKey(itemPlan);

    if (itemDefinitionKey) {
      dispatch(
        characterActions.itemPlanInventoryMappingCreate(
          itemDefinitionKey,
          1,
          itemPlanOriginDefinitionKey
        )
      );
    }
  };

  return (
    <div className={clsx([styles.magicItemPlans, className])} {...props}>
      {itemPlans.length > 0 ? (
        itemPlans.map((plan) => {
          const planOriginDefinitionKey =
            ItemPlanUtils.getOriginDefinitionKey(plan);
          const planName = ItemPlanUtils.getItemName(plan);
          const itemDefinitionKey = ItemPlanUtils.getItemDefinitionKey(plan);
          const item = ItemPlanUtils.getItem(plan);
          const planDescription = ItemPlanUtils.getDescription(plan);

          return itemDefinitionKey ? (
            <div className={styles.itemPlan} key={planOriginDefinitionKey}>
              <div className={styles.planHeader}>
                <p className={styles.planName}>{planName}</p>
                <p className={styles.description}>{planDescription}</p>
              </div>
              <div className={styles.itemContent}>
                {item ? (
                  <div className={styles.itemPreview}>
                    <ItemPreview
                      theme={characterTheme}
                      item={item}
                      onClick={() => handleItemClick(item)}
                    />
                  </div>
                ) : (
                  <Button
                    className={styles.replicateButton}
                    themed
                    size="xx-small"
                    onClick={() => handleReplicateItem(plan)}
                    disabled={atMax}
                  >
                    {atMax ? "At Max Replicated Items" : "Replicate Item"}
                  </Button>
                )}
              </div>
            </div>
          ) : null;
        })
      ) : (
        <div className={styles.empty}>
          No Magic Item plans have been selected for this character
          <Button
            className={styles.emptyButton}
            themed
            size="x-small"
            onClick={handleItemPlansManagePaneShow}
          >
            Add Magic Item Plans
          </Button>
        </div>
      )}
    </div>
  );
};
