<?php

namespace App\Http\Middleware;

use App\Services\VisitorService;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cookie;
use Symfony\Component\HttpFoundation\Response;

class TrackVisitor
{
    public function __construct(private VisitorService $visitorService) {}

    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        // PRC-557 — Middleware route-level uygulanıyor (`->middleware(['track.visitor'])`).
        // Eski `isStoreRoute()` path-whitelist check'i kaldırıldı: PRC-554'te eklenen
        // TR slug'ları (urunler, sepet, alan-adi vb.) listede yoktu ve middleware
        // erken return yapıyordu → cookie set EDİLMİYORDU. Route'a atanmışsa zaten
        // store route'tur; defensive path check redundant + buggy.

        // Ziyaretçi ID'sini al veya oluştur
        $visitorId = $this->visitorService->getOrCreateVisitorId($request);

        // Visitor ID'yi request'e kaydet (diğer middleware'ler için)
        $request->attributes->set('visitor_id', $visitorId);

        // PRC-557 — İlk landing bilgisini kaydet (attribution).
        // Method idempotent: entry_at zaten varsa pas geçer. Dışarıda cookie-presence
        // check yapmıyoruz — cookie var ama Redis temiz (eviction/dev cleanup) durumunda
        // ilk request'i kaydetmek gerekir.
        $this->visitorService->setEntryInfo($visitorId, $request);

        // IP adresini kaydet
        $ipAddress = $request->ip();
        $this->visitorService->setIpAddress($visitorId, $ipAddress);

        // IP'den ülke bilgisini al ve kaydet
        $this->visitorService->setCountryFromIp($visitorId, $ipAddress);

        // Browser dil bilgisini al ve kaydet
        $browserLanguage = $this->visitorService->extractBrowserLanguage($request);
        if ($browserLanguage) {
            $this->visitorService->setBrowserLanguage($visitorId, $browserLanguage);
        }

        // Visitor için uygun dili belirle ve kaydet
        $determinedLanguage = $this->visitorService->determineVisitorLanguage($visitorId);
        $this->visitorService->setVisitorLanguage($visitorId, $determinedLanguage);

        // Ziyaretçi oluşturulma tarihini kaydet (sadece ilk kez)
        $this->visitorService->setCreatedAt($visitorId);

        // Affiliate ID'sini kontrol et ve kaydet
        $affiliateId = $this->visitorService->extractAffiliateId($request);
        if ($affiliateId) {
            $this->visitorService->setAffiliateId($visitorId, $affiliateId);
        }

        // Logged-in kullanıcı ile visitor'ı harmanla
        $clientId = Auth::guard('client')->check() ? Auth::guard('client')->id() : null;
        if ($clientId) {
            // Eğer kullanıcının başka bir visitor'ı varsa, sepetleri birleştir.
            // findVisitorByUserId, linkUserToVisitor index'i üzerine yazmadan
            // ÖNCE okunmalı (index hâlâ eski visitor'ı gösteriyor olmalı).
            $existingVisitorId = $this->visitorService->findVisitorByUserId($clientId);
            if ($existingVisitorId && $existingVisitorId !== $visitorId) {
                \App\Helpers\VisitorHelper::mergeVisitorBasket($existingVisitorId, $visitorId);
            }

            // Kullanıcı giriş yapmışsa visitor'a bağla
            $this->visitorService->linkUserToVisitor($visitorId, $clientId);

            // Kullanıcının currency bilgisini visitor_info'ya senkronize et
            $client = Auth::guard('client')->user();
            if ($client && $client->currency_id) {
                $clientCurrency = \App\Models\Currency::where('status', true)
                    ->where('id', $client->currency_id)
                    ->first();

                if ($clientCurrency) {
                    $this->visitorService->updateVisitorInfo($visitorId, [
                        'currency' => $clientCurrency->code,
                        'currencySetFrom' => 'user_login',
                        'currencySyncedAt' => now()->toISOString(),
                    ]);
                }
            }
        }

        // PRC-557 — Cookie HER response tipinde set edilsin (HTTP/Json/Redirect/...).
        // Cookie::queue() Laravel'in AddQueuedCookiesToResponse middleware'i üzerinden
        // tüm response tiplerine otomatik attach eder. Eski `$response->withCookie()`
        // sadece `\Illuminate\Http\Response`'da çalışıyordu → JsonResponse,
        // RedirectResponse, StreamedResponse'larda cookie set EDİLMİYORDU.
        Cookie::queue($this->visitorService->setVisitorCookie($visitorId));

        return $next($request);
    }
}
