const express = require('express')

/**
 * NewsApiCompatibilityController
 *
 * Mimics the subset of NewsAPI endpoints currently consumed by the front-end.
 */
class NewsApiCompatibilityController {
  constructor(storageService) {
    this._storageService = storageService
    this.router = express.Router()
    this._registerRoutes()
  }

  /**
   * @returns {void}
   */
  _registerRoutes() {
    this.router.get('/everything', this._wrap(async (request, response) => {
      const categoryKey = this._normalizeCategoryKey(request.query.q)
      const page = this._parsePositiveInteger(request.query.page, 1)
      const pageSize = this._parsePositiveInteger(request.query.pageSize, 10)
      const document = await this._storageService.getCategoryNewsPage(categoryKey, page, pageSize)

      response.json({
        status: 'ok',
        totalResults: document.total,
        articles: document.articles
      })
    }))

    this.router.get('/top-headlines', this._wrap(async (request, response) => {
      const categoryKey = this._normalizeCategoryKey(request.query.category || 'business')
      const page = this._parsePositiveInteger(request.query.page, 1)
      const pageSize = this._parsePositiveInteger(request.query.pageSize, 10)
      const document = await this._storageService.getCategoryNewsPage(categoryKey, page, pageSize)

      response.json({
        status: 'ok',
        totalResults: document.total,
        articles: document.articles
      })
    }))
  }

  /**
   * @param {unknown} value
   * @returns {string}
   */
  _normalizeCategoryKey(value) {
    const categoryKey = String(value || 'finance').trim().toLowerCase()
    return categoryKey
  }

  /**
   * @param {unknown} value
   * @param {number} fallback
   * @returns {number}
   */
  _parsePositiveInteger(value, fallback) {
    const parsed = Number(value)
    return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback
  }

  /**
   * @param {(request: import('express').Request, response: import('express').Response) => Promise<void>} handler
   * @returns {(request: import('express').Request, response: import('express').Response, next: import('express').NextFunction) => void}
   */
  _wrap(handler) {
    return (request, response, next) => {
      handler(request, response).catch(next)
    }
  }
}

module.exports = {
  NewsApiCompatibilityController
}