import { useRef, useState } from 'react';

import type { MappedContentLink } from '~/lib/songwhipApi/mapper';
import type { FormApi, FormOnSubmit, FormValues } from '~/src/components/Form';

import { toNumber } from '~/lib/utils/number';
import Box from '~/src/components/Box';
import { ConfirmButton } from '~/src/components/Button/ConfirmButton';
import { Clickable } from '~/src/components/Clickable';
import { DialogBoxHeader } from '~/src/components/DialogBox/DialogBoxHeader';
import ErrorText from '~/src/components/ErrorText';
import Form from '~/src/components/Form';
import {
  InputLabelDescription,
  InputLabelValue,
} from '~/src/components/InputLabel';
import { useAppAlert, useAppToast } from '~/src/components/NextApp/lib/CoreUi';
import Text from '~/src/components/Text';
import {
  DestinationInput,
  DetailsForm,
} from '~/src/features/contentLink/components';
import { resolveContentLinkDomain } from '~/src/features/contentLink/utils';
import { useApiMutation } from '~/src/hooks/useApi';
import useFetchSessionUser from '~/src/hooks/useFetchSessionUser';
import useTheme from '~/src/hooks/useTheme';
import { resolveDefaultDomainId } from '~/src/lib/customDomain';
import { useI18n } from '~/src/lib/i18n';
import uploadImage from '~/src/lib/image/uploadImage';
import { useAppRouter } from '~/src/lib/router2';
import { deleteContentLinkApi } from '~/src/lib/songwhipApi/contentLinks/delete';
import { getUserContentLinksApi } from '~/src/lib/songwhipApi/contentLinks/get';
import { updateContentLinkApi } from '~/src/lib/songwhipApi/contentLinks/update';

interface ContentLinkFormValues extends FormValues {
  destinationUrl: string;
  title: string;
  domain: string;
  path: string;
}

export const ContentLinkForm = ({
  contentLink,
}: {
  contentLink: MappedContentLink;
}) => {
  const { artists, customLink } = contentLink;
  const mainArtist = artists[0];

  const { t: tApp } = useI18n('app');
  const { t } = useI18n('contentLinkEdit');

  const formApiRef = useRef<FormApi>(null);
  const { userAccountId } = useFetchSessionUser();
  const appAlert = useAppAlert();
  const appToast = useAppToast();
  const router = useAppRouter();
  const theme = useTheme();

  const [isSaving, setIsSaving] = useState(false);
  const [isDeleting, setIsDeleting] = useState(false);

  const { trigger: updateContentLink } = useApiMutation(updateContentLinkApi, {
    revalidate: [getUserContentLinksApi],
  });

  const { trigger: deleteContentLink } = useApiMutation(deleteContentLinkApi, {
    revalidate: [getUserContentLinksApi],
  });

  const [imageUrl, setImageUrl] = useState<string | null | undefined>(
    contentLink.image
  );

  const handleImageUpload = async (file?: File) => {
    if (!file) return;

    const image = await uploadImage({
      file,
      scaleToWidth: 1200,
      asType: 'jpeg',
      scaleBeforeUpload: false,
      accountId: userAccountId,
    });

    return image.url;
  };

  const handleSubmit: FormOnSubmit<ContentLinkFormValues> = async ({
    form,
    values,
  }) => {
    setIsSaving(true);

    try {
      const domainId = toNumber(values.domain);
      const imageFile = form.image.files[0];
      const image = (await handleImageUpload(imageFile)) ?? imageUrl;

      if (!domainId) throw new Error('Domain is required');

      await updateContentLink(contentLink.id, {
        name: values.title,
        destinationUrl: values.destinationUrl,
        image,
        ...resolveContentLinkDomain(domainId),
        path: `/${values.path}`,
      });

      const persistedQuery = router.getPersistedQuery(
        '/catalog',
        'contentLinks'
      );

      await router.push('/catalog?tab=contentLinks', {
        asQuery: persistedQuery,
        routerQuery: persistedQuery,
      });

      appToast({ text: tApp('actions.saved') });
    } catch (error) {
      appAlert({ content: <ErrorText error={error} /> });
    } finally {
      setIsSaving(false);
    }
  };

  const handleDelete = async () => {
    setIsDeleting(true);

    try {
      await deleteContentLink(contentLink.id);
      await router.replace('/catalog?tab=contentLinks');
    } catch (error) {
      appAlert({ content: <ErrorText error={error} /> });
    } finally {
      setIsDeleting(false);
    }
  };

  return (
    <>
      <DialogBoxHeader
        title={t('header')}
        background="none"
        zIndex={1}
        onBackClick={async () => {
          const persistedQuery = router.getPersistedQuery(
            '/catalog',
            'contentLinks'
          );

          await router.push('/catalog?tab=contentLinks', {
            asQuery: persistedQuery,
            routerQuery: persistedQuery,
          });
        }}
        renderRight={({ textProps }) => (
          <Clickable
            isDisabled={isSaving || isDeleting}
            onClick={async () => {
              await formApiRef.current?.submit();
            }}
          >
            <Text {...textProps}>
              {isSaving ? tApp('actions.saving') : tApp('actions.save')}
            </Text>
          </Clickable>
        )}
      />
      <Box padding="1rem 2rem 2rem" centerContent>
        <Box maxWidth="64rem" width="100%">
          <Form<ContentLinkFormValues>
            apiRef={formApiRef}
            onSubmit={handleSubmit}
            flexColumn
            gap="1.8rem"
          >
            <DestinationInput
              initialValue={contentLink.destinationUrl}
              isDisabled={isSaving}
            />
            <DetailsForm
              initialValues={{
                title: contentLink.name,
                imageUrl: contentLink.image,
                domainId: resolveDefaultDomainId(customLink),
                path: customLink.path,
              }}
              artistId={mainArtist.id}
              artistPath={mainArtist.path}
              isLoading={isSaving}
              onImageReset={async () => {
                setImageUrl(null);
              }}
            />
            <Box>
              <InputLabelValue value={t('delete.header')} />
              <InputLabelDescription
                value={t('delete.description')}
                margin="0 0 1rem 0"
              />
              <ConfirmButton
                text={t('delete.text')}
                isLoading={isDeleting}
                isDisabled={isSaving}
                onClick={handleDelete}
                style={{ color: theme.colorDanger }}
              />
            </Box>
          </Form>
        </Box>
      </Box>
    </>
  );
};
