'use strict';

/**
 * ui/api-client.js — HTTP-клиент к /api/v1/*.
 *
 * UI-роуты не ходят напрямую в БД — только сюда.
 * Токен берётся из req.session.token (установлен на /login).
 *
 * Все ошибки пробрасываются как Error с понятным message.
 */

const http  = require('http');
const https = require('https');

const API_BASE = process.env.API_BASE || 'http://localhost:' + (process.env.PORT || 3000);

/**
 * Выполнить запрос к API.
 * @param {string} method  — GET, POST, PATCH, DELETE
 * @param {string} path    — /api/v1/entries
 * @param {string} token   — Bearer token
 * @param {object} [body]  — JSON body (для POST/PATCH)
 * @returns {Promise<{status: number, data: any}>}
 */
function apiRequest(method, path, token, body) {
  return new Promise((resolve, reject) => {
    const url  = new URL(API_BASE + path);
    const lib  = url.protocol === 'https:' ? https : http;
    const bodyStr = body ? JSON.stringify(body) : null;

    const opts = {
      hostname: url.hostname,
      port:     url.port || (url.protocol === 'https:' ? 443 : 80),
      path:     url.pathname + url.search,
      method,
      headers: {
        'Authorization': 'Bearer ' + token,
        'Accept':        'application/json',
      },
    };
    if (bodyStr) {
      opts.headers['Content-Type']   = 'application/json';
      opts.headers['Content-Length'] = Buffer.byteLength(bodyStr);
    }

    const req = lib.request(opts, (res) => {
      let raw = '';
      res.on('data', c => { raw += c; });
      res.on('end', () => {
        const ct = res.headers['content-type'] || '';
        const data = ct.includes('application/json') ? JSON.parse(raw) : raw;
        resolve({ status: res.statusCode, data });
      });
    });
    req.on('error', reject);
    req.on('timeout', () => { req.destroy(); reject(new Error('API timeout')); });
    if (bodyStr) req.write(bodyStr);
    req.end();
  });
}

// Хелперы — один вызов на метод
const api = {
  get:    (path, token)       => apiRequest('GET',    path, token),
  post:   (path, token, body) => apiRequest('POST',   path, token, body),
  patch:  (path, token, body) => apiRequest('PATCH',  path, token, body),
  delete: (path, token)       => apiRequest('DELETE', path, token),

  // Достать Bearer из сессии
  token: (req) => req.session && req.session.token,
};

module.exports = api;
