'use client';

import { useGateValue } from '@statsig/react-bindings';
import { observer } from 'mobx-react-lite';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useInView } from 'react-intersection-observer';

import { useStores } from '@/app/(root)/AppProviders';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import DiscoverHookCard, {
  Props as DiscoverHookCardProps,
} from '@/components/card/DiscoverHookCard';
import { HooksFeedType } from '@/components/hooksPlayer/constants';
import {
  VideoHookEntity,
  useVideoHookActions,
  useVideoHooksContextualFeed,
} from '@/components/hooksPlayer/useVideoHooks';
import { useDialogModal } from '@/components/modal/DialogModal';
import { ModalTypes } from '@/components/modal/constants/ModalTypes';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import { useModalContext } from '@/context/ModalContext';
import { PlusIcon } from '@/icons';
import { logHookWebGeneralEvent } from '@/logging/logWebUserEvent';

export const LibraryHookCard: React.FC<
  DiscoverHookCardProps & { hook: VideoHookEntity }
> = observer((props) => {
  const { hook, index, ...restProps } = props;

  const enableHookDownloads = useGateValue('web-hooks-download');

  const { session } = useStores();
  const { openModalWithData } = useModalContext();

  const { t } = useTranslation();
  const { launchDialog } = useDialogModal();

  const hookActions = useVideoHookActions({
    feedId: HooksFeedType.Profile,
    userHandle: session.user?.handle,
    enabled: !!session.user?.handle,
  });

  const { mutateAsync: hookDeleteMutateAsync } = hookActions.deleteMutation;
  const handleDeleteClick = useCallback(
    async (payload: { id: string }) => {
      const action = await launchDialog<boolean>(t('hooks.confirmDelete'), [
        { label: t('cta.confirm'), action: true },
        { label: t('cta.cancel'), action: false },
      ]);
      if (action === true) {
        return await hookDeleteMutateAsync({
          hookId: payload.id,
        });
      }
    },
    [t, launchDialog, hookDeleteMutateAsync]
  );

  const { mutateAsync: hookDownloadMutateAsync } = hookActions.downloadMutation;
  const handleDownloadClick = useCallback(
    async (payload: { id: string }) =>
      hookDownloadMutateAsync({
        hookId: payload.id,
      }),
    [hookDownloadMutateAsync]
  );

  return (
    <DiscoverHookCard
      className='w-full'
      index={index}
      hookId={hook.id}
      hookImage={hook.thumbnailImageUrl ?? undefined}
      hookTitle={hook.title}
      hookCaption={hook.caption}
      hookArtistAvatar={hook.user?.avatarImageUrl ?? undefined}
      hookArtistDisplayName={hook.user?.displayName ?? undefined}
      hookArtistHandle={hook.user?.handle ?? undefined}
      hookCreatedAt={hook?.createdAt}
      hookStatus={hook.status}
      clipId={hook.originalClipId}
      clipImage={hook.clip?.imageUrl ?? undefined}
      clipVideo={hook.clip?.videoCoverUrl ?? undefined}
      clipTitle={hook.clip?.title ?? undefined}
      clipCaption={hook.clip?.caption}
      clipArtistAvatar={hook.clip?.avatarImageUrl ?? undefined}
      clipArtistDisplayName={hook.clip?.displayName ?? undefined}
      clipArtistHandle={hook.clip?.handle ?? undefined}
      viewCount={hook.viewCount}
      likeCount={hook.likeCount}
      showViewCount={
        hook.viewCount >= 10 &&
        (session.isStaff || hook.user?.externalUserId === session.userId)
      }
      isOwnHook={hook.user?.externalUserId === session.userId}
      onDeleteClick={
        hook.user?.externalUserId === session.userId
          ? handleDeleteClick
          : undefined
      }
      onDownloadClick={
        enableHookDownloads && hook.user?.externalUserId === session.userId
          ? handleDownloadClick
          : undefined
      }
      onEditClick={
        hook.user?.externalUserId === session.userId
          ? ({ id }) => {
              openModalWithData(ModalTypes.EDIT_HOOK_METADATA, {
                hookId: id,
              });
            }
          : undefined
      }
      isClipPublic={hook.clip?.isPublic ?? true}
      contentRatingTags={hook.contentRatingTags ?? []}
      linkArtistFeed
      {...restProps}
    />
  );
});

const LibraryHooks: React.FC = observer(() => {
  const { session } = useStores();

  const { hooks, query: hooksQuery } = useVideoHooksContextualFeed({
    feedId: HooksFeedType.Profile,
    userHandle: session.user?.handle,
    enabled: !!session.user?.handle,
  });

  const [paginationRef] = useInView({
    onChange: async (inView) => {
      if (inView && !hooksQuery.isFetchingNextPage) {
        hooksQuery.fetchNextPage();
      }
    },
  });

  if (!hooksQuery.isFetched) {
    return (
      <div className='flex h-full items-center justify-center'>
        <SpinnerSVG />
      </div>
    );
  }

  if (!hooks.length) {
    return (
      <div className='flex flex-col items-stretch justify-center gap-4 p-6'>
        <p className='text-center text-foreground-tertiary'>
          You have not created any hooks yet. Try it out!
        </p>
        <Button
          className='mx-auto'
          icon={PlusIcon}
          size={ButtonSize.Small}
          variant={ButtonVariant.Primary}
          shape={ButtonShape.Pill}
          href='/hooks/create'
          onClick={() => {
            logHookWebGeneralEvent({
              actionName: 'CreateHookClicked',
              context: {
                hookId: '',
                recommendationItemId: '',
                entryPoint: 'library',
              },
            });
          }}
        >
          Create hook
        </Button>
      </div>
    );
  }

  return (
    <div className='px-6 py-2'>
      <ul className='grid grid-cols-[repeat(auto-fill,minmax(10rem,1fr))] gap-4 max-xs:grid-cols-1'>
        {hooks.map((hook, i) => (
          <li key={hook.id} className='max-w-60 max-xs:max-w-full'>
            <LibraryHookCard index={i} hook={hook} />
          </li>
        ))}
      </ul>
      {!hooksQuery.hasNextPage || hooksQuery.isFetchingNextPage ? null : (
        <div ref={paginationRef} />
      )}
    </div>
  );
});

export default LibraryHooks;
