<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

/**
 * Création de session Stripe Checkout pour le marketplace.
 *
 * - local : clés MARKETPLACE_STRIPE_* sur cette instance (hébergeur peut détourner les paiements).
 * - remote : session créée par le serveur de licence (GdevStudio) — seul ce serveur tient sk_live.
 */
class MarketplaceCheckoutService
{
    public function __construct(
        protected MarketplaceStripeService $stripe
    ) {}

    public function driver(): string
    {
        return config('marketplace.payment.driver', 'local');
    }

    public function isRemoteDriver(): bool
    {
        return $this->driver() === 'remote';
    }

    public function isCheckoutAvailable(): bool
    {
        if ($this->isRemoteDriver()) {
            return $this->isRemoteConfigured();
        }

        return $this->stripe->isConfigured();
    }

    public function isRemoteConfigured(): bool
    {
        $licenseUrl = rtrim((string) config('marketplace.license.url', ''), '/');

        return $licenseUrl !== ''
            && ! empty(config('marketplace.license.api_key'));
    }

    protected function remoteCheckoutEndpoint(): string
    {
        $explicit = trim((string) config('marketplace.payment.remote.checkout_url', ''));

        if ($explicit !== '') {
            return $explicit;
        }

        return rtrim((string) config('marketplace.license.url', ''), '/').'/api/marketplace/create-checkout-session';
    }

    /**
     * @return array{url: string, session_id?: string}|array{error: string}
     */
    public function createCheckoutSession(
        string $itemType,
        string $itemSlug,
        string $itemName,
        int $priceCents,
        string $successUrl,
        string $cancelUrl
    ): array {
        if ($this->isRemoteDriver()) {
            return $this->createRemoteCheckoutSession(
                $itemType,
                $itemSlug,
                $successUrl,
                $cancelUrl
            );
        }

        return $this->stripe->createCheckoutSession(
            $itemType,
            $itemSlug,
            $itemName,
            $priceCents,
            $successUrl,
            $cancelUrl
        );
    }

    /**
     * Le serveur distant détermine prix et libellé depuis son catalogue (pas de confiance au client).
     *
     * @return array{url: string, session_id?: string}|array{error: string}
     */
    protected function createRemoteCheckoutSession(
        string $itemType,
        string $itemSlug,
        string $successUrl,
        string $cancelUrl
    ): array {
        if (! $this->isRemoteConfigured()) {
            return ['error' => 'Serveur de licence ou clé API non configuré.'];
        }

        $appUrl = rtrim((string) config('app.url', ''), '/');
        if ($appUrl === '') {
            Log::warning('Marketplace remote checkout: APP_URL vide.');

            return ['error' => 'APP_URL est vide dans le .env.'];
        }

        $endpoint = $this->remoteCheckoutEndpoint();

        try {
            $response = Http::timeout(20)
                ->withHeaders([
                    'Authorization' => 'Bearer '.config('marketplace.license.api_key'),
                    'Accept' => 'application/json',
                ])
                ->post($endpoint, [
                    'item_type' => $itemType,
                    'item_slug' => $itemSlug,
                    'success_url' => $successUrl,
                    'cancel_url' => $cancelUrl,
                    'app_url' => $appUrl,
                ]);
        } catch (\Throwable $e) {
            Log::error('Marketplace remote checkout HTTP error', [
                'endpoint' => $endpoint,
                'message' => $e->getMessage(),
            ]);

            return ['error' => 'Impossible de joindre le serveur de licence : '.$e->getMessage()];
        }

        if (! $response->successful()) {
            $status = $response->status();
            $json = $response->json();
            $code = is_array($json) ? ($json['error'] ?? null) : null;

            if ($status === 422 && $code === null && is_array($json)) {
                $first = ! empty($json['errors'])
                    ? collect($json['errors'])->flatten()->filter()->first()
                    : null;
                $hint = is_string($first) ? $first : '';
                $msg = is_string($json['message'] ?? null) ? (string) $json['message'] : '';
                if ($msg !== '' || $hint !== '') {
                    $detail = $msg !== '' ? $msg : 'Données invalides.';
                    if ($hint !== '') {
                        $detail .= ' — '.$hint;
                    }
                    Log::warning('Marketplace remote checkout rejected', [
                        'endpoint' => $endpoint,
                        'status' => $status,
                        'body' => $response->body(),
                    ]);

                    return ['error' => 'Serveur de licence (HTTP 422) : '.$detail];
                }
            }

            $suffix = is_string($code) && $code !== '' ? ' Code : '.$code.'.' : '';
            $message = match (true) {
                $status === 404 => 'URL API introuvable (HTTP 404). Causes fréquentes : (1) cache des routes obsolète sur le VPS après rsync — exécuter `php artisan route:clear` puis `route:cache`. (2) Nginx `root` hors de `public/`. Test : '.rtrim((string) config('marketplace.license.url', ''), '/').'/api/health doit renvoyer du JSON.',
                $code === 'unauthorized' => 'Clé API refusée par le serveur de licence : la valeur doit être identique à LICENSE_API_KEY sur le VPS (caractère pour caractère, y compris base64: si présent).',
                $code === 'url_host_mismatch' => 'Le domaine de APP_URL ne correspond pas aux URLs success/cancel générées par le CMS (hôte différent). Vérifie APP_URL dans le .env du CMS : il doit être exactement l’URL du site (même host que dans le navigateur, avec ou sans www comme tu l’utilises).',
                $code === 'https_required' => 'Le serveur de licence refuse les URLs en http pour ton domaine. Passe le CMS en HTTPS ou, en staging uniquement, mets LICENSE_ALLOW_HTTP_CALLBACKS=true sur le VPS puis config:cache.',
                $code === 'server_not_configured' => 'Stripe n’est pas configuré sur le serveur de licence : renseigne LICENSE_STRIPE_SECRET sur le VPS.',
                $code === 'unknown_item' => 'Ce produit n’existe pas dans le catalogue du serveur de licence : mets à jour config/marketplace_catalog.php sur le VPS et redéploie.',
                $code === 'external_product' => 'Ce produit n’est pas vendu en ligne (lien externe).',
                $code === 'invalid_price' => 'Prix invalide dans le catalogue serveur.',
                $code === 'stripe_error' => 'Erreur Stripe côté serveur de licence — consulte storage/logs/laravel.log sur le VPS.',
                default => 'Serveur de licence (HTTP '.$status.').'.$suffix,
            };
            Log::warning('Marketplace remote checkout rejected', [
                'endpoint' => $endpoint,
                'status' => $response->status(),
                'body' => $response->body(),
            ]);

            return ['error' => $message];
        }

        $url = $response->json('url');
        if (! is_string($url) || $url === '') {
            return ['error' => 'Réponse serveur de licence invalide (pas d’URL Checkout).'];
        }

        $sessionId = $response->json('session_id');

        return [
            'session_id' => is_string($sessionId) ? $sessionId : null,
            'url' => $url,
        ];
    }
}
