import { discoverSections } from '@/services/mock-data'
import { apiGet, isMockApiEnabled, mockResponse, type ServiceRequestOptions } from '@/services/api-client'
import type { DiscoverParams, DiscoverSection, MediaItem } from '@/types/domain'

const normalize = (value: string): string => value.trim().toLowerCase()

const itemMatchesFilters = (item: MediaItem, params: Required<DiscoverParams>): boolean => {
  if (params.mediaType !== 'all' && item.type !== params.mediaType) {
    return false
  }

  if (params.genre && !item.genres.includes(params.genre)) {
    return false
  }

  if (!params.query) {
    return true
  }

  const term = normalize(params.query)
  return (
    normalize(item.title).includes(term) ||
    normalize(item.overview).includes(term) ||
    item.genres.some((genre) => normalize(genre).includes(term))
  )
}

const sanitizeParams = (params: DiscoverParams): Required<DiscoverParams> => ({
  page: Math.max(1, params.page ?? 1),
  pageSize: Math.max(1, params.pageSize ?? 6),
  query: params.query?.trim() ?? '',
  genre: params.genre ?? '',
  mediaType: params.mediaType ?? 'all',
})

const sectionPage = (
  items: MediaItem[],
  currentPage: number,
  pageSize: number,
): MediaItem[] => {
  const start = (currentPage - 1) * pageSize
  const end = currentPage * pageSize
  return items.slice(start, end)
}

const buildSections = (params: Required<DiscoverParams>): DiscoverSection[] =>
  discoverSections
    .map((section) => {
      const filtered = section.items.filter((item) => itemMatchesFilters(item, params))
      const paged = sectionPage(filtered, params.page, params.pageSize)

      return {
        ...section,
        title: params.genre ? `${section.title} · ${params.genre}` : section.title,
        items: paged,
      }
    })
    .filter((section) => section.items.length > 0)

export const discoverService = {
  getSections: async (
    params: DiscoverParams,
    options: ServiceRequestOptions = {},
  ): Promise<DiscoverSection[]> => {
    const sanitized = sanitizeParams(params)

    if (isMockApiEnabled()) {
      return mockResponse('/api/v1/discover', () => buildSections(sanitized), options)
    }

    return apiGet<DiscoverSection[]>('/api/v1/discover', {
      page: sanitized.page,
      pageSize: sanitized.pageSize,
      query: sanitized.query,
      genre: sanitized.genre,
      mediaType: sanitized.mediaType,
    })
  },
}
