import { Clip } from '@/state/clipStore';
import { GenerateFormStore } from '@/state/createStore';
import { CreateV2Store } from '@/state/createV2Store';
import { SessionStore } from '@/state/sessionStore';
import { getClipTitle } from '@/utils/clip';

export const ensureRemixInTitle = (title: string): string => {
  if (!title) return '';
  return title.endsWith(' (Remix)') ? title : `${title} (Remix)`;
};

export const removeRemixFromTitle = (title: string): string => {
  if (!title) return '';
  return title.endsWith(' (Remix)') ? title.slice(0, -8) : title;
};

export type RemixHandlerProps = {
  clip: Clip;
  session: SessionStore;
  genForm: GenerateFormStore;
  createV2: CreateV2Store;
  router?: any;
  pathname?: string;
  showRemixCreate?: boolean;
};

export const handleRemixCoverAction = async (props: RemixHandlerProps) => {
  const { clip, genForm, router } = props;

  router.push('/create?remix_clip=' + clip.id + '&remix_type=cover');
  genForm.shouldOpenMobileCreate = true;
  return;
};

export const handleRemixExtendAction = async (props: RemixHandlerProps) => {
  const { clip, genForm, router } = props;

  router.push('/create?remix_clip=' + clip.id + '&remix_type=extend');
  genForm.shouldOpenMobileCreate = true;
  return;
};

export const handleRemixUseStylesLyricsAction = async (
  props: RemixHandlerProps
) => {
  const { clip, genForm, router } = props;

  router.push('/create?remix_clip=' + clip.id + '&remix_type=reuse');
  genForm.shouldOpenMobileCreate = true;
  return;
};

export const handleAdjustSpeedAction = async (props: RemixHandlerProps) => {
  const { clip, genForm, router } = props;

  // Disallow users to adjust speed on uploads
  if (clip?.metadata?.type === 'upload' || !!clip?.metadata?.has_vocal) {
    return;
  }

  router.push('/create?remix_clip=' + clip.id + '&remix_type=speed');
  genForm.shouldOpenMobileCreate = true;
  return;
};

type ApplySpeedProps = {
  clipId: string;
  speedMultiplier: number;
  keepPitch: boolean;
  project: any;
  clips: any;
};

export const handleApplySpeedAction = async ({
  clipId,
  speedMultiplier,
  keepPitch,
  project,
  clips,
}: ApplySpeedProps): Promise<string | null> => {
  const clip = clips.getClipById(clipId);
  if (!clip) return null;

  const formattedMultiplier =
    speedMultiplier % 1 === 0
      ? speedMultiplier.toFixed(0)
      : speedMultiplier.toFixed(2);

  const speedAdjustedTitle = `${getClipTitle(clip)} (${formattedMultiplier}x)`;

  const result = await project.apiClient.POST('/api/clips/adjust-speed/', {
    body: {
      clip_id: clipId,
      speed_multiplier: speedMultiplier,
      keep_pitch: keepPitch,
      title: speedAdjustedTitle,
    } as any,
    params: { query: { data: {} } },
  });

  const resultClipId = result.data?.id;

  if (resultClipId) {
    const newClip = result.data;

    if (newClip) {
      clips.addClip(newClip, true);
      project.addClip(newClip, true);

      if (project.currentProjectId) {
        project.addClipsToProject([newClip], project.currentProjectId);
      }

      clips.runningRequests.add(resultClipId);
      return resultClipId;
    }
  }
  return null;
};

/**
 * Determines if a RemixOf component should be displayed
 * @param currentClip The current clip being viewed
 * @param parentClip The parent clip of the current clip
 * @param session The current user session
 * @returns boolean indicating if RemixOf should be displayed
 */
export const shouldShowRemixOf = (
  currentClip: any,
  parentClip: any,
  session: SessionStore
): boolean => {
  const isOwnParentClip = parentClip?.user_handle === session?.user?.handle;
  const isOwnCurrentClip = currentClip?.user_id === session?.user?.id;
  const isRemix = currentClip?.metadata?.is_remix === true;
  const showRemix = currentClip?.metadata?.show_remix === true;

  if (isOwnParentClip) {
    // If user owns both clips and is session user
    if (isOwnCurrentClip) {
      return isRemix && showRemix;
    }
    // If user owns parent clip and is session user but doesn't own current clip
    return isRemix;
  } else {
    return isRemix;
  }
};

/**
 * Determines if a ClipLineageCard should be displayed
 * @param currentClip The current clip being viewed
 * @param parentClip The parent clip of the current clip
 * @param session The current user session
 * @returns boolean indicating if ClipLineageCard should be displayed
 */
export const shouldShowClipLineageCard = (
  currentClip: any,
  parentClip: any,
  session: any
): boolean => {
  // For users with the remix flag:
  // Check if either the current clip or parent clip is owned by the user
  const isOwnCurrentClip = currentClip?.user_id === session?.user?.id;
  const isOwnParentClip = parentClip?.user_handle === session?.user?.handle;

  // Don't show if parent clip is not owned by the user
  if (!isOwnParentClip) {
    return false;
  }

  // Show clip lineage if it's the user's own song and show_remix is not true
  if (isOwnCurrentClip && currentClip?.metadata?.show_remix !== true) {
    return true;
  }

  // In all other cases, don't show clip lineage
  return false;
};

/**
 * Overall, should show if:
 * For OWN SONG: only on ClipPreview & MoreSongsPanel (disregarding song menu here) regardless of is_public and can_remix
 * For OTHERS' SONGS: only if can_remix is true, regardless of is_public (users can send links of songs to each other)
 */
export const shouldShowRemixButton = ({
  clip,
  session,
  hideOnOwnSong = false,
}: {
  clip: Clip;
  session: SessionStore;
  hideOnOwnSong?: boolean;
}) => {
  // Check if it's the user's own song
  const isOwnSong = clip.user_id === session.user?.id;

  // Don't show on user's own song if showOnSongRow is true
  if (isOwnSong && hideOnOwnSong) return false;

  return true;
};
