import { StemView } from '@/app/(root)/stems/StemsTypes';
import { ClipFeedbackModalSource } from '@/logging/eventTypes/ClipFeedbackModalEventType';
import { InviteFriendModalSource } from '@/logging/eventTypes/InviteFriendModalEventType';
import { ShareModalSource } from '@/logging/eventTypes/ShareModalEventType';

export enum ModalTypes {
  ADD_TO_PLAYLIST = 'add_to_playlist',
  ADD_TO_PROJECT = 'add_to_project',
  CLIP_FEEDBACK = 'feedback',
  CLIP_JSON = 'clip_json',
  CREATE_PERSONA = 'create_persona',
  DELETE_CLIP = 'delete',
  DOWNLOAD_FILE = 'download',
  DOWNLOAD_SHARE_ASSET = 'download_share_asset',
  COPYRIGHT_FLAG = 'copyright_flag',
  COPYRIGHT_WARNING = 'copyright_warning',
  FLAG_CLIP = 'flag',
  LIBRARY_SELECT = 'library_select',
  SHARE_CLIP = 'share_clip',
  SHARE_WITH_FRIENDS = 'share_with_friends',
  UPSAMPLE_MODEL_SELECT = 'upsample_model_select',
  UPDATE_CLIP_METADATA = 'update_clip_metadata',
  FEEDBACK_FORM = 'feedback_form',
  CONFIRM_PIN_REPLACEMENT = 'confirm_pin_replacement',
  GENERIC_CONFIRM = 'generic_confirm',
  SONG_QUEUE = 'song_queue',
  PUBLISH_SONG = 'publish_song',
  UNPUBLISH_SONG = 'unpublish_song',
  STEM_EXTRACTION = 'stem_extraction',
  UPSELL_MODAL = 'upsell_modal',
  SONG_EDITOR = 'song_editor',
  EXTENDED_UPLOADS = 'extended_uploads',
  SELECT_HOOK_SONG = 'select_hook_song',
  EDIT_HOOK_METADATA = 'edit_hook_metadata',
  INVITE_FRIEND = 'invite_friend',
  REMIX_PERMISSION = 'remix_permission',
  OMNIPLAYER = 'omniplayer',
  STEMS = 'stems',
  DOWNLOAD_QUOTA = 'download_quota',
  COMMERCIAL_RIGHTS_SUCCESS = 'commercial_rights_success',
  SUBSCRIPTION_SUCCESS = 'subscription_success',
  REMASTER_MODAL = 'remaster_modal',
  RENEW_SUBSCRIPTION = 'renew_subscription',
  CREDITS_PURCHASE = 'credits_purchase',
  CANCEL_SUBSCRIPTION_CHANGES = 'cancel_subscription_changes',
  CANCEL_SUBSCRIPTION = 'cancel_subscription',
  MARKETPLACE_CREATE_PROJECT = 'marketplace_create_project',
  MARKETPLACE_UPLOAD_MEDIA = 'marketplace_upload_media',
  MARKETPLACE_PARTICIPANT_REVIEWS = 'marketplace_participant_reviews',
  GENERATE_COVER_ART = 'generate_cover_art',
  MARKETPLACE_EDIT_LISTING = 'marketplace_edit_listing',
  JOIN_SUNO = 'join_suno',
}

export type ModalOpenStateMap = Record<ModalTypes, boolean>;

// Define modals that need metadata + data types
export type StemsModalData = {
  clipId: string;
  initialView: StemView;
};
export type FlagModalData = {
  clipId: string;
  clipTitle: string;
};
export type CopyrightFlagModalData = {
  clipId: string;
};
export type ShareModalData = {
  clipId?: string;
  profileHandle?: string;
};
export type ShareWithFriendsModalData = {
  clipId: string;
};
export type ClipJsonModalData = {
  clipId: string;
  clipTitle?: string | null;
  clipJson: string;
};
export type ClipFeedbackModalData = {
  clipId: string;
};
export type UpsampleModelSelectModalData = {
  clipId: string;
};
export type RemasterModalData = {
  clipId?: string;
};
export type UnpublishSongModalData = {
  clipId: string;
};
export type AddToPlaylistModalData = {
  contextType?: string;
  recommendationItemId?: string;
  hookId?: string;
};
export type EditHookMetadataModalData = {
  hookId: string;
};
export type ConfirmPinReplacementModalData = {
  clipId: string;
  title: string;
  message: string;
};
export type MarketplaceCreateProjectModalData = {
  clipId: string;
  clipTitle: string;
  clipUrl: string;
};
export type MarketplaceUploadMediaModalData = {
  projectId?: string;
  mode?: 'full' | 'audio-only';
  title?: string;
  referenceType?: 'submission' | 'reference';
  isCreator?: boolean;
  existingSubmissionCount?: number;
  initialParentTaskId?: string | null;
  initialDescription?: string;
  onUploadComplete?: (
    mediaReferences: Array<{
      id: string;
      type: 'audio' | 'image';
      url: string;
      name: string;
    }>
  ) => void;
};
export type MarketplaceParticipantReviewsModalData = {
  userId: number;
  userName: string;
  userRole: 'creator' | 'fulfiller';
  userAvatarUrl?: string | null;
  userHandle?: string | null;
  projectId: string;
  projectStatus: string;
  canLeaveReview: boolean;
  onReviewSubmitted?: () => void;
};
export type MarketplaceEditListingModalData = {
  projectId: string;
  title: string;
  summary?: string | null;
  description: string;
  creditBounty: number;
  deadline?: string | null;
  originalClipImageUrl?: string | null;
  status: string;
  onSaveComplete?: () => void;
};
export type PublishSongModalScreenType =
  | 'main'
  | 'lyrics'
  | 'moreOptions'
  | 'addingVideo'
  | 'addingImage'
  | 'addingMedia'
  | 'shareContestSubmission'
  | 'generatingCover'
  | 'generationHistory'
  | 'generationFavorites'
  | 'generationCarousel';

