const API_BASE = import.meta.env.VITE_API_BASE || '/api';

async function request(path, options = {}) {
  const response = await fetch(`${API_BASE}${path}`, {
    headers: {
      'Content-Type': 'application/json',
      ...(options.headers || {})
    },
    ...options
  });

  if (!response.ok) {
    let errorPayload = null;
    let message = `HTTP ${response.status}`;
    try {
      errorPayload = await response.json();
      message = errorPayload?.error?.message || message;
    } catch (_error) {
      // ignore parse errors
    }
    const error = new Error(message);
    error.status = response.status;
    error.details = errorPayload?.error?.details || null;
    throw error;
  }

  const contentType = response.headers.get('content-type') || '';
  if (contentType.includes('application/json')) {
    return response.json();
  }

  return response.text();
}

export const api = {
  getSettings() {
    return request('/settings');
  },
  getHandBrakePresets() {
    return request('/settings/handbrake-presets');
  },
  getScripts() {
    return request('/settings/scripts');
  },
  createScript(payload = {}) {
    return request('/settings/scripts', {
      method: 'POST',
      body: JSON.stringify(payload || {})
    });
  },
  updateScript(scriptId, payload = {}) {
    return request(`/settings/scripts/${encodeURIComponent(scriptId)}`, {
      method: 'PUT',
      body: JSON.stringify(payload || {})
    });
  },
  deleteScript(scriptId) {
    return request(`/settings/scripts/${encodeURIComponent(scriptId)}`, {
      method: 'DELETE'
    });
  },
  testScript(scriptId) {
    return request(`/settings/scripts/${encodeURIComponent(scriptId)}/test`, {
      method: 'POST'
    });
  },
  updateSetting(key, value) {
    return request(`/settings/${encodeURIComponent(key)}`, {
      method: 'PUT',
      body: JSON.stringify({ value })
    });
  },
  updateSettingsBulk(settings) {
    return request('/settings', {
      method: 'PUT',
      body: JSON.stringify({ settings })
    });
  },
  testPushover(payload = {}) {
    return request('/settings/pushover/test', {
      method: 'POST',
      body: JSON.stringify(payload)
    });
  },
  getPipelineState() {
    return request('/pipeline/state');
  },
  analyzeDisc() {
    return request('/pipeline/analyze', {
      method: 'POST'
    });
  },
  rescanDisc() {
    return request('/pipeline/rescan-disc', {
      method: 'POST'
    });
  },
  searchOmdb(q) {
    return request(`/pipeline/omdb/search?q=${encodeURIComponent(q)}`);
  },
  selectMetadata(payload) {
    return request('/pipeline/select-metadata', {
      method: 'POST',
      body: JSON.stringify(payload)
    });
  },
  startJob(jobId) {
    return request(`/pipeline/start/${jobId}`, {
      method: 'POST'
    });
  },
  confirmEncodeReview(jobId, payload = {}) {
    return request(`/pipeline/confirm-encode/${jobId}`, {
      method: 'POST',
      body: JSON.stringify(payload || {})
    });
  },
  cancelPipeline(jobId = null) {
    return request('/pipeline/cancel', {
      method: 'POST',
      body: JSON.stringify({ jobId })
    });
  },
  retryJob(jobId) {
    return request(`/pipeline/retry/${jobId}`, {
      method: 'POST'
    });
  },
  resumeReadyJob(jobId) {
    return request(`/pipeline/resume-ready/${jobId}`, {
      method: 'POST'
    });
  },
  reencodeJob(jobId) {
    return request(`/pipeline/reencode/${jobId}`, {
      method: 'POST'
    });
  },
  restartReviewFromRaw(jobId) {
    return request(`/pipeline/restart-review/${jobId}`, {
      method: 'POST'
    });
  },
  restartEncodeWithLastSettings(jobId) {
    return request(`/pipeline/restart-encode/${jobId}`, {
      method: 'POST'
    });
  },
  getPipelineQueue() {
    return request('/pipeline/queue');
  },
  reorderPipelineQueue(orderedJobIds = []) {
    return request('/pipeline/queue/reorder', {
      method: 'POST',
      body: JSON.stringify({ orderedJobIds: Array.isArray(orderedJobIds) ? orderedJobIds : [] })
    });
  },
  getJobs(params = {}) {
    const query = new URLSearchParams();
    if (params.status) query.set('status', params.status);
    if (params.search) query.set('search', params.search);
    const suffix = query.toString() ? `?${query.toString()}` : '';
    return request(`/history${suffix}`);
  },
  getDatabaseRows(params = {}) {
    const query = new URLSearchParams();
    if (params.status) query.set('status', params.status);
    if (params.search) query.set('search', params.search);
    const suffix = query.toString() ? `?${query.toString()}` : '';
    return request(`/history/database${suffix}`);
  },
  getOrphanRawFolders() {
    return request('/history/orphan-raw');
  },
  importOrphanRawFolder(rawPath) {
    return request('/history/orphan-raw/import', {
      method: 'POST',
      body: JSON.stringify({ rawPath })
    });
  },
  assignJobOmdb(jobId, payload = {}) {
    return request(`/history/${jobId}/omdb/assign`, {
      method: 'POST',
      body: JSON.stringify(payload || {})
    });
  },
  deleteJobFiles(jobId, target = 'both') {
    return request(`/history/${jobId}/delete-files`, {
      method: 'POST',
      body: JSON.stringify({ target })
    });
  },
  deleteJobEntry(jobId, target = 'none') {
    return request(`/history/${jobId}/delete`, {
      method: 'POST',
      body: JSON.stringify({ target })
    });
  },
  getJob(jobId, options = {}) {
    const query = new URLSearchParams();
    if (options.includeLiveLog) {
      query.set('includeLiveLog', '1');
    }
    if (options.includeLogs) {
      query.set('includeLogs', '1');
    }
    if (options.includeAllLogs) {
      query.set('includeAllLogs', '1');
    }
    if (Number.isFinite(Number(options.logTailLines)) && Number(options.logTailLines) > 0) {
      query.set('logTailLines', String(Math.trunc(Number(options.logTailLines))));
    }
    const suffix = query.toString() ? `?${query.toString()}` : '';
    return request(`/history/${jobId}${suffix}`);
  }
};

export { API_BASE };
