'use client';

/* eslint jsx-a11y/click-events-have-key-events: warn */

/* eslint jsx-a11y/no-static-element-interactions: warn */
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import clsx from 'clsx';
import { useRouter } from 'next/navigation';
import React, { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { twMerge } from 'tailwind-merge';

import AvatarTag from '@/components//tag/AvatarTag';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import Link from '@/components/link/Link';
import { FailedModerationModal } from '@/components/modal/FailedModerationModal';
import SimpleVideoPlayer from '@/components/video/SimpleVideoPlayer';
import {
  CommentIcon,
  DownloadIcon,
  EditIcon,
  EyeIcon,
  GlobeSlashIcon,
  InfoOutlineIcon,
  MoreVerticalIcon,
  ThumbsUpIcon,
  TrashIcon,
} from '@/icons';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { generateLinkUrl } from '@/utils/embeds';
import { getCountString } from '@/utils/utils';

import DiscoverCard, {
  DiscoverCardBackground,
  type DiscoverCardProps,
} from './DiscoverCard';
import DiscoverCardActions from './DiscoverCardActions';
import DiscoverCardMeta from './DiscoverCardMeta';

export type DiscoverHookCardProps = DiscoverCardProps & {
  index: number;
  hookId?: string;
  hookImage?: string;
  hookVideo?: string;
  hookTitle?: string | null;
  hookCaption?: string | null;
  hookArtistAvatar?: string;
  hookArtistDisplayName?: string;
  hookArtistHandle?: string;
  hookArtistHref?: string;
  hookCreatedAt?: string;
  hookStatus?: string;
  clipId?: string;
  clipImage?: string;
  clipVideo?: string;
  clipTitle?: string | null;
  clipCaption?: string | null;
  clipArtistAvatar?: string;
  clipArtistDisplayName?: string;
  clipArtistHandle?: string;
  clipArtistHref?: string;
  duration?: number;
  viewCount?: number;
  likeCount?: number;
  commentCount?: number;
  linkArtistFeed?: boolean;
  isLiked?: boolean;
  isOwnHook?: boolean;
  isClipPublic?: boolean;
  showArtistAttribution?: boolean;
  showViewCount?: boolean;
  contentRatingTags?: string[];
  recommendationItemId?: string | null;
  onLikeClick?: (
    payload: { index?: number; id: string; isLiked?: boolean },
    e?: Event | React.MouseEvent
  ) => void;
  onViewCountClick?: (
    payload: {
      index?: number;
      id: string;
    },
    e?: Event | React.MouseEvent
  ) => void;
  onCommentClick?: (
    payload: {
      index?: number;
      id: string;
    },
    e?: Event | React.MouseEvent
  ) => void;
  onDownloadClick?: (
    payload: {
      index?: number;
      id: string;
    },
    e?: Event | React.MouseEvent
  ) => void;
  onEditClick?: (
    payload: {
      index?: number;
      id: string;
    },
    e?: Event | React.MouseEvent
  ) => void;
  onDeleteClick?: (
    payload: {
      index?: number;
      id: string;
    },
    e?: Event | React.MouseEvent
  ) => void;
};

export type Props = Omit<
  React.HTMLAttributes<HTMLDivElement>,
  keyof DiscoverHookCardProps
> &
  DiscoverHookCardProps;

function formatHookCreatedAt(hookCreatedAt?: string): string | null {
  if (!hookCreatedAt) return null;
  const now = new Date();
  const created = new Date(hookCreatedAt);
  const diffMs = now.getTime() - created.getTime();
  const diffSec = Math.floor(diffMs / 1000);
  const diffMin = Math.floor(diffSec / 60);
  const diffHour = Math.floor(diffMin / 60);
  const diffDay = Math.floor(diffHour / 24);

  if (diffMin < 1) {
    return 'Just Now';
  } else if (diffMin < 60) {
    return `${diffMin}m ago`;
  } else if (diffHour < 24) {
    return `${diffHour}h ago`;
  } else if (diffDay < 30) {
    return `${diffDay} day${diffDay === 1 ? '' : 's'} ago`;
  } else {
    const options: Intl.DateTimeFormatOptions = {
      month: 'long',
      day: 'numeric',
    };
    if (now.getFullYear() !== created.getFullYear()) {
      options.year = 'numeric';
    }
    return created.toLocaleDateString(undefined, options);
  }
}

const DiscoverHookCard: React.FC<Props> = (props) => {
  const {
    children,
    className: explicitClassName,
    backgroundImageClassName,
    backgroundOverlayClassName,
    clipId,
    clipImage,
    clipVideo,
    clipTitle,
    clipCaption,
    clipArtistAvatar,
    clipArtistDisplayName,
    clipArtistHandle,
    clipArtistHref,
    hookId,
    hookImage,
    hookVideo,
    hookTitle,
    hookCaption,
    hookArtistAvatar,
    hookArtistDisplayName,
    hookArtistHandle,
    hookArtistHref,
    hookCreatedAt,
    hookStatus,
    duration,
    viewCount,
    likeCount,
    commentCount,
    linkArtistFeed,
    isLiked,
    isOwnHook,
    isClipPublic = true,
    showArtistAttribution = !isOwnHook,
    showViewCount = (viewCount ?? 0) >= 10,
    contentRatingTags = [],
    index,
    recommendationItemId,
    onLikeClick,
    onViewCountClick,
    onCommentClick,
    onDownloadClick,
    onEditClick,
    onDeleteClick,
    ...restProps
  } = props;

  const { t } = useTranslation();
  const router = useRouter();

  const [isFailedModerationModalOpen, setIsFailedModerationModalOpen] =
    useState(false);

  const isFailedModeration = hookStatus === 'rendered_failed_moderation';
  const firstContentRatingTag = contentRatingTags?.[0];

  const hookUrl =
    hookId &&
    (linkArtistFeed
      ? generateLinkUrl(hookId, 'hook', undefined, { handle: hookArtistHandle })
      : generateLinkUrl(hookId, 'hook'));

  const className = twMerge('group w-[160px] aspect-9/16', explicitClassName);

  const hasMoreActions = !!(onDeleteClick || onDownloadClick || onEditClick);

  const handleDownloadClick = useCallback(
    (e: Event) => {
      onDownloadClick?.({ index, id: hookId || '' }, e);
    },
    [onDownloadClick, index, hookId]
  );

  const handleEditClick = useCallback(
    (e: Event) => {
      onEditClick?.({ index, id: hookId || '' }, e);
    },
    [onEditClick, index, hookId]
  );

  const handleDeleteClick = useCallback(
    (e: Event) => {
      onDeleteClick?.({ index, id: hookId || '' }, e);
    },
    [onDeleteClick, index, hookId]
  );

  const actions = useMemo(
    () => (
      // Negative x-margin to compensate for button padding
      <div className='-mx-1 -mt-1 flex flex-row items-center justify-between gap-2'>
        <DiscoverCardActions
          className={clsx('pointer-events-auto max-w-max gap-2', {
            hidden: !isOwnHook,
          })}
        >
          {showViewCount && (viewCount || onViewCountClick) ? (
            <Button
              variant={ButtonVariant.Inherit}
              shape={ButtonShape.Rounded}
              size={ButtonSize.Micro}
              icon={EyeIcon}
              iconClassName='w-4 h-4'
              href={undefined}
              onClick={
                onViewCountClick &&
                ((e) =>
                  onViewCountClick(
                    {
                      id: hookId || '',
                    },
                    e
                  ))
              }
              aria-label={
                viewCount == null
                  ? undefined
                  : t('card.numViews', {
                      count: viewCount,
                      formattedCount: getCountString(viewCount),
                    })
              }
            >
              {viewCount == null ? null : getCountString(viewCount)}
            </Button>
          ) : null}
          <Button
            variant={ButtonVariant.Inherit}
            shape={ButtonShape.Rounded}
            size={ButtonSize.Micro}
            active={isLiked}
            icon={ThumbsUpIcon}
            iconClassName='w-4 h-4'
            href={undefined}
            onClick={
              onLikeClick &&
              ((e) =>
                onLikeClick(
                  {
                    id: hookId || '',
                    isLiked: !isLiked,
                  },
                  e
                ))
            }
            aria-label={
              likeCount == null
                ? undefined
                : t('card.numLikes', {
                    count: likeCount,
                    formattedCount: getCountString(likeCount),
                  })
            }
          >
            {likeCount == null ? null : getCountString(likeCount)}
          </Button>
          {commentCount || onCommentClick ? (
            <Button
              variant={ButtonVariant.Inherit}
              shape={ButtonShape.Rounded}
              size={ButtonSize.Micro}
              icon={CommentIcon}
              iconClassName='w-4 h-4'
              href={undefined}
              onClick={
                onCommentClick &&
                ((e) =>
                  onCommentClick(
                    {
                      id: hookId || '',
                    },
                    e
                  ))
              }
              aria-label={
                commentCount == null
                  ? undefined
                  : t('card.numComments', {
                      count: commentCount,
                      formattedCount: getCountString(commentCount),
                    })
              }
            >
              {commentCount == null ? null : getCountString(commentCount)}
            </Button>
          ) : null}
        </DiscoverCardActions>
        {hasMoreActions && (
          <DiscoverCardActions className='pointer-events-auto ml-auto max-w-max gap-2'>
            <DropdownMenu.Root>
              <DropdownMenu.Trigger asChild>
                <Button
                  className='-my-1 -mr-1 cursor-pointer'
                  enableHoverState
                  variant={ButtonVariant.Inherit}
                  shape={ButtonShape.Pill}
                  size={ButtonSize.Micro}
                  icon={MoreVerticalIcon}
                  iconClassName='w-4 h-4'
                  href={undefined}
                  aria-label={t('actions.moreActions')}
                />
              </DropdownMenu.Trigger>
              <DropdownMenu.Portal>
                <DropdownMenu.Content
                  align='start'
                  className={clsx(
                    'flex flex-col items-start justify-start gap-1 rounded-md border',
                    'z-10 min-w-[160px] overflow-clip py-1',
                    'md:box-shadow border-border-primary bg-background-secondary text-foreground-secondary',
                    'font-sans text-sm font-medium'
                  )}
                >
                  {onDownloadClick && isOwnHook && hookId && (
                    <DropdownMenu.Item onSelect={handleDownloadClick} asChild>
                      <Button
                        className='w-full'
                        contentClassName='justify-start'
                        icon={DownloadIcon}
                        variant={ButtonVariant.Tertiary}
                        shape={ButtonShape.Rectangle}
                        size={ButtonSize.Mini}
                      >
                        {t('songActions.download')}
                      </Button>
                    </DropdownMenu.Item>
                  )}
                  {onEditClick && isOwnHook && hookId && (
                    <DropdownMenu.Item onSelect={handleEditClick} asChild>
                      <Button
                        className='w-full'
                        contentClassName='justify-start'
                        icon={EditIcon}
                        variant={ButtonVariant.Tertiary}
                        shape={ButtonShape.Rectangle}
                        size={ButtonSize.Mini}
                      >
                        {t('songActions.edit')}
                      </Button>
                    </DropdownMenu.Item>
                  )}
                  {onDeleteClick && (
                    <DropdownMenu.Item onSelect={handleDeleteClick} asChild>
                      <Button
                        className='w-full'
                        contentClassName='justify-start'
                        icon={TrashIcon}
                        variant={ButtonVariant.Tertiary}
                        shape={ButtonShape.Rectangle}
                        size={ButtonSize.Mini}
                      >
                        {t('actions.delete')}
                      </Button>
                    </DropdownMenu.Item>
                  )}
                </DropdownMenu.Content>
              </DropdownMenu.Portal>
            </DropdownMenu.Root>
          </DiscoverCardActions>
        )}
      </div>
    ),
    [
      isLiked,
      commentCount,
      likeCount,
      viewCount,
      onCommentClick,
      onLikeClick,
      onViewCountClick,
      onDownloadClick,
      onEditClick,
      onDeleteClick,
      handleDownloadClick,
      handleEditClick,
      handleDeleteClick,
      hasMoreActions,
      isOwnHook,
      showViewCount,
      hookId,
      t,
    ]
  );

  const hookTitleWithLink = useMemo(
    () =>
      hookUrl
        ? ({ className: innerClassName }: { className?: string }) => (
            <Link href={hookUrl}>
              <h2 className={twMerge(innerClassName, 'hover:underline')}>
                {hookTitle || clipTitle}
              </h2>
            </Link>
          )
        : hookTitle,
    [hookUrl, hookTitle, clipTitle]
  );

  const contentRatingTagContent = useMemo(() => {
    // if (contentRatingTags.length === 0) {
    //   return null;
    // }
    // return (
    //   <div className='flex flex-row'>
    //     <div className='py-1 text-xs text-foreground-primary'>
    //       {contentRatingTags[0] === ''
    //         ? 'Moderation Failed'
    //         : 'Moderation Failed: ' + contentRatingTags[0]}
    //     </div>
    //   </div>
    // );
    return null;
  }, [contentRatingTags]);

  const backgroundContent = useMemo(() => {
    const handleCardClick = hookUrl
      ? () => {
          logWebUserEvent({
            actionName: 'DiscoverHookCardClicked',
            principalObjectType: 'hook',
            principalObjectValue: hookId || '',
            context: {
              title: hookTitle || clipTitle || '',
              caption: hookCaption || '',
              artistDisplayName: hookArtistDisplayName || '',
              artistHandle: hookArtistHandle || '',
              likeCount: likeCount,
              commentCount: commentCount,
              viewCount: viewCount,
              index,
              recommendationItemId: recommendationItemId ?? '',
            },
          });
          router.push(hookUrl);
        }
      : undefined;
    const backgroundImage = hookImage;
    return function DiscoverHookCardBackground({
      className: backgroundClassName,
    }: {
      className?: string;
    }) {
      const [isHovered, setIsHovered] = useState(false);
      // Do not preload until we hover
      const [preload, setPreload] = useState('none');
      const handleMouseEnter: React.MouseEventHandler<HTMLDivElement> =
        useCallback(() => {
          setIsHovered(true);
          setPreload('auto');
        }, []);
      const handleMouseLeave: React.MouseEventHandler<HTMLDivElement> =
        useCallback(() => {
          setIsHovered(false);
        }, []);
      const notPublicOverlay = isClipPublic ? null : (
        <div className='absolute inset-0 flex items-center justify-center bg-background-dark-overlay text-foreground-primary-on-dark'>
          <GlobeSlashIcon className='size-6' />
        </div>
      );
      if (hookVideo) {
        return (
          <div
            className={twMerge(
              'relative',
              'cursor-pointer text-black',
              'after:absolute after:inset-0',
              'after:[background:linear-gradient(to_bottom,var(--color-opacity-black-40),var(--color-opacity-black-20)_25%,var(--color-opacity-black-20)_66%,var(--color-opacity-black-60))]',
              backgroundClassName
            )}
            onClick={handleCardClick}
            onMouseEnter={handleMouseEnter}
            onMouseLeave={handleMouseLeave}
          >
            <SimpleVideoPlayer
              url={hookVideo}
              poster={hookImage}
              className='absolute inset-0 h-full w-full object-cover'
              playing={isHovered}
              loop
              preload={preload}
            />
            {notPublicOverlay}
          </div>
        );
      }
      return (
        <DiscoverCardBackground
          className={twMerge(
            'cursor-pointer text-black',
            '[--image-background-scale:1] group-focus-within:[--image-background-scale:1.1] group-hover:[--image-background-scale:1.1]',
            backgroundClassName
          )}
          imageClassName={clsx(
            'bg-size-[auto_calc(100%*var(--image-background-scale,1))]',
            'transition-[background-size] duration-300',
            'after:absolute after:inset-0',
            'after:[background:linear-gradient(to_bottom,var(--color-opacity-black-40),var(--color-opacity-black-20)_25%,var(--color-opacity-black-20)_66%,var(--color-opacity-black-60))]'
          )}
          backgroundImage={backgroundImage}
          overlayColor={null}
          onClick={handleCardClick}
        >
          {notPublicOverlay}
        </DiscoverCardBackground>
      );
    };
  }, [hookImage, hookVideo, hookUrl, isClipPublic, router]);

  return (
    <>
      <DiscoverCard
        className={className}
        contentClassName='flex flex-col justify-between items-stretch gap-2 pointer-events-none'
        backgroundContent={backgroundContent}
        {...restProps}
      >
        {actions}
        <div className='flex-1' />
        <DiscoverCardMeta
          className={clsx(
            'max-w-max min-w-0 flex-1 place-content-end *:pointer-events-auto',
            {
              '-mb-2': children,
            }
          )}
          contentRatingTags={contentRatingTagContent}
          title={hookTitleWithLink}
          titleClassName={clsx(
            'max-h-[2.4em] line-clamp-2',
            'transition-[max-height] duration-0 group-hover:duration-300',
            'group-hover:max-h-[4.8em] group-hover:line-clamp-4',
            'font-sans font-medium text-[14px] leading-[16px]'
          )}
          subtitle={
            !isClipPublic ? (
              'Private'
            ) : isOwnHook && isFailedModeration ? (
              <div
                onClick={(e) => {
                  e.stopPropagation();
                  setIsFailedModerationModalOpen(true);
                }}
                className='flex w-fit cursor-pointer items-center gap-[4px] rounded-[60px] bg-black/50 px-[12px] py-[6px] text-[10px] leading-4 font-medium tracking-[0.2px] text-accent-error-on-primary not-italic'
              >
                <InfoOutlineIcon className='h-4 w-4' /> Failed to Post
              </div>
            ) : isOwnHook ? (
              formatHookCreatedAt(hookCreatedAt)
            ) : undefined
          }
          subtitleClassName='text-foreground-tertiary-glass'
          content={
            !showArtistAttribution ||
            !(hookArtistDisplayName || hookArtistHandle) ? null : (
              <AvatarTag
                className='max-w-max font-sans text-[14px] leading-[16px] font-normal text-foreground-secondary-glass'
                avatarClassName='w-4 h-4'
                imageUrl={hookArtistAvatar}
                displayName={hookArtistDisplayName}
                handle={hookArtistHandle}
                href={hookArtistHref}
                onClick={() => {
                  logWebUserEvent({
                    actionName: 'DiscoverHookCardArtistClicked',
                    principalObjectType: 'hook',
                    principalObjectValue: hookId || '',
                    context: {
                      title: hookTitle || clipTitle || '',
                      // caption: hookCaption || '',
                      artistDisplayName: hookArtistDisplayName || '',
                      artistHandle: hookArtistHandle || '',
                      likeCount: likeCount,
                      commentCount: commentCount,
                      viewCount,
                      index,
                      recommendationItemId: recommendationItemId ?? '',
                    },
                  });
                }}
              />
            )
          }
        />
        {children && (
          <div className='flex min-h-0 flex-row items-end justify-between gap-3'>
            <div className='min-w-0 flex-1'>{children}</div>
          </div>
        )}
      </DiscoverCard>

      {isOwnHook && isFailedModeration && (
        <FailedModerationModal
          isOpen={isFailedModerationModalOpen}
          onClose={() => setIsFailedModerationModalOpen(false)}
          contentRatingTag={firstContentRatingTag}
        />
      )}
    </>
  );
};

export default DiscoverHookCard;
