import { useState, type ReactElement } from 'react';
import { Edit } from 'lucide-react';
import { Controller, useForm, type SubmitHandler } from 'react-hook-form';
import { Loader, Modal, NumberInput, Overlay, Select } from '@mantine/core';
import {
  BusinessTripExpenseCategories,
  type CategorizeBusinessTripExpenseInput,
} from '../../../../gql/graphql.js';
import { useCategorizeBusinessTripExpense } from '../../../../hooks/use-categorize-business-trip-expense.js';
import { Button } from '../../../ui/button.js';
import { Tooltip } from '../../index.js';

export function CategorizeExpense(props: {
  businessTripId: string;
  transactionId: string;
  defaultAmount?: number;
  onChange: () => void;
}): ReactElement {
  const { businessTripId, transactionId, onChange, defaultAmount } = props;
  const [opened, setOpened] = useState(false);

  return (
    <>
      <Tooltip content="Categorize">
        <Button
          variant="outline"
          size="icon"
          className="size-7.5"
          onClick={(event): void => {
            event.stopPropagation();
            setOpened(true);
          }}
        >
          <Edit className="size-5" />
        </Button>
      </Tooltip>
      {opened && (
        <ModalContent
          businessTripId={businessTripId}
          transactionId={transactionId}
          opened={opened}
          close={() => setOpened(false)}
          onChange={onChange}
          defaultAmount={defaultAmount}
        />
      )}
    </>
  );
}

const categories = Object.entries(BusinessTripExpenseCategories).map(([key, value]) => ({
  value,
  label: key,
}));

type ModalProps = {
  opened: boolean;
  close: () => void;
  onChange: () => void;
  businessTripId: string;
  transactionId: string;
  defaultAmount?: number;
};

function ModalContent({
  businessTripId,
  transactionId,
  defaultAmount,
  opened,
  close,
  onChange,
}: ModalProps): ReactElement {
  const { control, handleSubmit } = useForm<CategorizeBusinessTripExpenseInput>({
    defaultValues: { businessTripId, transactionId },
  });

  const { categorizeBusinessTripExpense, fetching: updatingInProcess } =
    useCategorizeBusinessTripExpense();

  const onSubmit: SubmitHandler<CategorizeBusinessTripExpenseInput> = data => {
    categorizeBusinessTripExpense({ fields: data }).then(() => {
      onChange?.();
      close();
    });
  };

  return (
    <Modal opened={opened} onClose={close} centered>
      <Modal.Title>Set Expense Category</Modal.Title>
      <Modal.Body>
        <form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-3 mt-3">
          <Controller
            name="category"
            control={control}
            render={({ field, fieldState }): ReactElement => (
              <Select
                data-autofocus
                {...field}
                data={categories}
                value={field.value}
                label="Category"
                placeholder="Scroll to see all options"
                maxDropdownHeight={160}
                searchable
                error={fieldState.error?.message}
                withinPortal
              />
            )}
          />
          <Controller
            name="amount"
            control={control}
            defaultValue={defaultAmount}
            render={({ field, fieldState }): ReactElement => (
              <NumberInput
                {...field}
                value={field.value ?? undefined}
                hideControls
                precision={2}
                removeTrailingZeros
                error={fieldState.error?.message}
                label="Amount"
              />
            )}
          />

          <div className="flex justify-center gap-3">
            <button
              type="submit"
              className="text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-hidden hover:bg-indigo-600 rounded-sm text-lg"
            >
              Confirm
            </button>
          </div>
        </form>
      </Modal.Body>
      {updatingInProcess && (
        <Overlay blur={1} center>
          <Loader />
        </Overlay>
      )}
    </Modal>
  );
}
