<?php

namespace App\Http\Controllers\Api\Hacienda;

use App\Http\Controllers\ApiController;
use App\Services\HaciendaWebhookService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\Response;

class WebhookHaciendaController extends ApiController
{
    public function __construct() {}

    public function __invoke(Request $request): JsonResponse
    {
        $secret = trim((string) env('MH_WEBHOOK_SECRET', ''));
        if ($secret === '') {
            return response()->json([
                'success' => false,
                'message' => 'Webhook secret not configured.',
                'data' => [],
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        $token = trim((string) $request->query('token', ''));
        if (!hash_equals($secret, $token)) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid webhook token.',
                'data' => [],
            ], Response::HTTP_UNAUTHORIZED);
        }

        $rawBody = $request->getContent();
        if ($rawBody === '' || $rawBody === null) {
            return response()->json([
                'success' => false,
                'message' => 'Empty payload.',
                'data' => [],
            ], Response::HTTP_BAD_REQUEST);
        }

        $payload = json_decode($rawBody, true);
        if (!is_array($payload)) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid JSON payload.',
                'data' => [],
            ], Response::HTTP_BAD_REQUEST);
        }

        $clave = trim((string) ($payload['clave'] ?? ''));
        $fecha = trim((string) ($payload['fecha'] ?? ''));
        $estado = strtolower(trim((string) ($payload['ind-estado'] ?? '')));

        if ($clave === '' || $fecha === '' || $estado === '') {
            return response()->json([
                'success' => false,
                'message' => 'Missing required payload fields.',
                'data' => [],
            ], Response::HTTP_UNPROCESSABLE_ENTITY);
        }

        $headers = json_encode($request->headers->all(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $payloadJson = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

        DB::statement(
            'INSERT IGNORE INTO webhook_hacienda_logs (clave, estado, payload, headers, ip, procesado, error, creado_en)
             VALUES (?, ?, ?, ?, ?, 0, NULL, NOW())',
            [
                $clave,
                $estado,
                $payloadJson,
                $headers,
                $request->ip(),
            ]
        );

        $log = DB::table('webhook_hacienda_logs')
            ->where('clave', $clave)
            ->where('estado', $estado)
            ->orderByDesc('id')
            ->first();

        if (!$log) {
            return response()->json([
                'success' => false,
                'message' => 'Webhook log not created.',
                'data' => [],
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }

        if ((int) $log->procesado === 1) {
            return response()->json([
                'success' => true,
                'message' => 'Webhook already processed.',
                'data' => [],
            ], Response::HTTP_OK);
        }

        try {
            app(HaciendaWebhookService::class)->process($payload, (int) $log->id);

            return response()->json([
                'success' => true,
                'message' => 'Webhook processed.',
                'data' => [],
            ], Response::HTTP_OK);
        } catch (\Throwable $e) {
            DB::table('webhook_hacienda_logs')
                ->where('id', (int) $log->id)
                ->update([
                    'procesado' => 0,
                    'error' => mb_substr($e->getMessage(), 0, 65000),
                ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage(),
                'data' => [],
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}