'use client';

import { observer } from 'mobx-react-lite';
import { useRouter } from 'next/navigation';
import { useMemo } from 'react';
import { twMerge } from 'tailwind-merge';

import ImpressionLogger, {
  ImpressionLoggerConfig,
} from '@/components/ImpressionLogger';
import ListItem from '@/components/listView/ListItem';
import { CommentIcon, MusicIcon, RemixIcon, ThumbsUpIcon } from '@/icons';
import { components } from '@/lib/gen';
import {
  logActivityFeedItemCommentClicked,
  logActivityFeedItemPrimaryUserClicked,
  logActivityFeedItemSecondaryUserClicked,
  logActivityFeedItemSongClicked,
} from '@/logging/activityFeedLogging';
import { SMALL_IMAGE } from '@/utils/constants';

import Avatar from '../image/Avatar';
import ImageWithFallback from '../image/ImageWithFallback';
import Link from '../link/Link';
import ProfileLink from '../link/ProfileLink';

type FollowingFeedItemSchema = components['schemas']['FollowingFeedItemSchema'];

enum ActivityType {
  PUBLISH = 'publish_song',
  COMMENT = 'comment_song',
  LIKE = 'like_song',
  REMIX = 'remix_song',
}

type ActivityFeedItemProps = {
  primaryUserAvatarUrl: string;
  primaryUserHandle: string;
  primaryUserDisplayName: string;
  secondaryUserAvatarUrl?: string;
  secondaryUserHandle?: string;
  secondaryUserDisplayName?: string;
  clipTitle: string;
  clipImageUrl?: string;
  clipId: string;
  commentContent?: string;
  commentId?: string;
  showFullFeed: boolean;
  index: number;
  feedType: 'full' | 'home';
  activityId: string;
  activityType: 'publish_song' | 'comment_song' | 'like_song' | 'remix_song';
  primaryUserId: string;
  secondaryUserId?: string;
};

// Helper function to extract context data from FollowingFeedItemSchema
function createActivityFeedItemProps(
  data: FollowingFeedItemSchema,
  showFullFeed: boolean,
  index: number
): ActivityFeedItemProps {
  const feedType = showFullFeed ? 'full' : 'home';
  const activityId = data.feed_timestamp; // Using feed_timestamp as unique activity ID

  return {
    primaryUserAvatarUrl: data.followed_user_profile?.avatar_image_url || '',
    primaryUserHandle: data.followed_user_profile?.handle || '',
    primaryUserDisplayName: data.followed_user_profile?.display_name || '',
    primaryUserId: data.followed_user_profile?.external_user_id || '',
    secondaryUserAvatarUrl: data.clip_schema?.avatar_image_url || '',
    secondaryUserHandle: data.clip_schema?.handle || '',
    secondaryUserDisplayName: data.clip_schema?.display_name || '',
    secondaryUserId: data.clip_schema?.user_id || '',
    clipTitle: data.clip_schema?.title || 'Untitled',
    clipImageUrl: data.clip_schema?.image_url || '',
    clipId: data.clip_schema?.id || '',
    commentContent: data.comment_schema?.content || '',
    commentId: data.comment_schema?.id || '',
    showFullFeed,
    index,
    feedType,
    activityId,
    activityType: data.activity_type as
      | 'publish_song'
      | 'comment_song'
      | 'like_song'
      | 'remix_song',
  };
}

