<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /private_html/public/src/Controllers/Content/RegeneratePostController.php
// Description: Regenerates a single Facebook post via the tenant's active AI provider — NUCLEAR+++
// Last Edited: 2026-03-28
// ==================================================

namespace AMAI\Core\Controllers\Content;

use AMAI\Core\Services\AI\AiProviderFactory;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;

final class RegeneratePostController
{
    private const VALID_POST_TYPES = [
        'educational',
        'product',
        'feel_good',
        'behind_scenes',
        'engagement',
    ];

    // @var callable(string, ?string=): ?string
    private mixed $env;

    public function __construct(
        private readonly AiProviderFactory        $providerFactory,
        private readonly ResponseFactoryInterface $responseFactory,
        private readonly LoggerInterface          $logger,
        callable                                  $env,
    ) {
        $this->env = $env;
    }

    // POST /api/content/regenerate-post
    // Body: {
    //   "post_id":          123,
    //   "post_type":        "educational",
    //   "scheduled_date":   "2026-03-30",
    //   "generation_batch": "2026-W14",
    //   "business_profile": { ...same fields as generate-week context... }
    // }
    // Returns: { "post_content": "..." }
    public function regenerate(Request $request): Response
    {
        $start     = microtime(true);
        $requestId = $request->getHeaderLine('X-Request-Id') ?: bin2hex(random_bytes(16));
        $tenant    = (string) ($request->getAttribute('tenant') ?? '');

        if ($tenant === '') {
            return $this->json(['error' => 'missing_tenant'], 400, $start, $requestId);
        }

        $data = $request->getParsedBody();
        if (!is_array($data)) {
            return $this->json(['error' => 'invalid_payload'], 400, $start, $requestId);
        }

        $post_id   = (int) ($data['post_id'] ?? 0);
        $post_type = trim((string) ($data['post_type'] ?? ''));

        if ($post_id <= 0) {
            return $this->json(['error' => 'missing_post_id'], 400, $start, $requestId);
        }

        if (!in_array($post_type, self::VALID_POST_TYPES, true)) {
            return $this->json(['error' => 'invalid_post_type'], 400, $start, $requestId);
        }

        $profile = $data['business_profile'] ?? null;
        if (!is_array($profile)) {
            return $this->json(['error' => 'missing_business_profile'], 400, $start, $requestId);
        }

        // Build context — same shape as generate-week
        $context = [
            'page_name'           => trim((string) ($profile['page_name']           ?? '')),
            'business_category'   => trim((string) ($profile['business_category']   ?? '')),
            'business_tone'       => trim((string) ($profile['business_tone']       ?? 'warm_personal')),
            'customer_descriptor' => trim((string) ($profile['customer_descriptor'] ?? '')),
            'differentiator'      => trim((string) ($profile['differentiator']      ?? '')),
            'values_and_causes'   => trim((string) ($profile['values_and_causes']   ?? '')),
        ];

        if ($context['page_name'] === '') {
            return $this->json(['error' => 'missing_page_name'], 400, $start, $requestId);
        }

        $validTones = ['warm_personal', 'professional_informative', 'witty_light'];
        if (!in_array($context['business_tone'], $validTones, true)) {
            $context['business_tone'] = 'warm_personal';
        }

        try {
            $provider = $this->providerFactory->make($tenant);
            $model    = $this->providerFactory->getModel($tenant);
        } catch (\RuntimeException $e) {
            $this->logger->warning('regenerate_post_no_provider', [
                'tenant'     => $tenant,
                'post_id'    => $post_id,
                'error'      => $e->getMessage(),
                'request_id' => $requestId,
            ]);
            return $this->json(['error' => $e->getMessage()], 422, $start, $requestId);
        }

        if ($model === '') {
            return $this->json(['error' => 'no_model_configured'], 422, $start, $requestId);
        }

        try {
            $post = $provider->generateSinglePost($context, $post_type, $model);
        } catch (\RuntimeException $e) {
            $this->logger->error('regenerate_post_ai_failed', [
                'tenant'     => $tenant,
                'post_id'    => $post_id,
                'post_type'  => $post_type,
                'error'      => $e->getMessage(),
                'request_id' => $requestId,
            ]);
            return $this->json(['error' => 'ai_generation_failed'], 502, $start, $requestId);
        } catch (\Throwable $e) {
            $this->logger->error('regenerate_post_unexpected_error', [
                'tenant'     => $tenant,
                'post_id'    => $post_id,
                'error'      => $e->getMessage(),
                'request_id' => $requestId,
            ]);
            return $this->json(['error' => 'server_error'], 500, $start, $requestId);
        }

        $this->logger->info('regenerate_post_success', [
            'tenant'     => $tenant,
            'post_id'    => $post_id,
            'post_type'  => $post_type,
            'request_id' => $requestId,
        ]);

        return $this->json(['post_content' => $post['content']], 200, $start, $requestId);
    }

    private function json(array $payload, int $status, float $start, string $requestId): Response
    {
        $json = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
            ?: '{"error":"json_encode_failed"}';

        $duration = (string) round((microtime(true) - $start) * 1000, 2);

        $r = $this->responseFactory->createResponse($status);
        $r->getBody()->write($json);

        return $r
            ->withHeader('Content-Type', 'application/json; charset=utf-8')
            ->withHeader('Cache-Control', 'no-store')
            ->withHeader('X-Request-Id', $requestId)
            ->withHeader('Server-Timing', 'regenerate_post;dur=' . $duration);
    }
}