<?php

namespace App\Services;

use App\Models\Client;
use App\Models\Country;
use App\Models\Currency;
use App\Models\Language;
use Illuminate\Support\Facades\Log;

class VisitorClientSyncService
{
    protected $visitorService;

    protected $discountManager;

    public function __construct(
        VisitorService $visitorService,
        DiscountManager $discountManager
    ) {
        $this->visitorService = $visitorService;
        $this->discountManager = $discountManager;
    }

    /**
     * Sync visitor cache with client data on login
     * Bu method login anında çağrılarak visitor cache'i client bilgileri ile günceller
     */
    public function syncVisitorWithClient(string $visitorId, Client $client): void
    {
        try {
            Log::info('Starting visitor-client sync', [
                'visitor_id' => $visitorId,
                'client_id' => $client->id,
            ]);

            // Client'a visitor'ı bağla
            $this->visitorService->linkUserToVisitor($visitorId, $client->id);

            // Client bilgilerini visitor cache'ine ekle/güncelle
            $syncData = $this->prepareClientDataForVisitor($client);
            $this->visitorService->updateVisitorDetails($visitorId, $syncData);

            // Client'in tüm indirimlerini visitor ile sync et
            $this->discountManager->syncAllDiscountsWithVisitor($client, $visitorId);

            Log::info('Visitor-client sync completed', [
                'visitor_id' => $visitorId,
                'client_id' => $client->id,
                'synced_data' => $syncData,
            ]);

        } catch (\Exception $e) {
            Log::error('Visitor-client sync failed', [
                'visitor_id' => $visitorId,
                'client_id' => $client->id,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * Sync client data with visitor cache for pricing calculations
     * Bu method client bilgileri değiştiğinde visitor cache'i günceller
     */
    public function syncClientWithVisitor(Client $client, ?string $visitorId = null): void
    {
        try {
            // Visitor ID'yi client'tan bul
            if (! $visitorId) {
                $visitorId = $this->visitorService->findVisitorByUserId($client->id);
            }

            if (! $visitorId) {
                Log::info('No active visitor found for client', ['client_id' => $client->id]);

                return;
            }

            // Client verilerini visitor cache'ine sync et
            $syncData = $this->prepareClientDataForVisitor($client);
            $this->visitorService->updateVisitorDetails($visitorId, $syncData);

            // Client'in tüm indirimlerini visitor ile sync et
            $this->discountManager->syncAllDiscountsWithVisitor($client, $visitorId);

            Log::info('Client-visitor sync completed', [
                'client_id' => $client->id,
                'visitor_id' => $visitorId,
                'synced_data' => $syncData,
            ]);

        } catch (\Exception $e) {
            Log::error('Client-visitor sync failed', [
                'client_id' => $client->id,
                'error' => $e->getMessage(),
            ]);
        }
    }

    /**
     * Prepare client data for visitor cache
     */
    protected function prepareClientDataForVisitor(Client $client): array
    {
        $data = [
            'client_id' => $client->id,
            'client_group_id' => $client->group_id,
            'sync_timestamp' => now()->toISOString(),
        ];

        // Country bilgisi
        if ($client->country_id) {
            $country = Country::find($client->country_id);
            if ($country) {
                $data['country'] = $country->name;
                $data['countryCode'] = $country->iso2;
                $data['client_country_id'] = $client->country_id;
            }
        }

        // Currency bilgisi
        if ($client->currency_id) {
            $currency = Currency::find($client->currency_id);
            if ($currency) {
                $data['currency'] = $currency->code;
                $data['client_currency_id'] = $client->currency_id;
                $data['determined_currency'] = $currency->code;
            }
        }

        // Language bilgisi
        if ($client->language_id) {
            $language = Language::find($client->language_id);
            if ($language) {
                $data['language'] = $language->a2_iso;
                $data['client_language_id'] = $client->language_id;
                $data['determined_language'] = $language->a2_iso;
            }
        }

        // Client specific fields for pricing
        $data['tax_exempt'] = $client->tax_exempt;
        $data['client_type'] = $client->type ?? 'individual';

        return $data;
    }

    /**
     * Get visitor data for pricing calculations
     */
    public function getVisitorDataForPricing(string $visitorId): array
    {
        $visitorDetails = $this->visitorService->getVisitorDetails($visitorId);

        return [
            'client_id' => $visitorDetails['client_id'] ?? null,
            'client_group_id' => $visitorDetails['client_group_id'] ?? null,
            'country_id' => $visitorDetails['client_country_id'] ?? null,
            'currency_id' => $visitorDetails['client_currency_id'] ?? null,
            'language_id' => $visitorDetails['client_language_id'] ?? null,
            'country_code' => $visitorDetails['countryCode'] ?? null,
            'currency_code' => $visitorDetails['currency'] ?? null,
            'language_code' => $visitorDetails['language'] ?? null,
            'tax_exempt' => $visitorDetails['tax_exempt'] ?? false,
            'client_type' => $visitorDetails['client_type'] ?? 'individual',
        ];
    }

    /**
     * Check if visitor has valid pricing context
     */
    public function hasValidPricingContext(string $visitorId): bool
    {
        $data = $this->getVisitorDataForPricing($visitorId);

        return ! empty($data['country_code']) && ! empty($data['currency_code']);
    }
}