export const ActivityFeedCommentItem: React.FC<{
  activityFeedData: ActivityFeedItemProps;
}> = observer(({ activityFeedData }) => {
  const router = useRouter();

  const handleClick = (e: React.MouseEvent) => {
    // ignore if clicking on a nested link or button
    if ((e.target as HTMLElement).closest('a, button')) {
      return;
    }

    if (activityFeedData.commentId && activityFeedData.clipId) {
      logActivityFeedItemCommentClicked({
        activityId: activityFeedData.activityId,
        commentId: activityFeedData.commentId || '',
        index: activityFeedData.index,
        activityType: activityFeedData.activityType,
        clipId: activityFeedData.clipId,
        clipTitle: activityFeedData.clipTitle,
        primaryUserId: activityFeedData.primaryUserId,
        primaryUserHandle: activityFeedData.primaryUserHandle,
        secondaryUserId: activityFeedData.secondaryUserId,
        secondaryUserHandle: activityFeedData.secondaryUserHandle,
        feedType: activityFeedData.feedType,
      });

      router.push(
        `/song/${activityFeedData.clipId}?show_comments=true&comment_id=${activityFeedData.commentId}`
      );
    }
  };

  const handleSongClick = () => {
    logActivityFeedItemSongClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  const handlePrimaryUserClick = () => {
    logActivityFeedItemPrimaryUserClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  const handleSecondaryUserClick = () => {
    logActivityFeedItemSecondaryUserClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  return (
    <ListItem
      className={twMerge(
        'border-primary/15 font-sans text-base font-normal text-foreground-secondary',
        !activityFeedData.showFullFeed && 'rounded-lg border-b-0 px-2',
        activityFeedData.commentId &&
          'cursor-pointer transition-colors duration-100 ease-linear hover:bg-background-secondary-glass'
      )}
      startClassName={activityFeedData.showFullFeed ? undefined : 'basis-16'}
      onClick={handleClick}
      start={
        <div className='relative'>
          <Avatar
            src={activityFeedData.primaryUserAvatarUrl}
            size={activityFeedData.showFullFeed ? 40 : 64}
            handle={activityFeedData.primaryUserHandle}
          />
          <CommentIcon
            className={twMerge(
              'absolute right-0 bottom-0 h-5 w-5 rounded-full border-[1.5px] border-background-secondary bg-primary fill-black p-0.5',
              activityFeedData.showFullFeed ? 'h-5 w-5' : 'h-7 w-7'
            )}
          />
        </div>
      }
      end={
        <Link
          href={`/song/${activityFeedData.clipId}`}
          onClick={handleSongClick}
        >
          <ImageWithFallback
            className='h-14 w-11 rounded-md object-cover'
            alt={activityFeedData.clipTitle || 'Untitled'}
            src={activityFeedData.clipImageUrl || null}
            imageSize={SMALL_IMAGE}
          />
        </Link>
      }
    >
      <p className='line-clamp-2 text-base leading-tight'>
        <ProfileLink
          handle={activityFeedData.primaryUserHandle}
          className='font-medium text-foreground-primary hover:underline'
          onClick={handlePrimaryUserClick}
        >
          {activityFeedData.primaryUserDisplayName}
        </ProfileLink>
        {` commented on '${activityFeedData.clipTitle}' by `}
        <ProfileLink
          handle={activityFeedData.secondaryUserHandle || ''}
          className='font-medium text-foreground-primary hover:underline'
          onClick={handleSecondaryUserClick}
        >
          {activityFeedData.secondaryUserDisplayName}
        </ProfileLink>
        {`: ${activityFeedData.commentContent}`}
      </p>
    </ListItem>
  );
});

export const ActivityFeedRemixItem: React.FC<{
  activityFeedData: ActivityFeedItemProps;
}> = observer(({ activityFeedData }) => {
  const handleSongClick = () => {
    logActivityFeedItemSongClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  const handlePrimaryUserClick = () => {
    logActivityFeedItemPrimaryUserClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  const handleSecondaryUserClick = () => {
    logActivityFeedItemSecondaryUserClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  return (
    <ListItem
      className={twMerge(
        'border-primary/15 font-sans text-base font-normal text-foreground-secondary',
        !activityFeedData.showFullFeed && 'border-b-0 px-2'
      )}
      startClassName={activityFeedData.showFullFeed ? undefined : 'basis-16'}
      start={
        <div className='relative'>
          <Avatar
            src={activityFeedData.primaryUserAvatarUrl}
            size={activityFeedData.showFullFeed ? 40 : 64}
            handle={activityFeedData.primaryUserHandle}
          />
          <RemixIcon
            className={twMerge(
              'absolute right-0 bottom-0 h-5 w-5 rounded-full border-[1.5px] border-background-secondary bg-primary fill-black p-0.5',
              activityFeedData.showFullFeed ? 'h-5 w-5' : 'h-7 w-7'
            )}
          />
        </div>
      }
      end={
        <Link
          href={`/song/${activityFeedData.clipId}`}
          onClick={handleSongClick}
        >
          <ImageWithFallback
            className='h-14 w-11 rounded-md object-cover'
            alt={activityFeedData.clipTitle || 'Untitled'}
            src={activityFeedData.clipImageUrl || null}
            imageSize={SMALL_IMAGE}
          />
        </Link>
      }
    >
      <p className='line-clamp-2 text-base leading-tight'>
        <ProfileLink
          handle={activityFeedData.primaryUserHandle}
          className='font-medium text-foreground-primary hover:underline'
          onClick={handlePrimaryUserClick}
        >
          {activityFeedData.primaryUserDisplayName}
        </ProfileLink>
        {` remixed '${activityFeedData.clipTitle}' by `}
        <ProfileLink
          handle={activityFeedData.secondaryUserHandle || ''}
          className='font-medium text-foreground-primary hover:underline'
          onClick={handleSecondaryUserClick}
        >
          {activityFeedData.secondaryUserDisplayName}
        </ProfileLink>
      </p>
    </ListItem>
  );
});

export const ActivityFeedPublishItem: React.FC<{
  activityFeedData: ActivityFeedItemProps;
}> = observer(({ activityFeedData }) => {
  const handleSongClick = () => {
    logActivityFeedItemSongClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  const handlePrimaryUserClick = () => {
    logActivityFeedItemPrimaryUserClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  return (
    <ListItem
      className={twMerge(
        'border-primary/15 font-sans text-base font-normal text-foreground-secondary',
        !activityFeedData.showFullFeed && 'border-b-0 px-2'
      )}
      startClassName={activityFeedData.showFullFeed ? undefined : 'basis-16'}
      start={
        <div className='relative'>
          <Avatar
            src={activityFeedData.primaryUserAvatarUrl}
            size={activityFeedData.showFullFeed ? 40 : 64}
            handle={activityFeedData.primaryUserHandle}
          />
          <MusicIcon
            className={twMerge(
              'absolute right-0 bottom-0 h-5 w-5 rounded-full border-[1.5px] border-background-secondary bg-primary fill-black p-0.5',
              activityFeedData.showFullFeed ? 'h-5 w-5' : 'h-7 w-7'
            )}
          />
        </div>
      }
      end={
        <Link
          href={`/song/${activityFeedData.clipId}`}
          onClick={handleSongClick}
        >
          <ImageWithFallback
            className='h-14 w-11 rounded-md object-cover'
            alt={activityFeedData.clipTitle || 'Untitled'}
            src={activityFeedData.clipImageUrl || null}
            imageSize={SMALL_IMAGE}
          />
        </Link>
      }
    >
      <p className='line-clamp-2 text-base leading-tight'>
        <ProfileLink
          handle={activityFeedData.primaryUserHandle}
          className='font-medium text-foreground-primary hover:underline'
          onClick={handlePrimaryUserClick}
        >
          {activityFeedData.primaryUserDisplayName}
        </ProfileLink>
        {` released a new song '${activityFeedData.clipTitle}'`}
      </p>
    </ListItem>
  );
});

export const ActivityFeedLikeItem: React.FC<{
  activityFeedData: ActivityFeedItemProps;
}> = observer(({ activityFeedData }) => {
  const handleSongClick = () => {
    logActivityFeedItemSongClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  const handlePrimaryUserClick = () => {
    logActivityFeedItemPrimaryUserClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  const handleSecondaryUserClick = () => {
    logActivityFeedItemSecondaryUserClicked({
      activityId: activityFeedData.activityId,
      index: activityFeedData.index,
      activityType: activityFeedData.activityType,
      clipId: activityFeedData.clipId,
      clipTitle: activityFeedData.clipTitle,
      primaryUserId: activityFeedData.primaryUserId,
      primaryUserHandle: activityFeedData.primaryUserHandle,
      secondaryUserId: activityFeedData.secondaryUserId,
      secondaryUserHandle: activityFeedData.secondaryUserHandle,
      feedType: activityFeedData.feedType,
    });
  };

  return (
    <ListItem
      className={twMerge(
        'border-primary/15 font-sans text-base font-normal text-foreground-secondary',
        !activityFeedData.showFullFeed && 'border-b-0 px-2'
      )}
      startClassName={activityFeedData.showFullFeed ? undefined : 'basis-16'}
      start={
        <div className='relative'>
          <Avatar
            src={activityFeedData.primaryUserAvatarUrl}
            size={activityFeedData.showFullFeed ? 40 : 64}
            handle={activityFeedData.primaryUserHandle}
          />
          <ThumbsUpIcon
            className={twMerge(
              'absolute right-0 bottom-0 h-5 w-5 rounded-full border-[1.5px] border-background-secondary bg-primary fill-black p-0.5',
              activityFeedData.showFullFeed ? 'h-5 w-5' : 'h-7 w-7'
            )}
          />
        </div>
      }
      end={
        <Link
          href={`/song/${activityFeedData.clipId}`}
          onClick={handleSongClick}
        >
          <ImageWithFallback
            className='h-14 w-11 rounded-md object-cover'
            alt={activityFeedData.clipTitle || 'Untitled'}
            src={activityFeedData.clipImageUrl || null}
            imageSize={SMALL_IMAGE}
          />
        </Link>
      }
    >
      <p className='line-clamp-2 text-base leading-tight'>
        <ProfileLink
          handle={activityFeedData.primaryUserHandle}
          className='font-medium text-foreground-primary hover:underline'
          onClick={handlePrimaryUserClick}
        >
          {activityFeedData.primaryUserDisplayName}
        </ProfileLink>
        {` liked '${activityFeedData.clipTitle}' by `}
        <ProfileLink
          handle={activityFeedData.secondaryUserHandle || ''}
          className='font-medium text-foreground-primary hover:underline'
          onClick={handleSecondaryUserClick}
        >
          {activityFeedData.secondaryUserDisplayName}
        </ProfileLink>
      </p>
    </ListItem>
  );
});

export const ActivityFeedItem: React.FC<{
  data: FollowingFeedItemSchema;
  showFullFeed?: boolean;
  index?: number;
}> = observer(({ data, showFullFeed = false, index = 0 }) => {
  // Early return if required data is missing
  if (
    !data.clip_schema ||
    !data.followed_user_profile ||
    !data.clip_schema.id
  ) {
    return null;
  }

  const activityFeedData = createActivityFeedItemProps(
    data,
    showFullFeed,
    index
  );

  // Impression logging configuration
  const impressionLoggerConfig = useMemo<ImpressionLoggerConfig[]>(() => {
    return [
      {
        event: {
          actionName: 'ActivityFeedItemSeen',
          principalObjectType: 'activity',
          principalObjectValue: activityFeedData.activityId,
          context: {
            index: activityFeedData.index,
            activityType: activityFeedData.activityType,
            clipId: activityFeedData.clipId,
            clipTitle: activityFeedData.clipTitle,
            primaryUserId: activityFeedData.primaryUserId,
            primaryUserHandle: activityFeedData.primaryUserHandle,
            secondaryUserId: activityFeedData.secondaryUserId,
            secondaryUserHandle: activityFeedData.secondaryUserHandle,
            feedType: activityFeedData.feedType,
          },
        },
        threshold: 0.9,
      },
    ];
  }, [activityFeedData]);

  const ActivityComponent = () => {
    if (data.activity_type === ActivityType.COMMENT) {
      return <ActivityFeedCommentItem activityFeedData={activityFeedData} />;
    } else if (data.activity_type === ActivityType.REMIX) {
      return <ActivityFeedRemixItem activityFeedData={activityFeedData} />;
    } else if (data.activity_type === ActivityType.PUBLISH) {
      return <ActivityFeedPublishItem activityFeedData={activityFeedData} />;
    } else if (data.activity_type === ActivityType.LIKE) {
      return <ActivityFeedLikeItem activityFeedData={activityFeedData} />;
    }
    return null;
  };

  return (
    <ImpressionLogger configs={impressionLoggerConfig}>
      <ActivityComponent />
    </ImpressionLogger>
  );
});