export type PublishSongModalData = {
  initialScreen?: PublishSongModalScreenType;
  clipId?: string; // Optional clipId to override library.activeClip
};
export type GenerateCoverArtModalData = {
  clipId: string;
  useClipCoverImage?: boolean;
};
export type JoinSunoModalData = {
  clipId: string;
  redirectUrl?: string;
};
export type ModalTypeDataMap = {
  [ModalTypes.STEMS]: StemsModalData;
  [ModalTypes.FLAG_CLIP]: FlagModalData;
  [ModalTypes.COPYRIGHT_FLAG]: CopyrightFlagModalData;
  [ModalTypes.SHARE_CLIP]: ShareModalData;
  [ModalTypes.SHARE_WITH_FRIENDS]: ShareWithFriendsModalData;
  [ModalTypes.CLIP_JSON]: ClipJsonModalData;
  [ModalTypes.CLIP_FEEDBACK]: ClipFeedbackModalData;
  [ModalTypes.UPSAMPLE_MODEL_SELECT]: UpsampleModelSelectModalData;
  [ModalTypes.REMASTER_MODAL]: RemasterModalData;
  [ModalTypes.UNPUBLISH_SONG]: UnpublishSongModalData;
  [ModalTypes.ADD_TO_PLAYLIST]: AddToPlaylistModalData;
  [ModalTypes.CONFIRM_PIN_REPLACEMENT]: ConfirmPinReplacementModalData;
  [ModalTypes.EDIT_HOOK_METADATA]: EditHookMetadataModalData;
  [ModalTypes.MARKETPLACE_CREATE_PROJECT]: MarketplaceCreateProjectModalData;
  [ModalTypes.MARKETPLACE_UPLOAD_MEDIA]: MarketplaceUploadMediaModalData;
  [ModalTypes.MARKETPLACE_PARTICIPANT_REVIEWS]: MarketplaceParticipantReviewsModalData;
  [ModalTypes.MARKETPLACE_EDIT_LISTING]: MarketplaceEditListingModalData;
  [ModalTypes.PUBLISH_SONG]: PublishSongModalData;
  [ModalTypes.UPDATE_CLIP_METADATA]: PublishSongModalData;
  [ModalTypes.GENERATE_COVER_ART]: GenerateCoverArtModalData;
  [ModalTypes.JOIN_SUNO]: JoinSunoModalData;
};

// define modals that need to be opened with a source for tracking
export enum StemsModalSource {
  STUDIO = 'Studio',
  SONG_MENU = 'SongMenu',
  EDIT = 'Edit',
}
export type PublishSongModalSource =
  | 'PublishButton'
  | 'SongMenu'
  | 'DesktopSongPage'
  | 'ClipCaption'
  | 'GenerationNotification'
  | 'MobileSongPage'
  | 'ClipPreview'
  | 'FocusedObjectPanel';
export type AddToPlaylistModalSource =
  | 'SongMenu'
  | 'DesktopSongPage'
  | 'MobileSongPage'
  | 'HooksFeedClient';
export type ModalTypeSourcesMap = {
  [ModalTypes.INVITE_FRIEND]: InviteFriendModalSource;
  [ModalTypes.STEMS]: StemsModalSource;
  [ModalTypes.PUBLISH_SONG]: PublishSongModalSource;
  [ModalTypes.UPDATE_CLIP_METADATA]: PublishSongModalSource;
  [ModalTypes.SHARE_CLIP]: ShareModalSource;
  [ModalTypes.SHARE_WITH_FRIENDS]: ShareModalSource;
  [ModalTypes.CLIP_FEEDBACK]: ClipFeedbackModalSource;
  [ModalTypes.ADD_TO_PLAYLIST]: AddToPlaylistModalSource;
  [ModalTypes.GENERATE_COVER_ART]: PublishSongModalSource;
};

// Types for modals that need to be opened with a source for tracking
export type ModalTypeRequiredSources = keyof ModalTypeSourcesMap;
export type ModalTypeNoSources = Exclude<ModalTypes, ModalTypeRequiredSources>;
export type ModalSourceMap = Partial<ModalTypeSourcesMap> &
  Partial<Record<ModalTypeNoSources, undefined>>;

export type OpenModalFn = {
  <T extends ModalTypeRequiredSources>(
    modalType: T,
    source: ModalTypeSourcesMap[T]
  ): void;
  (modalType: ModalTypeNoSources): void;
};
export type GetModalSourceFn = {
  <T extends keyof ModalTypeSourcesMap>(modalType: T): ModalTypeSourcesMap[T];
  (modalType: ModalTypeNoSources): undefined;
};

// Types for modals that need to be opened with data
export type ModalTypeRequiredData = keyof ModalTypeDataMap;
export type ModalTypeNoData = Exclude<ModalTypes, ModalTypeRequiredData>;
export type ModalDataMap = Partial<ModalTypeDataMap> &
  Partial<Record<ModalTypeNoData, undefined>>;

export type OpenModalWithDataFn = {
  <T extends ModalTypeRequiredData & ModalTypeRequiredSources>(
    modalType: T,
    data: ModalTypeDataMap[T],
    source: ModalTypeSourcesMap[T]
  ): void;
  <T extends ModalTypeRequiredData>(
    modalType: T,
    data: ModalTypeDataMap[T]
  ): void;
};

export type GetModalDataFn = {
  <T extends ModalTypeRequiredData>(
    modalType: T
  ): ModalTypeDataMap[T] | undefined;
  (modalType: ModalTypeNoData): undefined;
};
