<?php

namespace App\Http\Controllers;

use App\Events\Purchase;
use App\Models\User;
use Esign\ConversionsApi\Facades\ConversionsApi;
use FacebookAds\Object\ServerSide\CustomData;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;

class HotmartController extends Controller
{
    public function Hotmart(Request $request)
    {
        try {
            Log::info('Recebendo Payload:', $request->all());

            $json = $request->input('data');
            $first_name = strtolower($json['buyer']['first_name'] ?? '');
            $last_name = strtolower($json['buyer']['last_name'] ?? '');
            $email = strtolower($json['buyer']['email'] ?? '');
            $phone = preg_replace('/\D/', '', $json['buyer']['checkout_phone'] ?? '');
            $utmSource = $json['purchase']['origin']['xcod'] ?? '';
            $parts = explode('|', $utmSource);
            $origin = '';
            foreach ($parts as $part) {
                if (strpos($part, 'userId') === 0) { 
                    $origin = str_replace('userId', '', $part);
                    break;
                }
            }
            $currency = $json['purchase']['price']['currency_value'] ?? $json['purchase']['full_price']['currency_value'] ?? 'BRL';
            $price = (float) (
                $json['purchase']['price']['value'] ?? $json['purchase']['full_price']['value']
                    ?? 0
            );

            $user = User::where('external_id', $origin)->first();
            if (!$user) {
                return response()->json(['message' => 'O usuário não tem origem.']);
            }

            // // 1. Tenta encontrar pelo external_id
            // $user = User::where('external_id', $origin)->first();

            // // 2. Se não encontrou, tenta pelo telefone
            // if (!$user && !empty($phone)) {
            //     $user = User::where('phone', $phone)->first();
            // }

            // // 3. Se ainda não encontrou, tenta pelo email
            // if (!$user && !empty($email)) {
            //     $user = User::where('email', $email)->first();
            // }

            if ($user) {
                $user->update([
                    'first_name' => $first_name,
                    'last_name' => $last_name,
                    'email' => $email,
                    'phone' => $phone,
                ]);
            } else {
                $user = User::create([
                    'first_name' => $first_name,
                    'last_name' => $last_name,
                    'email' => $email,
                    'phone' => $phone,
                ]);
            }

            $contentId = $user->content_id ?? '';
            $external_id = $origin ?? '';
            $client_ip_address = $user->client_ip_address ?? '';
            $client_user_agent = $user->client_user_agent ?? '';
            $fbp = $user->fbp ?? '';
            $fbc = $user->fbc ?? '';
            $country = $user->country ?? '';
            $state = $user->state ?? '';
            $city = $user->city ?? '';
            $postal_code = $user->postal_code ?? '';
            $first_name = $user->first_name ?? '';
            $last_name = $user->last_name ?? '';
            $email = $user->email ?? '';
            $phone = $user->phone ?? '';
            $URL = $user->url ?? '';

            $products = config('pixel.products');
            $map = config('URLs.map');
            if ($URL !== '') {
                $parsed = parse_url($URL);
                $scheme = $parsed['scheme'] ?? 'https';
                $host   = strtolower($parsed['host'] ?? '');
                $path   = isset($parsed['path']) ? rtrim($parsed['path'], '/') : '';
                $base   = "{$scheme}://{$host}{$path}";
                if ($host && (isset($map[$base]) || isset($map[$host.$path]) || isset($map[$host]))) {
                    $URL = $this->mapBlackToWhite($URL, $map);
                }
            }
            
            if (!isset($products[$contentId])) {
                Log::info('[ERROR][EVENTS] O nome do Pixel no Header deve ser o mesmo do arquivo Pixel.php: ' . $contentId);
                return response()->json(['error' => 'O nome do Pixel no Header deve ser o mesmo do arquivo Pixel.php'], 400);
            }
            
            $productConfig = $products[$contentId];
            foreach ($productConfig['pixel_id'] as $index => $pixelId) {
                $accessToken = $productConfig['access_token'][$index] ?? null;
                $testCode = $productConfig['test_code'][$index] ?? null;
                
                Config::set('conversions-api.pixel_id', $pixelId);
                Config::set('conversions-api.access_token', $accessToken);
                Config::set('conversions-api.test_code', $testCode);

                // Log::info('Dados do Pixel', [
                //     'pixel_id' => $pixelId,
                //     'access_token' => $accessToken,
                //     'test_code' => $testCode,
                // ]);

                ConversionsApi::clearEvents();

                $event = Purchase::create();
                $event->setEventSourceUrl($URL);
                $advancedMatching = $event->getUserData()
                    ->setExternalId($external_id)
                    ->setClientIpAddress($client_ip_address)
                    ->setClientUserAgent($client_user_agent)
                    ->setFbp($fbp)
                    ->setFbc($fbc)
                    ->setCountryCode($country)
                    ->setState($state)
                    ->setCity($city)
                    ->setZipCode($postal_code)
                    ->setFirstName($first_name)
                    ->setLastName($last_name)
                    ->setEmail($email)
                    ->setPhone($phone);
                $event->setUserData($advancedMatching);
                // $event->setCustomData((new CustomData())->setContentIds([$contentId])->setCurrency($currency)->setValue($price));

                $customData = new CustomData();
                $customData->setContentIds([$contentId]);
                if (!is_null($price)) {
                    $customData->setValue($price)->setCurrency($currency);
                }
                $event->setCustomData($customData);

                $batch = ConversionsApi::addEvent($event)->sendEvents();
                $response = $batch->wait();

                // Log::info('Facebook Response:', [
                //     'status' => $response->getStatusCode(),
                //     'body' => json_decode($response->getBody()->getContents(), true)
                // ]);
            }

            if (env('LOG_DEBUG') === true) {
                $log = [
                    'event_id' => $event->getEventId(),
                    'event_name' => $event->getEventName(),
                    'event_time' => $event->getEventTime(),
                    'event_source_url' => urldecode($event->getEventSourceUrl()),
                ];
                
                if ($event->getCustomData()->getValue()) {
                    $log['custom_data'] = [
                        'value' => $event->getCustomData()->getValue(),
                        'currency' => $event->getCustomData()->getCurrency(),
                    ];
                }
                
                $log['user_data'] = [
                    'client_user_agent' => $event->getUserData()->getClientUserAgent(),
                    'client_ip_address' => $event->getUserData()->getClientIpAddress(),
                    'fbc' => $event->getUserData()->getFbc(),
                    'fbp' => $event->getUserData()->getFbp(),
                    'external_id' => $event->getUserData()->getExternalId(),
                    'country' => $event->getUserData()->getCountryCode(),
                    'state' => $event->getUserData()->getState(),
                    'city' => $event->getUserData()->getCity(),
                    'postal_code' => $event->getUserData()->getZipCode(),
                    'first_name' => $event->getUserData()->getFirstName(),
                    'last_name' => $event->getUserData()->getLastName(),
                    'email' => $event->getUserData()->getEmail(),
                    'phone' => $event->getUserData()->getPhone(),
                ];

                Log::channel('Events')->info(json_encode($log, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
            }
            
            return response()->json(['message' => 'Webhook processado com sucesso']);
        } catch (\Exception $e) {
            Log::error('Erro ao enviar evento.', [
                'exception' => [ 'message' => $e->getMessage(), 'line' => $e->getLine() ],
                'request' => $request->all()
            ]);
            
            return response()->json(['error' => 'Erro interno no servidor'], 500);
        }
    }

    function mapBlackToWhite(string $incomingUrl, array $map): string
    {
        // Parse da URL recebida (black)
        $black = parse_url($incomingUrl);

        // Normaliza base (scheme://host/path) para comparar
        $blackScheme = $black['scheme'] ?? 'https';
        $blackHost   = strtolower($black['host'] ?? '');
        $blackPath   = isset($black['path']) ? rtrim($black['path'], '/') : '';
        $blackBase   = "{$blackScheme}://{$blackHost}{$blackPath}";

        // Também tentar variações de base (sem scheme) caso seu array use apenas host+path
        $blackKeyNoScheme = "{$blackHost}{$blackPath}";

        // Query original (UTMs etc.)
        $blackQueryStr = $black['query'] ?? '';
        parse_str($blackQueryStr, $blackQuery);

        // Descobre destino white no mapa
        $whiteBase = $map[$blackBase]
            ?? $map[$blackKeyNoScheme]
            ?? $map[$blackHost]              // fallback: só host
            ?? null;

        // Se não achou no mapa, retorna a própria URL original
        if (!$whiteBase) {
            return $incomingUrl;
        }

        // Parse da white base (pode ter path e até query)
        $white = parse_url($whiteBase);
        $whiteScheme = $white['scheme'] ?? 'https';
        $whiteHost   = strtolower($white['host'] ?? '');
        $whitePath   = $white['path'] ?? '';
        $whiteQueryStr = $white['query'] ?? '';
        parse_str($whiteQueryStr, $whiteQuery);

        // Merge dos parâmetros (black sobrepõe white)
        $mergedQuery = array_merge($whiteQuery, $blackQuery);
        $finalQueryStr = http_build_query($mergedQuery);

        // Preserva fragment da black, se houver (opcional)
        $fragment = isset($black['fragment']) ? '#'.$black['fragment'] : '';

        // Reconstrói URL final white + UTMs
        $final =
            $whiteScheme.'://'.
            $whiteHost.
            $whitePath.
            ($finalQueryStr ? '?'.$finalQueryStr : '').
            $fragment;

        return $final;
    }
}
