import { useState } from 'react';
import { z } from 'zod/mini';

import type { MappedContentLink } from '~/lib/songwhipApi/mapper';

import Clickable from '~/src/components/Clickable';
import { DialogBoxHeader } from '~/src/components/DialogBox/DialogBoxHeader';
import CrossIcon from '~/src/components/Icon/CrossIcon';
import Page from '~/src/components/Page';
import PageMetadata from '~/src/components/PageMetadata';
import { resolveContentLinkDomain } from '~/src/features/contentLink/utils';
import { useApiMutation } from '~/src/hooks/useApi';
import useIsEnabled from '~/src/hooks/useIsEnabled';
import { useI18n } from '~/src/lib/i18n';
import { useAppRouter } from '~/src/lib/router2';
import { createContentLinkApi } from '~/src/lib/songwhipApi/contentLinks/create';
import { getUserContentLinksApi } from '~/src/lib/songwhipApi/contentLinks/get';
import { Features } from '~/src/store/session/types';
import { NextButton } from '../components';
import { CreateFlow } from '../components/CreateFlow';
import {
  assertNumber,
  assertString,
  optionalString,
} from '../components/CreateFlow/utils';
import { DestinationLinkStage, DetailsStage } from './components';
import { ChooseArtistStage } from './components/ChooseArtistStage';
import { SuccessStage } from './components/SuccessStage';

const createContentLinkPageQuerySchema = z.object({
  stage: z.catch(
    z.optional(
      z.enum(['artist', 'destination', 'details', 'success'] as const)
    ),
    undefined
  ),
});

export const CreateContentLinkPage = () => {
  const { t } = useI18n('create');

  const isEnabled = useIsEnabled(Features.CONTENT_LINKS);

  const [contentLink, setContentLink] = useState<MappedContentLink>();
  const router = useAppRouter();
  const query = router.getQuery(createContentLinkPageQuerySchema);

  const { trigger: createContentLink } = useApiMutation(createContentLinkApi, {
    revalidate: [getUserContentLinksApi],
  });

  if (!isEnabled) {
    router.replace('/create');
    return;
  }

  if (query.stage === 'success' && !contentLink) {
    // if user tries to access success stage without content link data, redirect them to catalog
    router.replace('/catalog');
    return;
  }

  const handleSubmit = async (data: Record<string, unknown>) => {
    const artistId = assertNumber(data, 'artistId');
    const name = assertString(data, 'title');
    const destinationUrl = assertString(data, 'destinationUrl');
    const domainId = assertNumber(data, 'domain');
    const path = assertString(data, 'path');
    const image = optionalString(data, 'imageUrl');

    const page = await createContentLink({
      artistId,
      destinationUrl,
      image,
      name,
      ...resolveContentLinkDomain(domainId),
      path: `/${path}`,
    });

    // set created content link data in state to be used in success stage
    setContentLink(page);

    // navigate to success stage with new content link data
    await router.setQuery({ stage: 'success' }, { reset: true });
  };

  return (
    <Page withGradient>
      <PageMetadata noIndex title={t('contentLink.title')} />
      <CreateFlow
        onSubmit={handleSubmit}
        stages={[
          {
            id: 'artist',
            title: t('pickArtist'),
            Component: ChooseArtistStage,
            hideNextButton: true,
          },
          {
            id: 'destination',
            title: t('contentLink.destinationHeader'),
            Component: DestinationLinkStage,
          },
          {
            id: 'details',
            title: t('contentLink.detailsHeader'),
            HeaderComponent: ({ events, definition }) => (
              <DialogBoxHeader
                title={definition.title}
                background="none"
                zIndex={1}
                onBackClick={async () => {
                  await router.setQuery({
                    ...query,
                    title: undefined,
                    imageUrl: undefined,
                    stage: 'destination',
                  });
                }}
                renderRight={() => (
                  <NextButton
                    testId="nextButton"
                    onClick={() => events.emit('nextButtonPressed')}
                  />
                )}
              />
            ),
            Component: DetailsStage,
          },
          {
            id: 'success',
            title: t('contentLink.successHeader'),
            HeaderComponent: ({ definition }) => (
              <DialogBoxHeader
                title={definition.title}
                background="none"
                renderRight={() => (
                  <Clickable
                    isInline
                    onClick={() => {
                      router.push('/catalog?tab=contentLinks');
                    }}
                  >
                    <CrossIcon color="#999" size="2.6rem" />
                  </Clickable>
                )}
              />
            ),
            Component: SuccessStage,
            props: contentLink,
          },
        ]}
      />
    </Page>
  );
};
