<?php

namespace App\Services;

use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\Order;
use App\Jobs\SendMetaCapiEvent;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class AnalyticsService
{
    /**
     * Build the user data array, hashing identifiable inputs for Meta security standards.
     */
    public static function getUserData(?Order $order = null): array
    {
        $userData = [
            'client_ip_address' => request()->ip(),
            'client_user_agent' => request()->header('User-Agent'),
        ];

        // Capture _fbp and _fbc cookies for deduplication (must not be hashed)
        if ($fbp = request()->cookie('_fbp')) {
            $userData['fbp'] = $fbp;
        }
        if ($fbc = request()->cookie('_fbc')) {
            $userData['fbc'] = $fbc;
        }

        // Capture details from the order if provided
        if ($order) {
            if ($order->customer_email) {
                $userData['em'] = [self::hashParam($order->customer_email)];
            }
            if ($order->customer_phone) {
                $userData['ph'] = [self::hashParam($order->customer_phone)];
            }
            $nameParts = explode(' ', trim($order->customer_name));
            if (count($nameParts) > 0) {
                $userData['fn'] = [self::hashParam($nameParts[0])];
                if (count($nameParts) > 1) {
                    $userData['ln'] = [self::hashParam(end($nameParts))];
                }
            }
        } elseif (Auth::check()) {
            $user = Auth::user();
            if ($user->email) {
                $userData['em'] = [self::hashParam($user->email)];
            }
            if (isset($user->phone) && $user->phone) {
                $userData['ph'] = [self::hashParam($user->phone)];
            }
            $nameParts = explode(' ', trim($user->name));
            if (count($nameParts) > 0) {
                $userData['fn'] = [self::hashParam($nameParts[0])];
                if (count($nameParts) > 1) {
                    $userData['ln'] = [self::hashParam(end($nameParts))];
                }
            }
        }

        // Return user data, filtering out null parameters
        return array_filter($userData);
    }

    /**
     * Helper to SHA256 hash parameter strings for Meta requirements.
     */
    private static function hashParam(?string $value): ?string
    {
        if (empty($value)) {
            return null;
        }
        return hash('sha256', strtolower(trim($value)));
    }

    /**
     * Track Product Details view (ViewContent / view_item).
     */
    public static function trackViewContent(Product $product, string $eventId): void
    {
        try {
            \App\Services\AnalyticsLoggingService::logEvent('view_item', $product->id);
        } catch (\Throwable $e) {
            Log::error('DB view_item logging failed: ' . $e->getMessage());
        }

        $price = $product->sale_price ?? $product->price;

        $customData = [
            'content_name' => $product->name,
            'content_ids' => [(string)$product->id],
            'content_type' => 'product',
            'value' => (float)$price,
            'currency' => 'BDT',
        ];

        SendMetaCapiEvent::dispatch(
            'ViewContent',
            $eventId,
            self::getUserData(),
            $customData,
            request()->fullUrl()
        );
    }

    /**
     * Track Add to Cart (AddToCart / add_to_cart).
     */
    public static function trackAddToCart(Product $product, ?ProductVariant $variant, int $quantity, string $eventId): void
    {
        try {
            \App\Services\AnalyticsLoggingService::logEvent('add_to_cart', $product->id);
        } catch (\Throwable $e) {
            Log::error('DB add_to_cart logging failed: ' . $e->getMessage());
        }

        $price = $variant && $variant->price !== null && floatval($variant->price) > 0 ? $variant->price : ($product->sale_price ?? $product->price);

        $customData = [
            'content_name' => $product->name,
            'content_ids' => [(string)$product->id],
            'content_type' => 'product',
            'value' => (float)($price * $quantity),
            'currency' => 'BDT',
        ];

        SendMetaCapiEvent::dispatch(
            'AddToCart',
            $eventId,
            self::getUserData(),
            $customData,
            request()->fullUrl()
        );
    }

    /**
     * Track Initiate Checkout (InitiateCheckout / begin_checkout).
     */
    public static function trackInitiateCheckout(array $cartItems, float $subtotal, string $eventId): void
    {
        try {
            \App\Services\AnalyticsLoggingService::logEvent('begin_checkout');
            foreach ($cartItems as $item) {
                if (isset($item['product_id'])) {
                    \App\Services\AnalyticsLoggingService::logEvent('begin_checkout', (int)$item['product_id']);
                }
            }
        } catch (\Throwable $e) {
            Log::error('DB begin_checkout logging failed: ' . $e->getMessage());
        }

        $contentIds = array_map(fn($item) => (string)$item['product_id'], $cartItems);

        $customData = [
            'content_ids' => $contentIds,
            'content_type' => 'product',
            'value' => (float)$subtotal,
            'currency' => 'BDT',
            'num_items' => count($cartItems),
        ];

        SendMetaCapiEvent::dispatch(
            'InitiateCheckout',
            $eventId,
            self::getUserData(),
            $customData,
            request()->fullUrl()
        );
    }

    /**
     * Track Purchase (Purchase / purchase).
     */
    public static function trackPurchase(Order $order, string $eventId): void
    {
        try {
            \App\Services\AnalyticsLoggingService::logEvent('purchase');
            foreach ($order->items as $item) {
                \App\Services\AnalyticsLoggingService::logEvent('purchase', $item->product_id);
            }
        } catch (\Throwable $e) {
            Log::error('DB purchase logging failed: ' . $e->getMessage());
        }

        $contentIds = $order->items->pluck('product_id')->map(fn($id) => (string)$id)->toArray();

        $customData = [
            'content_ids' => $contentIds,
            'content_type' => 'product',
            'value' => (float)$order->grand_total,
            'currency' => 'BDT',
            'num_items' => $order->items->sum('quantity'),
        ];

        SendMetaCapiEvent::dispatch(
            'Purchase',
            $eventId,
            self::getUserData($order),
            $customData,
            request()->fullUrl()
        );
    }

    /**
     * Track Category view (ViewContent / view_item_list).
     */
    public static function trackViewCategory(\App\Models\Category $category, string $eventId): void
    {
        $customData = [
            'content_name' => $category->name,
            'content_category' => $category->name,
            'content_ids' => [(string)$category->id],
            'content_type' => 'product_group',
        ];

        SendMetaCapiEvent::dispatch(
            'ViewContent',
            $eventId,
            self::getUserData(),
            $customData,
            request()->fullUrl()
        );
    }
}
