<?php

namespace App\Http\Controllers;

use App\Services\ClaudeService;
use App\Services\NotionService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;

class ReleasePreviewController extends Controller
{
    /** How many past months to show in sprint selector */
    private const SPRINT_MONTHS = 12;

    public function __construct(
        private readonly NotionService $notion,
        private readonly ClaudeService $claude,
    ) {}

    /**
     * Show the release email preview page for a given sprint.
     *
     * Fetches release notes from Notion, calls Claude::generateReleaseEmail(),
     * renders resources/views/releases/preview.blade.php.
     *
     * Route: GET /releases/{sprint}/preview
     */
    public function show(string $sprint): View
    {
        Log::info('ReleasePreviewController::show', ['sprint' => $sprint]);

        [$releaseNotes, $emailHtml, $approved] = $this->buildEmailData($sprint);

        return view('releases.preview', [
            'sprint'           => $sprint,
            'emailHtml'        => $emailHtml,
            'releaseNotes'     => $releaseNotes,
            'approved'         => $approved,
            'availableSprints' => $this->getAvailableSprints(),
        ]);
    }

    /**
     * Force-regenerate the release email via Claude — returns JSON.
     * Called by the "Regenerate" button via AJAX (no page reload).
     *
     * Route: POST /releases/{sprint}/regenerate
     */
    public function regenerate(Request $request, string $sprint): JsonResponse
    {
        Log::info('ReleasePreviewController::regenerate', ['sprint' => $sprint]);

        try {
            $releaseNotes = $this->fetchReleaseNotes($sprint);

            if (empty($releaseNotes)) {
                return response()->json([
                    'error' => "No 'Generated' release notes found for sprint '{$sprint}'.",
                ], 404);
            }

            $emailHtml = $this->claude->generateReleaseEmail($releaseNotes, $sprint);

            return response()->json([
                'html'   => $emailHtml,
                'count'  => count($releaseNotes),
                'sprint' => $sprint,
            ]);
        } catch (\Throwable $e) {
            Log::error('ReleasePreviewController::regenerate failed', [
                'sprint' => $sprint,
                'error'  => $e->getMessage(),
            ]);

            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    /**
     * Save the approved HTML email to Notion, returns JSON success/error.
     * Called by the "Approve & Save to Notion" button via AJAX.
     *
     * Route: POST /releases/{sprint}/approve
     */
    public function approve(Request $request, string $sprint): JsonResponse
    {
        $validated = $request->validate([
            'html' => 'required|string|min:100',
        ]);

        Log::info('ReleasePreviewController::approve', ['sprint' => $sprint]);

        try {
            $parentId = config('services.notion.releases_parent_page_id');

            $page = $this->notion->createPage(
                parentId: $parentId,
                title:    "\xF0\x9F\x93\xA7 [APPROVED] Release Email \xe2\x80\x94 {$sprint}",
                content:  [
                    [
                        'object'    => 'block',
                        'type'      => 'paragraph',
                        'paragraph' => [
                            'rich_text' => [[
                                'type' => 'text',
                                'text' => ['content' => 'Approved on ' . now()->toDateTimeString()],
                            ]],
                        ],
                    ],
                    [
                        'object' => 'block',
                        'type'   => 'code',
                        'code'   => [
                            'language'  => 'html',
                            'rich_text' => [[
                                'type' => 'text',
                                'text' => ['content' => $validated['html']],
                            ]],
                        ],
                    ],
                ]
            );

            Log::info('ReleasePreviewController::approve saved to Notion', [
                'sprint'   => $sprint,
                'page_id'  => $page['id'],
                'page_url' => $page['url'],
            ]);

            return response()->json([
                'success'    => true,
                'notion_url' => $page['url'],
                'page_id'    => $page['id'],
                'message'    => "Release email for {$sprint} approved and saved to Notion.",
            ]);
        } catch (\Throwable $e) {
            Log::error('ReleasePreviewController::approve failed', [
                'sprint' => $sprint,
                'error'  => $e->getMessage(),
            ]);

            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    // ── Private Helpers ──────────────────────────────────────────────────────

    /**
     * Fetch release notes, generate email HTML, determine approval status.
     */
    private function buildEmailData(string $sprint): array
    {
        $releaseNotes = $this->fetchReleaseNotes($sprint);
        $approved     = false;

        $emailHtml = empty($releaseNotes)
            ? $this->emptyStateHtml($sprint)
            : $this->claude->generateReleaseEmail($releaseNotes, $sprint);

        return [$releaseNotes, $emailHtml, $approved];
    }

    /**
     * Query the Tasks database for all documented tasks in the given sprint.
     */
    private function fetchReleaseNotes(string $sprint): array
    {
        return $this->notion->releaseNotesForSprint($sprint);
    }

    /**
     * Build a list of sprint labels (YYYY-MM) for the sprint selector dropdown.
     * Returns the last SPRINT_MONTHS months + 1 month ahead.
     */
    private function getAvailableSprints(): array
    {
        $sprints = [];
        $now     = Carbon::now();

        for ($i = self::SPRINT_MONTHS; $i >= -1; $i--) {
            $sprints[] = $now->copy()->subMonths($i)->format('Y-m');
        }

        return array_reverse($sprints);
    }

    private function emptyStateHtml(string $sprint): string
    {
        return <<<HTML
<html><body style="font-family:-apple-system,BlinkMacSystemFont,sans-serif;padding:48px;text-align:center;color:#6c757d;">
<div style="max-width:420px;margin:0 auto;">
  <div style="font-size:48px;margin-bottom:16px;">📭</div>
  <h2 style="color:#343a40;font-weight:600;">No release notes found</h2>
  <p>No tasks with <strong>Documentation Status = Generated</strong> were found for sprint <strong>{$sprint}</strong>.</p>
  <p style="font-size:14px;">Mark tasks as <em>Ready to Release</em> in Notion to trigger the Claude documentation pipeline.</p>
</div>
</body></html>
HTML;
    }
}