import TimeAgo from 'javascript-time-ago';
import en from 'javascript-time-ago/locale/en';

import { PersonaMetadata } from '@/state/personaStore';
import { isUnpublishableUploadClip } from '@/utils/clip';

import { Clip } from '../../state/clipStore';

TimeAgo.addDefaultLocale(en);

export const TIME_AGO = new TimeAgo('en-US');

export const NEGATIVE_TAG_CHAR = '‑';
export const TAG_DELIMITER_REGEX = /[,，،；、᠂،ฯ་،،.。।]/;

/**
 * Splits and trims a music style tag string
 */
export function tagsToArray(...allTags: string[]) {
  return allTags
    .flatMap((tags) => tags.split(TAG_DELIMITER_REGEX).map((tag) => tag.trim()))
    .filter(Boolean);
}

/**
 * Clean and prepend music style tags with the negative tag character
 */
export function tagsToNegativeTags(tags: string[]) {
  return tags.map((tag) => `${NEGATIVE_TAG_CHAR}${cleanTag(tag)}`);
}

/**
 * Trims the music style tag and removes the negative tag prefix, if present
 */
export function cleanTag(srcTag: string) {
  const tag = srcTag ? srcTag.trim() : '';
  return tag.startsWith(NEGATIVE_TAG_CHAR) ? tag.slice(1) : tag;
}

export function formatDuration(
  durationSeconds: number | null | undefined,
  shortenDefault = false,
  showMs = false
) {
  if (durationSeconds == null) {
    return shortenDefault ? '-:--' : '--:--';
  }
  const hours = Math.floor(durationSeconds / 3600);
  const minutes = Math.floor(durationSeconds / 60) % 60;
  const seconds = Math.floor(durationSeconds) % 60;
  const ms = Math.floor((durationSeconds * 1000) % 1000);

  const segments: string[] = [];
  // Hours and minutes: Only pad minutes if we're also showing hours
  if (hours > 0) {
    segments.push(hours.toString(10), minutes.toString(10).padStart(2, '0'));
  } else {
    segments.push(minutes.toString(10));
  }
  // Seconds and milliseconds
  if (showMs) {
    segments.push(
      `${seconds.toString(10).padStart(2, '0')}.${ms.toString(10).padStart(3, '0')}`
    );
  } else {
    segments.push(seconds.toString(10).padStart(2, '0'));
  }
  return segments.join(':');
}

export enum SunoShortType {
  IMAGE = 'image',
  VIDEO = 'video',
}

export function isSunoShort(clip: Clip) {
  return !!clip?.metadata?.is_suno_short;
}

export function getSunoShortType(clip: Clip): SunoShortType | undefined {
  if (!isSunoShort(clip)) return undefined;
  return !!clip?.metadata?.is_image_to_song
    ? SunoShortType.IMAGE
    : SunoShortType.VIDEO;
}

export const showExtentedInSongRow = (
  isLikedPlaylist: boolean,
  isComplete: boolean,
  isContestClip: boolean,
  clip: Clip,
  userId: string
) => {
  if (isContestClip) {
    return true;
  }
  if (isLikedPlaylist) {
    return false;
  }
  if (!isComplete) {
    return false;
  }
  return clip.user_id === userId || !isUnpublishableUploadClip(clip);
};

export const showCoverInSongRow = (isContestClip: boolean) => {
  if (isContestClip) {
    return true;
  }
  return false;
};

/**
 * Determines if a persona should be shown based on visibility rules
 */
export function shouldShowPersona(
  persona?: PersonaMetadata | null,
  currentUserHandle?: string | null
): boolean {
  if (!persona || !persona.id) return false;

  // Don't show trashed personas
  if (persona.is_trashed) return false;

  // Show if public or owned by current user
  return persona.is_public || persona.user_handle === currentUserHandle;
}
