<?php

namespace App\Http\Controllers;

use App\Models\WhatsAppConversation;
use App\Services\WhatsAppConversationService;
use App\Services\WhatsAppMessageLogger;
use App\Support\WhatsAppConfig;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class WhatsAppWebhookController extends Controller
{
    /**
     * Meta webhook verification (GET) - required for subscription.
     */
    public function verify(Request $request)
    {
        $mode = $request->query('hub_mode');
        $token = $request->query('hub_verify_token');
        $challenge = $request->query('hub_challenge');

        $expected = WhatsAppConfig::verifyToken();
        if ($mode === 'subscribe' && $token !== null && $token === $expected && $expected !== '') {
            return response($challenge, 200)->header('Content-Type', 'text/plain');
        }

        Log::warning('WhatsApp webhook verify failed', ['mode' => $mode, 'has_expected' => $expected !== '']);
        return response()->json(['error' => 'Forbidden'], 403);
    }

    /**
     * Receive webhook payloads (POST) - validate HMAC and process.
     */
    public function receive(Request $request)
    {
        $rawBody = $request->getContent();
        Log::info('WhatsApp webhook POST received', ['content_length' => strlen($rawBody)]);

        $signature = $request->header('X-Hub-Signature-256');
        $appSecret = WhatsAppConfig::appSecret();
        $skipSignature = config('app.debug') && $appSecret === '' && env('WHATSAPP_SKIP_SIGNATURE_IN_DEV', false);

        if (!$skipSignature && !$this->validateSignature($rawBody, $signature)) {
            Log::warning('WhatsApp webhook: invalid signature', [
                'has_signature' => !empty($signature),
                'has_app_secret' => !empty($appSecret),
            ]);
            return response()->json(['error' => 'Invalid signature'], 401);
        }

        if ($skipSignature) {
            Log::warning('WhatsApp webhook: signature validation SKIPPED (dev mode)');
        }

        $payload = $request->all();
        $processed = false;
        if (isset($payload['object']) && $payload['object'] === 'whatsapp_business_account') {
            foreach ($payload['entry'] ?? [] as $entry) {
                foreach ($entry['changes'] ?? [] as $change) {
                    if (($change['field'] ?? '') === 'messages') {
                        $this->processMessages($change['value'] ?? []);
                        $processed = true;
                    }
                }
            }
        }

        if (!$processed) {
            Log::info('WhatsApp webhook: no messages to process', ['object' => $payload['object'] ?? null, 'entry_count' => count($payload['entry'] ?? [])]);
        }

        return response()->json(['success' => true]);
    }

    protected function validateSignature(string $payload, ?string $signature): bool
    {
        if (!$signature || !str_starts_with($signature, 'sha256=')) {
            return false;
        }
        $appSecret = WhatsAppConfig::appSecret();
        $expected = 'sha256=' . hash_hmac('sha256', $payload, $appSecret);
        return hash_equals($expected, $signature);
    }

    protected function processMessages(array $value): void
    {
        $contacts = $value['contacts'] ?? [];
        $messages = $value['messages'] ?? [];
        foreach ($messages as $msg) {
            $from = $msg['from'] ?? null;
            $type = $msg['type'] ?? 'text';

            $text = '';
            $listReplyId = null;
            $listReplyTitle = null;

            if ($type === 'text') {
                $text = $msg['text']['body'] ?? '';
            } elseif ($type === 'interactive') {
                $interactive = $msg['interactive'] ?? [];
                $interactiveType = $interactive['type'] ?? '';
                if ($interactiveType === 'list_reply') {
                    $listReplyId = $interactive['list_reply']['id'] ?? null;
                    $listReplyTitle = $interactive['list_reply']['title'] ?? null;
                    $text = $listReplyId ?? '';
                } elseif ($interactiveType === 'button_reply') {
                    $listReplyId = $interactive['button_reply']['id'] ?? null;
                    $text = $listReplyId ?? '';
                }
            }

            if (!$from) {
                continue;
            }

            $contactName = $this->resolveContactName($contacts, (string) $from);

            Log::info('WhatsApp message', [
                'from' => $from,
                'type' => $type,
                'text' => $text,
                'list_reply' => $listReplyId,
                'list_reply_title' => $listReplyTitle,
                'contact_name' => $contactName,
            ]);

            $conv = WhatsAppConversation::getOrCreate($from);

            $inboundBody = $text !== '' ? $text : ($listReplyTitle ?? $listReplyId ?? '');
            $inboundMeta = [
                'wa_type' => $type,
                'list_reply_id' => $listReplyId,
                'list_reply_title' => $listReplyTitle,
                'contact_name' => $contactName,
            ];
            WhatsAppMessageLogger::inbound(
                $from,
                $type === 'interactive' ? 'interactive' : 'text',
                $inboundBody,
                $inboundMeta
            );

            if ($conv->fresh()->human_takeover) {
                $digits = preg_replace('/\D/', '', (string) $from) ?? '';
                try {
                    app(WhatsAppConversationService::class)->notifyHumanModeInbound(
                        $digits,
                        $inboundBody,
                        $contactName
                    );
                } catch (\Throwable $e) {
                    Log::error('WhatsApp human_mode notify failed', [
                        'from' => $from,
                        'error' => $e->getMessage(),
                    ]);
                }

                continue;
            }

            try {
                app(WhatsAppConversationService::class)->handleMessage(
                    $from,
                    $text ?: 'hola',
                    $listReplyId,
                    $listReplyTitle,
                    $contactName
                );
            } catch (\Throwable $e) {
                Log::error('WhatsApp conversation error', [
                    'from' => $from,
                    'error' => $e->getMessage(),
                    'trace' => $e->getTraceAsString(),
                ]);
            }
        }
    }

    /**
     * Nombre público del perfil de WhatsApp (si Meta lo envía en el mismo payload).
     *
     * @param  array<int, array<string, mixed>>  $contacts
     */
    protected function resolveContactName(array $contacts, string $from): ?string
    {
        $fromDigits = preg_replace('/\D/', '', $from);
        if ($fromDigits === '') {
            return null;
        }
        foreach ($contacts as $c) {
            if (! is_array($c)) {
                continue;
            }
            $waId = isset($c['wa_id']) ? preg_replace('/\D/', '', (string) $c['wa_id']) : '';
            if ($waId === '' || $waId !== $fromDigits) {
                continue;
            }
            $name = $c['profile']['name'] ?? null;

            return is_string($name) && trim($name) !== '' ? trim($name) : null;
        }

        return null;
    }
}
