'use strict';

/**
 * Google Gemini Provider
 * 
 * Pricing (April 2026):
 *   Gemini 2.5 Pro: $1.25 / 1M input,  $10.00 / 1M output
 */

const https = require('https');
const { URL } = require('url');

const DEFAULT_MODELS = {
  classification: 'gemini-2.5-pro',
  codeGeneration: 'gemini-2.5-pro',
  analysis: 'gemini-2.5-pro',
};

class GoogleProvider {
  constructor(config) {
    this.apiKey = config.apiKey;
    this.baseUrl = config.baseUrl || 'https://generativelanguage.googleapis.com/v1beta';
    this.models = Object.assign({}, DEFAULT_MODELS, config.model);
    this.temperature = config.temperature ?? 0.1;
    this.maxTokens = config.maxTokens ?? 4096;
    this.timeout = config.timeout ?? 60000;
  }

  async chat(messages, options = {}) {
    const model = options.model || this.models.codeGeneration;

    // Google uses a different request format
    let systemInstruction = '';
    const contents = [];
    for (const msg of messages) {
      if (msg.role === 'system') {
        systemInstruction += (systemInstruction ? '\n\n' : '') + msg.content;
      } else {
        contents.push({
          role: msg.role === 'assistant' ? 'model' : 'user',
          parts: [{ text: msg.content }],
        });
      }
    }

    const body = {
      contents,
      generationConfig: {
        temperature: options.temperature ?? this.temperature,
        maxOutputTokens: options.maxTokens ?? this.maxTokens,
      },
    };
    if (systemInstruction) {
      body.systemInstruction = { parts: [{ text: systemInstruction }] };
    }

    const path = `/models/${model}:generateContent?key=${this.apiKey}`;
    const response = await this._request(path, body);

    if (!response.candidates || !response.candidates[0]) {
      throw new Error('Google AI API returned empty response');
    }

    const parts = response.candidates[0].content?.parts;
    if (!parts || !parts[0]) {
      throw new Error('Google AI API returned no content parts');
    }

    return parts[0].text;
  }

  async _request(path, body) {
    const url = new URL(path, this.baseUrl);

    return new Promise((resolve, reject) => {
      const postData = JSON.stringify(body);

      const req = https.request(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Content-Length': Buffer.byteLength(postData),
        },
        timeout: this.timeout,
      }, (res) => {
        let data = '';
        res.on('data', chunk => data += chunk);
        res.on('end', () => {
          if (res.statusCode >= 400) {
            reject(new Error(`Google AI API ${res.statusCode}: ${data.slice(0, 500)}`));
            return;
          }
          try {
            resolve(JSON.parse(data));
          } catch (e) {
            reject(new Error(`Failed to parse Google response: ${e.message}`));
          }
        });
      });

      req.on('timeout', () => {
        req.destroy();
        reject(new Error('Google AI API request timed out'));
      });

      req.on('error', reject);
      req.write(postData);
      req.end();
    });
  }
}

module.exports = GoogleProvider;
