<?php

namespace App\Services;

use App\Prompts\DocumentationPrompt;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class ClaudeService
{
    private const API_URL = 'https://api.anthropic.com/v1/messages';

    // ─────────────────────────────────────────────────────────────────────────
    // Skill #1 — Documentation Generator
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Generate a technical doc and user-facing release note from a task.
     *
     * @param  array  $taskData  Keys: title, type, problem, analysis, correction, qaScenarios
     * @return array             Keys: technical, user_note
     */
    public function generateDocumentation(array $taskData): array
    {
        $prompt = DocumentationPrompt::buildDocumentationPrompt($taskData);

        $response = $this->callClaude($prompt);
        $content  = $response['content'][0]['text'] ?? '';

        // Claude is instructed to return only valid JSON
        $decoded = json_decode($content, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            Log::error('ClaudeService: JSON parse failed', [
                'raw' => $content,
                'error' => json_last_error_msg(),
            ]);
            throw new \RuntimeException('Claude returned invalid JSON: ' . json_last_error_msg());
        }

        return [
            'technical' => $decoded['technical_doc']      ?? '',
            'user_note' => $decoded['user_release_note']  ?? '',
        ];
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Skill #2 — Release Email Generator
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Aggregate all release notes into a formatted HTML email.
     *
     * @param  array   $releaseNotes  Array of release note strings (user-facing)
     * @param  string  $sprint        Sprint label e.g. "2026-06"
     * @return string                 Complete HTML email string
     */
    public function generateReleaseEmail(array $releaseNotes, string $sprint): string
    {
        $prompt = DocumentationPrompt::buildReleaseEmailPrompt($releaseNotes, $sprint);

        $response = $this->callClaude($prompt, model: config('services.anthropic.model'));
        $html     = $response['content'][0]['text'] ?? '';

        // Strip any markdown code fences Claude might wrap around the HTML
        $html = preg_replace('/^```html\s*/i', '', $html);
        $html = preg_replace('/\s*```$/i', '', $html);

        return trim($html);
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Core API Call
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Send a message to the Claude Messages API.
     *
     * @param  string  $userMessage  The fully constructed user prompt.
     * @param  string  $model        Model override (defaults to config).
     * @param  int     $maxTokens    Maximum tokens to generate.
     * @return array                 Full Anthropic API response object.
     */
    private function callClaude(
        string $userMessage,
        string $model     = '',
        int    $maxTokens = 4096
    ): array {
        $model = $model ?: config('services.anthropic.model', 'claude-sonnet-4-5');

        $response = Http::withHeaders([
            'x-api-key'         => config('services.anthropic.api_key'),
            'anthropic-version' => '2023-06-01',
            'Content-Type'      => 'application/json',
        ])->timeout(120)->post(self::API_URL, [
            'model'      => $model,
            'max_tokens' => $maxTokens,
            'messages'   => [
                ['role' => 'user', 'content' => $userMessage],
            ],
        ]);

        if ($response->failed()) {
            Log::error('ClaudeService: API call failed', [
                'status' => $response->status(),
                'body'   => $response->body(),
                'model'  => $model,
            ]);
            throw new \RuntimeException('Claude API error: ' . $response->body());
        }

        Log::info('ClaudeService: success', [
            'model'         => $model,
            'input_tokens'  => $response->json('usage.input_tokens'),
            'output_tokens' => $response->json('usage.output_tokens'),
        ]);

        return $response->json();
    }
}