/** Central English copy for future localization. */

export const messages = {
  appHeaderBrandPrefix: 'discovery',
  appHeaderBrandResetLabel: 'discovery-by-llm: start a new chat',
  appHeaderBrandAccent: '-by-',
  appHeaderBrandSuffix: 'llm',
  appHeaderKicker: 'proof of concept',
  appHeaderDemoMode: 'demo mode',
  appHeaderLiveMode: 'live mode',
  appHeaderModeUnavailable: 'mode unavailable',
  appHeaderCheckingMode: 'checking mode',
  appHeaderDevPanel: 'Dev panel',
  appHeaderDevPanelShort: 'Dev',
  appHeaderDevPanelShortcut: 'Ctrl+D',

  assistantMessageReadingRequest: 'Reading the request',
  assistantMessageCheckingCandidates: 'Checking candidates',
  assistantMessageCheckingCandidateCount: 'Checking {count} candidates',
  assistantMessageStreamingTracks: 'Streaming verified tracks',
  assistantMessageAvatar: 'd',

  authStatusCheckingConnection: 'Checking Spotify connection',
  authStatusConnectSpotify: 'Connect Spotify',
  authStatusConnect: 'Connect',
  authStatusTryAgain: 'Try Spotify again',
  authStatusRetry: 'Retry',
  authStatusConnectedAs: 'Connected as ',
  authStatusLoggingOut: 'Logging out...',
  authStatusLogOut: 'Log out',

  chatViewNoTurns: 'no turns yet',
  chatViewOneTurn: '{count} turn in this session',
  chatViewManyTurns: '{count} turns in this session',

  devPanelTitle: 'Dev panel',
  devPanelCloseLabel: 'Close dev panel',
  devPanelCloseSymbol: 'X',
  devPanelLatestRequest: 'Latest request',
  devPanelContractCaption: 'Only counters supplied by the recommendation contract are shown.',
  devPanelRequestId: 'request id',
  devPanelCandidateCount: 'candidate count',
  devPanelTrackCount: 'track count',
  devPanelTotalMilliseconds: 'total ms',
  devPanelWaiting: 'waiting',
  devPanelConversation: 'Conversation',
  devPanelClearConversation: 'Clear conversation',
  devPanelEventStream: 'Event stream',
  devPanelIdle: 'idle',
  devPanelWaitingForRequest: 'waiting for a request',

  emptyResultsTitle: 'No verified tracks matched this request.',
  emptyResultsGuidance: 'Try broadening the moment or removing one constraint.',

  emptyStateHeading: 'What should be playing',
  emptyStateHeadingAccent: ' right now?',
  emptyStateDescription:
    'Describe the moment, not the genre. The assistant reads the request, proposes candidates, verifies each one on Spotify and explains why it picked them.',
  emptyStateSuggestionLabel: 'Try one of these',

  messageInputAriaLabel: 'Describe what you want to listen to',
  messageInputPlaceholder:
    'Describe the moment: "something calm while I am programming, but not boring"',
  messageInputNarrowPlaceholder: 'Describe the moment...',
  messageInputWorking: 'Working...',
  messageInputSend: 'Send',
  messageInputHint:
    'Enter to send / refine with follow-ups like "more electronic and drop number 3"',

  messageListConversationLabel: 'Conversation',
  messageListRequestFailed: 'The recommendation request failed.',
  messageListTracksReady: '{count} tracks ready.',
  messageListWarning: 'Warning {count}: {message}',
  messageListReadingRequest: 'Reading the request.',
  messageListCheckingCandidates: 'Checking recommendation candidates.',
  messageListVerifiedTracksReceived: '{count} verified tracks received.',

  modeBannerDemo: 'Demo mode: replaying recorded recommendation sessions',

  playlistSavedConfirmationPrefix: 'Saved ',
  playlistSavedMetadata: '{count} tracks / private / created just now',
  playlistSavedOpenSpotify: 'Open in Spotify',

  requestMetadataCandidates: '{count} candidates considered',
  requestMetadataVerified: '{count} verified',
  requestMetadataDuration: '{milliseconds} ms',

  resultActionsSaving: 'Saving...',
  resultActionsTryAgain: 'Try saving again',
  resultActionsSavePlaylist: 'Save as playlist',
  resultActionsConnectSpotify: 'Connect Spotify to save',
  resultActionsSummary: '{count} verified tracks ready for a private playlist',

  resultSetRecommendedTrackLabel: '{count} recommended track',
  resultSetRecommendedTracksLabel: '{count} recommended tracks',

  streamErrorRetry: 'Edit and retry',

  suggestionChipsRegionLabel: 'Listening suggestions',

  trackCardArtworkAlt: '{album} album artwork',
  trackCardOpenSpotify: 'Open in Spotify',

  useApiInvalidCurrentUser: 'Invalid current user response.',
  useApiInvalidPlaylist: 'Invalid playlist response.',
  useApiLoginFailed: 'Spotify login did not complete. Please try again.',
  useApiAuthenticationCheckFailed: 'Authentication check failed.',
  useApiConnectionUnavailable: 'Spotify connection status is unavailable.',
  useApiHealthCheckFailed: 'Health check failed.',
  useApiInvalidHealth: 'Invalid health response.',
  useApiModeUnavailable: 'Service mode is unavailable.',
  useApiLogoutFailed: 'Logout failed.',
  useApiSpotifyLogoutFailed: 'Spotify logout failed. Refresh before trying again.',
  useApiPlaylistCreationFailed: 'Playlist creation returned {status}.',

  useChatStreamTrackCountMismatch: 'The final track count did not match the streamed results.',
  useChatStreamRequestReplaced: 'This request was replaced by a newer request.',
  useChatStreamUnexpectedFailure: 'The recommendation request failed unexpectedly.',
  useChatStreamTransportEvent: 'transport',
  useChatStreamPlaylistFailure: 'Spotify could not create the playlist. Nothing was retried.',

  recommendationStreamInvalidJson: 'The response contained invalid JSON.',
  recommendationStreamMissingMetadata: 'The stream did not begin with metadata.',
  recommendationStreamDuplicateMetadata: 'The stream contained duplicate metadata.',
  recommendationStreamAfterFinalEvent: 'The stream continued after its final event.',
  recommendationStreamUnavailable: 'The recommendation service could not be reached.',
  recommendationStreamHttpFailure: 'The recommendation service returned {status}.',
  recommendationStreamInvalidContentType: 'The response was not an NDJSON stream.',
  recommendationStreamEmpty: 'The response stream was empty.',
  recommendationStreamUnexpectedEnd:
    'The recommendation stream ended before a final event arrived.',
  recommendationStreamInterrupted: 'The recommendation stream was interrupted.',

  streamParserInvalidField: 'Invalid {field} field.',
  streamParserInvalidTrack: 'Invalid track field.',
  streamParserMissingType: 'Stream record has no valid type.',
  streamParserUnknownEvent: 'Unknown stream event type: {type}.',
} as const satisfies Readonly<Record<string, string>>

export type MessageKey = keyof typeof messages

/** Fill named placeholders in one extracted message. */
export function formatMessage(
  key: MessageKey,
  values: Readonly<Record<string, string | number>>,
): string {
  let message: string = messages[key]
  for (const [name, value] of Object.entries(values)) {
    message = message.replaceAll(`{${name}}`, String(value))
  }
  return message
}
