import React, { useState } from 'react';
import styled from 'styled-components';
import { useFormikContext } from 'formik';
import { INVOICE_ITEMS_DISCOUNT_TYPES } from '@tamanu/constants';
import { TranslatedText } from '../../../components/Translation';
import { INVOICE_ITEM_ACTION_MODAL_TYPES } from '../../../constants';
import { NoteModalActionBlocker } from '../../../components';
import { InvoiceItemActionModal } from './InvoiceItemActionModal';
import { ThreeDotMenu } from '../../../components/ThreeDotMenu';

const useInvoiceItemActionsMenu = ({
  item,
  index,
  hidePriceInput,
  onUpdateInvoice,
  onUpdateApproval,
  isFinalised,
  isSaved,
}) => {
  const [actionModal, setActionModal] = useState();
  const { values } = useFormikContext();

  const onCloseActionModal = () => {
    setActionModal(undefined);
  };

  const handleApproval = approved => {
    // Use dedicated approval endpoint if available (works for both in-progress and finalised invoices)
    onUpdateApproval({ itemId: item.id, approved });
  };

  const handleAction = async (data, type = actionModal) => {
    const updatedInvoiceItems = [...values.invoiceItems];

    switch (type) {
      case INVOICE_ITEM_ACTION_MODAL_TYPES.DELETE: {
        updatedInvoiceItems.splice(index, 1);
        break;
      }
      case INVOICE_ITEM_ACTION_MODAL_TYPES.ADD_DISCOUNT: {
        updatedInvoiceItems[index] = {
          ...item,
          discount: {
            ...item.discount,
            amount:
              data.type === INVOICE_ITEMS_DISCOUNT_TYPES.PERCENTAGE
                ? data.amount / 100
                : data.amount,
            type: data.type,
            reason: data.reason,
          },
        };
        break;
      }
      case INVOICE_ITEM_ACTION_MODAL_TYPES.ADD_MARKUP: {
        updatedInvoiceItems[index] = {
          ...item,
          discount: {
            ...item.discount,
            amount:
              data.type === INVOICE_ITEMS_DISCOUNT_TYPES.PERCENTAGE
                ? -(data.amount / 100)
                : -data.amount,
            type: data.type,
            reason: data.reason,
          },
        };
        break;
      }
      case INVOICE_ITEM_ACTION_MODAL_TYPES.REMOVE_DISCOUNT_MARKUP: {
        updatedInvoiceItems[index] = {
          ...item,
          discount: undefined,
        };
        break;
      }
      case INVOICE_ITEM_ACTION_MODAL_TYPES.ADD_NOTE: {
        updatedInvoiceItems[index] = {
          ...item,
          note: data.note,
        };
        break;
      }
    }

    onUpdateInvoice({ ...values, invoiceItems: updatedInvoiceItems });
    onCloseActionModal();
  };

  const menuItems = [
    {
      label:
        Number(item.discount?.amount) < 0 ? (
          <TranslatedText
            stringId="invoice.modal.editInvoice.removeMarkup"
            fallback="Remove markup"
          />
        ) : (
          <TranslatedText
            stringId="invoice.modal.editInvoice.removeDiscount"
            fallback="Remove discount"
          />
        ),
      onClick: () => handleAction({}, INVOICE_ITEM_ACTION_MODAL_TYPES.REMOVE_DISCOUNT_MARKUP),
      hidden: !item.discount?.amount || isFinalised,
    },
    {
      label: (
        <TranslatedText stringId="invoice.modal.editInvoice.addDiscount" fallback="Add discount" />
      ),
      onClick: () => setActionModal(INVOICE_ITEM_ACTION_MODAL_TYPES.ADD_DISCOUNT),
      disabled: !item.productId,
      hidden: !!item.discount?.amount || !hidePriceInput || isFinalised,
    },
    {
      label: (
        <TranslatedText stringId="invoice.modal.editInvoice.addMarkup" fallback="Add markup" />
      ),
      onClick: () => setActionModal(INVOICE_ITEM_ACTION_MODAL_TYPES.ADD_MARKUP),
      disabled: !item.productId,
      hidden: !!item.discount?.amount || !hidePriceInput || isFinalised,
    },
    {
      label: item.note ? (
        <TranslatedText stringId="invoice.modal.editInvoice.editNote" fallback="Edit note" />
      ) : (
        <TranslatedText stringId="invoice.modal.editInvoice.addNote" fallback="Add note" />
      ),
      onClick: () => setActionModal(INVOICE_ITEM_ACTION_MODAL_TYPES.ADD_NOTE),
      disabled: !item.productId,
      hidden: !!item.sourceId || isFinalised,
    },
    {
      label: (
        <TranslatedText stringId="invoice.editInvoice.removeApproval" fallback="Remove approval" />
      ),
      onClick: () => handleApproval(false),
      hidden: !item.approved || !isSaved,
    },
    {
      label: (
        <TranslatedText
          stringId="invoice.editInvoice.markAsApproved"
          fallback="Mark as approved"
          data-testid="translatedtext-c3a4"
        />
      ),
      onClick: () => handleApproval(true),
      hidden: item.approved || !isSaved,
    },
    {
      label: (
        <TranslatedText
          stringId="invoice.modal.editInvoice.delete"
          fallback="Delete"
          data-testid="translatedtext-wwxo"
        />
      ),
      onClick: () => {
        isSaved
          ? setActionModal(INVOICE_ITEM_ACTION_MODAL_TYPES.DELETE)
          : handleAction({}, INVOICE_ITEM_ACTION_MODAL_TYPES.DELETE);
      },
      hidden: isFinalised,
    },
  ];

  return {
    actionModal,
    setActionModal,
    onCloseActionModal,
    handleAction,
    menuItems,
  };
};

const MenuAnchor = styled.div`
  margin-block: -12px;
  margin-inline: -10px;
`;

export const InvoiceItemActionsMenu = ({
  item,
  index,
  showActionMenu,
  hidePriceInput,
  onUpdateInvoice,
  onUpdateApproval,
  isFinalised,
  isSaved,
}) => {
  const { actionModal, onCloseActionModal, handleAction, menuItems } = useInvoiceItemActionsMenu({
    item,
    onUpdateInvoice,
    onUpdateApproval,
    index,
    hidePriceInput,
    isFinalised,
    isSaved,
  });
  return (
    <>
      {showActionMenu && (
        <MenuAnchor>
          <NoteModalActionBlocker>
            <ThreeDotMenu items={menuItems} data-testid="threedotmenu-zw6l" />
          </NoteModalActionBlocker>
        </MenuAnchor>
      )}
      {actionModal && (
        <InvoiceItemActionModal
          open
          action={actionModal}
          onClose={onCloseActionModal}
          onAction={data => handleAction(data)}
          item={item}
          data-testid="invoiceitemactionmodal-lar4"
        />
      )}
    </>
  );
};
