<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\WebhookEvent;
use App\Services\Billing\PaypalWebhookProcessor;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class AdminWebhookController extends Controller
{
    public function __construct(private readonly PaypalWebhookProcessor $processor) {}

    private function authorizeAdmin(Request $request): ?JsonResponse
    {
        $token = (string) config('dewemoji.admin.token', '');
        $provided = trim((string) $request->header('X-Admin-Token', ''));
        if ($token === '' || $provided === '' || ! hash_equals($token, $provided)) {
            return response()->json(['ok' => false, 'error' => 'unauthorized'], 401);
        }

        return null;
    }

    public function index(Request $request): JsonResponse
    {
        if ($res = $this->authorizeAdmin($request)) {
            return $res;
        }

        $query = WebhookEvent::query();
        if ($provider = $request->query('provider')) {
            $query->where('provider', (string) $provider);
        }
        if ($status = $request->query('status')) {
            $query->where('status', (string) $status);
        }

        $limit = min(max((int) $request->query('limit', 50), 1), 200);
        $items = $query->orderByDesc('id')->limit($limit)->get();

        return response()->json(['ok' => true, 'items' => $items]);
    }

    public function show(Request $request, int $id): JsonResponse
    {
        if ($res = $this->authorizeAdmin($request)) {
            return $res;
        }

        $item = WebhookEvent::find($id);
        if (! $item) {
            return response()->json(['ok' => false, 'error' => 'not_found'], 404);
        }

        return response()->json(['ok' => true, 'item' => $item]);
    }

    public function replay(Request $request, int $id): JsonResponse
    {
        if ($res = $this->authorizeAdmin($request)) {
            return $res;
        }

        $item = WebhookEvent::find($id);
        if (! $item) {
            return response()->json(['ok' => false, 'error' => 'not_found'], 404);
        }

        $item->update(['status' => 'pending', 'processed_at' => null, 'error' => null]);

        try {
            if ($item->provider === 'paypal') {
                $this->processor->process((string) ($item->event_type ?? ''), $item->payload ?? []);
            }
            $item->update([
                'status' => 'processed',
                'processed_at' => now(),
            ]);
        } catch (\Throwable $e) {
            $item->update([
                'status' => 'error',
                'error' => $e->getMessage(),
                'processed_at' => now(),
            ]);
        }

        return response()->json(['ok' => true, 'replayed' => true]);
    }
}
