import { useCallback, useRef } from 'react';
import Debug from 'debug';

import type { DialogBoxProps } from '~/src/components/DialogBox';
import type { FormApi } from '~/src/components/Form';
import type { FC } from 'react';
import type { LayoutData } from '../../../types';
import type { EditLinkDialogBoxProps } from '../../lib/EditLinkDialogBox';
import type { PresaveButtonsItem, PresaveReleaseItem } from '../types';

import Clickable from '~/src/components/Clickable';
import DialogBox, {
  DIALOG_BOX_CONTENT_PADDING_X,
} from '~/src/components/DialogBox';
import { DialogBoxHeader } from '~/src/components/DialogBox/DialogBoxHeader';
import Form, { FORM_SECTION_SPACING } from '~/src/components/Form';
import Text from '~/src/components/Text';
import useIsLargeScreen from '~/src/hooks/useIsLargeScreen';
import getServiceDisplayData from '~/src/lib/getServiceDisplayData';
import { useI18n } from '~/src/lib/i18n';
import { resolveLink } from '../../lib';
import { EditLinkDialogBox } from '../../lib/EditLinkDialogBox';
import RemoveButton from '../../lib/RemoveButton';
import TextInputWithIconButton from '../../lib/TextInputWithIconButton';

const debug = Debug('songwhip/EditItemDialog');

interface EditItemDialogProps extends Pick<DialogBoxProps, 'onClose'> {
  onDelete: (params: PresaveReleaseItem) => void;
  onLinkItemSubmit: EditLinkDialogBoxProps['onSubmit'];
  onSubscribeItemSubmit: (item: PresaveButtonsItem) => void;
  layoutData: LayoutData;
  item: PresaveReleaseItem;
}

export const EditItemDialog: FC<EditItemDialogProps> = ({
  item,
  layoutData,
  onDelete,
  onLinkItemSubmit,
  onSubscribeItemSubmit,
  onClose,
}) => {
  if (item.type === 'link') {
    const itemResolved = resolveLink(layoutData, item.dataPath);

    return (
      <EditLinkDialogBox
        item={itemResolved!}
        onSubmit={onLinkItemSubmit}
        onDelete={() => onDelete(item)}
        onClose={onClose}
        withEmailAndOptInsSetting
        initialEmailAndOptInsValue={item.withEmailAndOptIns}
      />
    );
  }

  return (
    <EditSubscribeItemDialog
      item={item}
      onSubmit={onSubscribeItemSubmit}
      onDelete={onDelete}
      onClose={onClose}
    />
  );
};

const EditSubscribeItemDialog: FC<{
  item: PresaveButtonsItem;
  onSubmit: (item: PresaveButtonsItem) => void;
  onDelete: (params: PresaveReleaseItem) => void;
  onClose: () => void;
}> = ({ item, onSubmit, onClose, onDelete }) => {
  const formApiRef = useRef<FormApi>(null);
  const isLargeScreen = useIsLargeScreen();
  const service = getServiceDisplayData(item.service)!;
  const initialText = item.text || service.name;
  const { t } = useI18n();

  return (
    <DialogBox
      fillViewport={!isLargeScreen}
      onClose={onClose}
      renderHeader={useCallback(
        ({ close }) => (
          <DialogBoxHeader
            title={t('itemEdit.labels.changeButtonText')}
            onCloseClick={close}
            renderRight={({ textProps }) => (
              <Clickable
                testId="done"
                onClick={() => {
                  formApiRef.current?.submit();
                }}
              >
                <Text {...textProps}>{t('app.actions.done')}</Text>
              </Clickable>
            )}
          />
        ),
        []
      )}
      renderContent={useCallback(
        ({ close }) => {
          return (
            <Form<{ text: string }>
              padding={`0 ${DIALOG_BOX_CONTENT_PADDING_X} ${FORM_SECTION_SPACING}`}
              apiRef={formApiRef}
              onSubmit={async ({ values }) => {
                const didChange = values.text !== initialText;

                await close();

                if (didChange) {
                  onSubmit({
                    ...item,
                    text: values.text,
                  });
                }
              }}
            >
              <TextInputWithIconButton
                Icon={service.Icon}
                name="text"
                iconButtonDisabled
                defaultValue={initialText}
                testId="buttonTextInput"
              />
              <RemoveButton
                text={t('itemEdit.actions.removeButton')}
                margin={`${DIALOG_BOX_CONTENT_PADDING_X} 0 0`}
                testId="remove"
                isInline
                onClick={async () => {
                  debug('delete click');

                  await close();
                  debug('closed');

                  onDelete(item);
                }}
              />
            </Form>
          );
        },
        [item]
      )}
    />
  );
};
