const axios = require('axios')

class APIError extends Error {
  constructor(message, status, data) {
    super(message)
    this.name = 'APIError'
    this.status = status
    this.data = data
  }
}

/**
 * Create a stateless API client for the BILDIT CMS.
 * @param {string} baseURL - CMS base URL (e.g. https://your-cms.bildit.io)
 * @param {string} token - Bearer token for authentication
 * @returns {import('axios').AxiosInstance}
 */
function createClient(baseURL, token) {
  if (!baseURL || !token) {
    throw new Error('baseURL and token are required for createClient')
  }

  const client = axios.create({
    baseURL,
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
  })

  client.interceptors.response.use(
    (response) => response,
    (error) => {
      if (error.response) {
        const { status, data } = error.response
        throw new APIError(
          data?.message || error.message || 'API request failed',
          status,
          data
        )
      }
      throw error
    }
  )

  return client
}

async function listBanners(client, appId, params = {}) {
  const response = await client.get(`/api/apps/${appId}/banners`, { params })
  return response.data
}

async function listCodeLibraries(client, appId) {
  const response = await client.get(`/api/apps/${appId}/codelibs`)
  return response.data
}

async function getCodeLibrary(client, appId, cid) {
  const response = await client.get(`/api/apps/${appId}/codelibs/${cid}`)
  return response.data
}

async function createCodeLibrary(client, appId, data) {
  const response = await client.post(`/api/apps/${appId}/codelibs`, data)
  return response.data
}

async function updateCodeLibrary(client, appId, cid, data) {
  const response = await client.put(`/api/apps/${appId}/codelibs/${cid}`, data)
  return response.data
}

async function updateBanner(client, appId, bid, data) {
  const response = await client.put(`/api/apps/${appId}/banners/${bid}`, data)
  return response.data
}

async function transpileCode(client, appId, code, codeType) {
  const response = await client.post(`/api/apps/${appId}/transpile`, {
    code,
    codeType,
  })
  return response.data.compiled ?? response.data
}

async function getApps(client) {
  const response = await client.get('/api/apps')
  return response.data
}

async function getWebs(client) {
  const response = await client.get('/api/webs')
  return response.data
}

async function createVersion(client, appId, cid, versionData) {
  const response = await client.post(
    `/api/apps/${appId}/codelibs/${cid}/versions`,
    versionData
  )
  return response.data
}

module.exports = {
  createClient,
  listBanners,
  listCodeLibraries,
  getCodeLibrary,
  createCodeLibrary,
  updateCodeLibrary,
  updateBanner,
  transpileCode,
  getApps,
  getWebs,
  createVersion,
  APIError,
}
