<?php

namespace App\Services\Site;

use App\Models\Customer\Customer;
use App\Models\Site\SiteVisitor;
use Illuminate\Support\Str;

/**
 * Canlı destek ziyaretçisini telefon/e-posta üzerinden mevcut müşteri
 * kaydıyla eşleştirir; eşleşme yoksa personel sohbet ekranından tek tıkla
 * müşteri kaydı oluşturabilir.
 */
class VisitorCustomerMatcher
{
    /** Ziyaretçiyi mevcut müşteriyle eşleştirmeyi dener; bulursa bağlar. */
    public function match(SiteVisitor $visitor): ?Customer
    {
        $customer = $this->findByPhone($visitor) ?? $this->findByEmail($visitor);

        if ($customer) {
            $visitor->forceFill(['customer_id' => $customer->id])->save();
        }

        return $customer;
    }

    /** Ziyaretçi bilgilerinden yeni müşteri kaydı oluşturur (idempotent). */
    public function createCustomer(SiteVisitor $visitor): Customer
    {
        if ($visitor->customer_id && $visitor->customer) {
            return $visitor->customer;
        }

        // Son bir kez eşleştirmeyi dene (yarış durumuna karşı)
        if ($existing = $this->match($visitor)) {
            return $existing;
        }

        $fullName = trim((string) $visitor->name) ?: 'Web Ziyaretçisi';
        $parts = preg_split('/\s+/', $fullName) ?: ['Ziyaretçi'];
        $lastName = count($parts) > 1 ? array_pop($parts) : '-';

        $customer = Customer::create([
            'agency_id' => $visitor->agency_id,
            'first_name' => implode(' ', $parts),
            'last_name' => $lastName,
            'phone' => $visitor->phone,
            'emails' => $visitor->email ? [$visitor->email] : null,
            'customer_type' => 'individual',
            'status' => 'potential',
        ]);

        $visitor->forceFill(['customer_id' => $customer->id])->save();

        return $customer;
    }

    protected function findByPhone(SiteVisitor $visitor): ?Customer
    {
        $digits = $this->normalizePhone($visitor->phone);
        if ($digits === null) {
            return null;
        }

        // Ülke kodu/format farklarını tolere etmek için son 10 hane ile ara
        $needle = '%' . $digits;

        return Customer::where('agency_id', $visitor->agency_id)
            ->where(function ($query) use ($needle, $digits) {
                $query->whereRaw("REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(phone,''),' ',''),'-',''),'(',''),')','') LIKE ?", [$needle])
                    ->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(phone_alt,''),' ',''),'-',''),'(',''),')','') LIKE ?", [$needle]);
            })
            ->first();
    }

    protected function findByEmail(SiteVisitor $visitor): ?Customer
    {
        $email = Str::lower(trim((string) $visitor->email));
        if ($email === '') {
            return null;
        }

        return Customer::where('agency_id', $visitor->agency_id)
            ->where(function ($query) use ($email) {
                $query->whereRaw('LOWER(COALESCE(email_alt, "")) = ?', [$email])
                    ->orWhereRaw('LOWER(COALESCE(emails, "")) LIKE ?', ['%"' . $email . '"%']);
            })
            ->first();
    }

    /** Telefonu karşılaştırılabilir son 10 haneye indirger. */
    protected function normalizePhone(?string $phone): ?string
    {
        $digits = preg_replace('/\D+/', '', (string) $phone);
        if (strlen($digits) < 7) {
            return null;
        }

        return substr($digits, -10);
    }
}
