import { dashboardPayload, mediaCatalog } from '@/services/mock-data'
import {
  apiDelete,
  apiGet,
  apiPost,
  isMockApiEnabled,
  mockResponse,
  type ServiceRequestOptions,
} from '@/services/api-client'
import type { MediaItem } from '@/types/domain'

const cloneMediaItem = (item: MediaItem): MediaItem => ({
  id: item.id,
  provider: item.provider,
  providerId: item.providerId,
  title: item.title,
  overview: item.overview,
  type: item.type,
  releaseDate: item.releaseDate,
  genres: [...item.genres],
  platforms: [...item.platforms],
  rating: item.rating,
  runtimeMinutes: item.runtimeMinutes,
  artworkKey: item.artworkKey,
})

let mockWatchLaterItems: MediaItem[] = dashboardPayload.watchLater.map(cloneMediaItem)

const authHeaders = (accessToken: string): Record<string, string> => ({
  Authorization: `Bearer ${accessToken}`,
})

export const watchLaterService = {
  getWatchLater: async (
    accessToken: string,
    options: ServiceRequestOptions = {},
  ): Promise<MediaItem[]> => {
    if (isMockApiEnabled()) {
      return mockResponse('/api/v1/watch-later', () => mockWatchLaterItems.map(cloneMediaItem), options)
    }

    return apiGet<MediaItem[]>('/api/v1/watch-later', {}, authHeaders(accessToken))
  },

  addWatchLater: async (
    accessToken: string,
    mediaId: number,
    options: ServiceRequestOptions = {},
  ): Promise<MediaItem[]> => {
    if (isMockApiEnabled()) {
      return mockResponse(
        '/api/v1/watch-later:add',
        () => {
          const existing = mockWatchLaterItems.find((item) => item.id === mediaId)
          if (existing) {
            return mockWatchLaterItems.map(cloneMediaItem)
          }

          const media = mediaCatalog.find((item) => item.id === mediaId)
          if (!media) {
            throw new Error('media not found')
          }

          mockWatchLaterItems = [cloneMediaItem(media), ...mockWatchLaterItems]
          return mockWatchLaterItems.map(cloneMediaItem)
        },
        options,
      )
    }

    return apiPost<MediaItem[]>('/api/v1/watch-later', { mediaId }, authHeaders(accessToken))
  },

  removeWatchLater: async (
    accessToken: string,
    mediaId: number,
    options: ServiceRequestOptions = {},
  ): Promise<MediaItem[]> => {
    if (isMockApiEnabled()) {
      return mockResponse(
        `/api/v1/watch-later/${mediaId}:remove`,
        () => {
          mockWatchLaterItems = mockWatchLaterItems.filter((item) => item.id !== mediaId)
          return mockWatchLaterItems.map(cloneMediaItem)
        },
        options,
      )
    }

    return apiDelete<MediaItem[]>(`/api/v1/watch-later/${mediaId}`, authHeaders(accessToken))
  },
}
