<?php

namespace App\Jobs;

use App\Services\ClaudeService;
use App\Services\NotionService;
use App\Support\NotionTask;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class GenerateDocumentationJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Maximum attempts before the job is marked failed.
     * Claude API calls can be slow — keep timeout generous.
     */
    public int $tries   = 3;
    public int $timeout = 300; // 5 minutes

    public function __construct(private readonly string $pageId) {}

    /**
     * Execute the job.
     */
    public function handle(NotionService $notion, ClaudeService $claude): void
    {
        Log::info('GenerateDocumentationJob: start', ['page_id' => $this->pageId]);

        // ── Step 1: Fetch task from the Tasks database ──────────────────────
        $page = $notion->getPage($this->pageId);

        // Idempotency: webhook events can arrive more than once.
        if (NotionTask::documentationStatus($page) === 'Generated') {
            Log::info('GenerateDocumentationJob: docs already generated, skipping', [
                'page_id' => $this->pageId,
            ]);
            return;
        }

        $title    = NotionTask::title($page);
        $category = NotionTask::category($page);

        $taskData = [
            'title'      => $title,
            'type'       => NotionTask::select($page['properties']['Type'] ?? []),
            'category'   => $category,
            'chamado'    => implode(', ', NotionTask::multiSelect($page['properties']['Tipo de Chamado'] ?? [])),
            'conclusion' => NotionTask::conclusion($page),
            'card_url'   => NotionTask::cardUrl($page),
            // The support ticket details, dev analysis, screenshots captions
            // and QA scenarios all live in the task page body.
            'body'       => $notion->getPageContent($this->pageId),
        ];

        Log::info('GenerateDocumentationJob: fetched task', [
            'title'    => $title,
            'category' => $category,
        ]);

        // ── Step 2: Call Claude API ─────────────────────────────────────────
        $docs = $claude->generateDocumentation($taskData);

        $categoryTag = match ($category) {
            'bug'     => '🐞 [Bug]',
            'project' => '🚀 [Projeto]',
            default   => '🧩 [Melhoria]',
        };

        // ── Step 3: Create Technical Doc page (dev-only section) ────────────
        $techPage = $notion->createPage(
            parentId: config('services.notion.technical_parent_page_id'),
            title:    "{$categoryTag} {$title}",
            content:  $this->markdownToNotionBlocks($docs['technical'])
        );

        // ── Step 4: Create User Release Note page (public section) ──────────
        $releasePage = $notion->createPage(
            parentId: config('services.notion.releases_parent_page_id'),
            title:    "{$categoryTag} " . NotionTask::cleanTitle($page),
            content:  $this->markdownToNotionBlocks($docs['user_note'])
        );

        // ── Step 5: Update original task with doc links & status ─────────────
        $notion->updatePageProperty($this->pageId, 'Documentation Status', [
            'select' => ['name' => 'Generated'],
        ]);

        $notion->updatePageProperty($this->pageId, 'Technical Doc', [
            'url' => $techPage['url'],
        ]);

        $notion->updatePageProperty($this->pageId, 'Release Note', [
            'url' => $releasePage['url'],
        ]);

        Log::info('GenerateDocumentationJob: completed', [
            'page_id'      => $this->pageId,
            'tech_page'    => $techPage['id'],
            'release_page' => $releasePage['id'],
        ]);
    }

    // ── Helpers ──────────────────────────────────────────────────────────────

    /**
     * Convert a simple markdown string into an array of Notion blocks.
     * Notion rich_text content is capped at 2000 chars per block.
     */
    private function markdownToNotionBlocks(string $markdown): array
    {
        $blocks = [];
        $lines  = explode("\n", $markdown);

        foreach ($lines as $line) {
            $trimmed = trim($line);

            if ($trimmed === '') {
                continue;
            }

            [$type, $text] = match (true) {
                str_starts_with($trimmed, '### ') => ['heading_3', substr($trimmed, 4)],
                str_starts_with($trimmed, '## ')  => ['heading_2', substr($trimmed, 3)],
                str_starts_with($trimmed, '# ')   => ['heading_1', substr($trimmed, 2)],
                str_starts_with($trimmed, '- '),
                str_starts_with($trimmed, '* ')   => ['bulleted_list_item', substr($trimmed, 2)],
                default                           => ['paragraph', $trimmed],
            };

            $blocks[] = [
                'object' => 'block',
                'type'   => $type,
                $type    => [
                    'rich_text' => [[
                        'type' => 'text',
                        'text' => ['content' => mb_substr($text, 0, 2000)],
                    ]],
                ],
            ];
        }

        return $blocks;
    }
}
