<?php

namespace App\Http\Controllers\Agency\Customer;

use App\Http\Controllers\Controller;
use App\Models\Customer\Customer;
use App\Models\Customer\CustomerActivity;
use App\Models\Customer\CustomerFieldDefinition;
use App\Models\Customer\CustomerFieldValue;
use App\Models\Customer\CustomerDocumentType;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class CustomerController extends Controller
{
     use AuthorizesRequests;

     // ─── INDEX ────────────────────────────────────────────────────────────────

     public function index(Request $request)
     {
          $query = Customer::with(['assignedAgent'])
               ->withCount('passengers')
               ->byAgency(Auth::user()->currentAgencyId());

          // -- Özel Alan Filterable Tanımları
          $agencyId = Auth::user()->currentAgencyId();
          $filterableFields = CustomerFieldDefinition::byAgency($agencyId)->active()->where('is_filterable', true)->get();
          $listableFields = CustomerFieldDefinition::byAgency($agencyId)->active()->where('is_visible_in_list', true)->get();

          // -- Arama (Standart + Özel Alanlar) — Türkçe karaktere/büyük-küçük harfe duyarsız
          if ($request->filled('search')) {
               $searchableFieldsIds = CustomerFieldDefinition::byAgency($agencyId)
                    ->active()
                    ->where('is_searchable', true)
                    ->pluck('id');

               $haystack = $this->trNormalizedSql("CONCAT_WS(' ', first_name, last_name, company_name, national_id, phone, emails)");
               $valueNorm = $this->trNormalizedSql('value');
               $tokens = $this->searchTokens($request->search);

               $query->where(function ($q) use ($tokens, $haystack, $valueNorm, $searchableFieldsIds) {
                    foreach ($tokens as $token) {
                         $escaped = addcslashes($token, '\\%_');
                         $q->where(function ($qq) use ($haystack, $valueNorm, $escaped, $searchableFieldsIds) {
                              $qq->whereRaw("{$haystack} LIKE ?", ["%{$escaped}%"])
                                   ->orWhereHas('customFieldValues', function ($sq) use ($valueNorm, $escaped, $searchableFieldsIds) {
                                        $sq->whereIn('field_definition_id', $searchableFieldsIds)
                                             ->whereRaw("{$valueNorm} LIKE ?", ["%{$escaped}%"]);
                                   });
                         });
                    }
               });
          }

          // -- Standart Filtreler
          if ($request->filled('status')) {
               $query->where('status', $request->status);
          }
          if ($request->filled('type')) {
               $query->where('customer_type', $request->type);
          }
          if ($request->filled('priority')) {
               $query->where('priority', $request->priority);
          }
          if ($request->filled('segment')) {
               $query->where('customer_segment', $request->segment);
          }

          // -- Özel Alan Filtreleri
          foreach ($filterableFields as $field) {
               $paramName = 'cf_' . $field->field_key;
               if ($request->filled($paramName)) {
                    $val = $request->get($paramName);
                    $query->whereHas('customFieldValues', function ($sq) use ($field, $val) {
                         $sq->where('field_definition_id', $field->id);
                         if ($field->field_type === 'multiselect') {
                              $sq->where('value', 'like', '%"' . $val . '"%');
                         } else {
                              $sq->where('value', $val);
                         }
                    });
               }
          }

          if ($request->boolean('blacklisted')) {
               $query->blacklisted();
          }

          // -- Sıralama
          $allowedSorts = ['first_name', 'company_name', 'customer_type', 'status', 'priority', 'loyalty_tier', 'created_at'];
          $sortBy = in_array($request->get('sort'), $allowedSorts, true) ? $request->get('sort') : 'created_at';
          $sortDir = $request->get('dir') === 'asc' ? 'asc' : 'desc';
          $query->orderBy($sortBy, $sortDir);

          // -- Sayfalama (özel alan değerleriyle birlikte yüklenir)
          $perPage = (int) $request->input('per_page', 20);
          $perPage = in_array($perPage, [20, 50, 100, 200], true) ? $perPage : 20;
          $customers = $query->with(['customFieldValues.fieldDefinition'])->paginate($perPage)->withQueryString();

          return view('agency.customers.index', compact('customers', 'filterableFields', 'listableFields'));
     }

     // ─── CREATE / STORE ───────────────────────────────────────────────────────

     public function create()
     {
          $agencyId = Auth::user()->currentAgencyId();
          $agents = \App\Models\User::byAgency($agencyId)
               ->active()
               ->orderBy('first_name')
               ->get();

          $definitions = CustomerFieldDefinition::byAgency($agencyId)
               ->active()
               ->orderBy('sort_order')
               ->get();

          // Şirketler artık customer_type = corporate olan müşteri kartlarıdır
          $companies = Customer::byAgency($agencyId)
               ->corporate()
               ->orderBy('company_name')
               ->get();

          return view('agency.customers.create', compact('agents', 'definitions', 'companies'));
     }

     public function store(Request $request)
     {
          $agencyId = Auth::user()->currentAgencyId();
          $requiredFields = CustomerFieldDefinition::byAgency($agencyId)->active()->where('is_required', true)->get();

          $isCorporate = $request->customer_type === 'corporate';

          $rules = [
               // Bağlı şirketler (sadece kişi/individual için) — corporate müşteri kartlarının id'leri
               'company_ids' => 'nullable|array',
               'company_ids.*' => 'integer|exists:customers,id',
               'first_name' => ($isCorporate ? 'nullable' : 'required') . '|string|max:100',
               'last_name' => ($isCorporate ? 'nullable' : 'required') . '|string|max:100',
               'emails' => 'nullable|array',
               'emails.*' => 'nullable|email|max:255',
               'phone' => 'nullable|string|max:20',
               'phone_alt' => 'nullable|string|max:20',
               'birth_date' => 'nullable|date',
               'gender' => 'nullable|in:male,female,other',
               'national_id' => 'nullable|string|max:20',
               'passport_number' => 'nullable|string|max:20',
               'passport_expiry' => 'nullable|date',
               'nationality' => 'nullable|string|size:2',
               'address' => 'nullable|string',
               'city' => 'nullable|string|max:100',
               'district' => 'nullable|string|max:100',
               'country' => 'nullable|string|size:2',
               'postal_code' => 'nullable|string|max:10',
               'customer_type' => 'required|in:individual,corporate',
               'status' => 'required|in:active,inactive,blocked,potential',
               'priority' => 'boolean',
               'company_name' => ($isCorporate ? 'required' : 'nullable') . '|string|max:255',
               'company_type' => 'nullable|string|max:100',
               'company_tax_number' => 'nullable|string|max:50',
               'company_tax_office' => 'nullable|string|max:100',
               'company_position' => 'nullable|string|max:100',
               'preferred_contact_method' => 'nullable|string|in:email,phone,sms',
               'email_marketing' => 'boolean',
               'sms_marketing' => 'boolean',
               'assigned_agent_id' => 'nullable|exists:users,id',
               'credit_limit' => 'nullable|numeric|min:0',
               'payment_term_days' => 'nullable|integer|min:0',
               'default_discount_rate' => 'nullable|numeric|min:0|max:100',
               'referral_source' => 'nullable|string|max:100',
               'internal_notes' => 'nullable|string',

               // Fatura Bilgileri
               'billing_address' => 'required|string',
               'billing_city' => 'nullable|string|max:100',
               'billing_district' => 'nullable|string|max:100',
               'billing_tax_number' => $request->customer_type === 'individual' ? 'required|digits:11' : 'required|digits:10',
               'billing_tax_office' => $request->customer_type === 'corporate' ? 'required|string|max:100' : 'nullable|string|max:100',
               'billing_email' => 'required|email|max:255',
          ];

          // Dinamik Zorunlu Alanlar (EAV için)
          $customAttributes = [
               'billing_address' => 'Fatura Adresi',
               'billing_email' => 'Fatura E-posta Adresi',
               'billing_tax_number' => $request->customer_type === 'individual' ? 'T.C. Kimlik Numarası' : 'Vergi Numarası',
               'billing_tax_office' => 'Fatura Vergi Dairesi',
          ];
          foreach ($requiredFields as $field) {
               $rules['custom_fields.' . $field->id] = 'required';
               $customAttributes['custom_fields.' . $field->id] = $field->label;
          }

          try {
               $validated = $request->validate($rules, [], $customAttributes);
               $validated['agency_id'] = $agencyId;

               // Tags ve Interests'i array'e dönüştür (eğer string olarak geldiyse)
               if (isset($validated['tags']) && is_string($validated['tags'])) {
                    $validated['tags'] = array_filter(array_map('trim', explode(',', $validated['tags'])));
               }
               if (isset($validated['interests']) && is_string($validated['interests'])) {
                    $validated['interests'] = array_filter(array_map('trim', explode(',', $validated['interests'])));
               }

               DB::beginTransaction();

               // Ana Müşteri Kaydı (company_ids pivot ilişkisi için ana kayıttan ayrılır)
               $customer = Customer::create(collect($validated)->except(['custom_fields', 'company_ids'])->toArray());

               // Kişi (individual) ise bağlı olduğu şirketleri pivot tabloya senkronla
               if (!$isCorporate) {
                    $customer->companies()->sync($this->resolveCompanyIds($request->input('company_ids', []), $agencyId));
               }

               // Özel Alan Değerlerini Kaydet
               if ($request->has('custom_fields')) {
                    foreach ($request->custom_fields as $defId => $value) {
                         if ($value !== null && $value !== '') {
                              // multiselect ise JSON sakla
                              if (is_array($value)) {
                                   $value = json_encode(array_values($value));
                              }
                              CustomerFieldValue::setValue($customer->id, (int) $defId, $value);
                         }
                    }
               }

               DB::commit();

               return redirect()
                    ->route('agency.customers.show', $customer)
                    ->with('success', 'Müşteri başarıyla oluşturuldu.');

          } catch (\Illuminate\Validation\ValidationException $e) {
               Log::warning('Müşteri oluşturma validasyon hatası', [
                    'errors' => $e->errors(),
                    'input' => $request->except(['password', 'password_confirmation'])
               ]);
               throw $e;
          } catch (\Exception $e) {
               DB::rollBack();
               Log::error('Müşteri oluşturulurken hata meydana geldi: ' . $e->getMessage(), [
                    'exception' => $e,
                    'input' => $request->all()
               ]);
               return back()
                    ->withInput()
                    ->with('error', 'Hata: ' . $e->getMessage());
          }
     }

     // ─── SHOW ─────────────────────────────────────────────────────────────────

     public function show(Customer $customer)
     {
          $this->authorizeAgency($customer);
          return redirect()->route('agency.customers.index', ['open_customer_id' => $customer->id]);
     }

     // ─── EDIT / UPDATE ────────────────────────────────────────────────────────

     public function edit(Customer $customer)
     {
          $this->authorizeAgency($customer);
          return redirect()->route('agency.customers.index', ['open_customer_id' => $customer->id, 'tab' => 'details']);
     }

     public function update(Request $request, Customer $customer)
     {
          $this->authorizeAgency($customer);

          $agencyId = Auth::user()->currentAgencyId();
          $requiredFields = CustomerFieldDefinition::byAgency($agencyId)->active()->where('is_required', true)->get();

          $isCorporate = $request->customer_type === 'corporate';

          $rules = [
               // Bağlı şirketler (sadece kişi/individual için)
               'company_ids' => 'nullable|array',
               'company_ids.*' => 'integer|exists:customers,id',
               // Kişisel
               'first_name' => ($isCorporate ? 'nullable' : 'required') . '|string|max:100',
               'last_name' => ($isCorporate ? 'nullable' : 'required') . '|string|max:100',
               'emails' => 'nullable|array',
               'emails.*' => 'nullable|email|max:255',
               'phone' => 'nullable|string|max:20',
               'phone_alt' => 'nullable|string|max:20',
               'birth_date' => 'nullable|date',
               'gender' => 'nullable|in:male,female,other',
               'national_id' => 'nullable|string|max:20',
               'passport_number' => 'nullable|string|max:20',
               'passport_expiry' => 'nullable|date',
               'nationality' => 'nullable|string|max:10',

               // Adres
               'address' => 'nullable|string',
               'city' => 'nullable|string|max:100',
               'district' => 'nullable|string|max:100',
               'country' => 'nullable|string|max:10',
               'postal_code' => 'nullable|string|max:10',

               // Tip & Durum
               'customer_type' => 'required|in:individual,corporate',
               'status' => 'required|in:active,inactive,blocked,potential',
               'priority' => 'boolean',

               // Kurumsal
               'company_name' => ($isCorporate ? 'required' : 'nullable') . '|string|max:255',
               'company_type' => 'nullable|string|max:100',
               'company_tax_number' => 'nullable|string|max:50',
               'company_tax_office' => 'nullable|string|max:100',
               'company_position' => 'nullable|string|max:100',

               // Fatura
               'billing_address' => 'required|string',
               'billing_city' => 'nullable|string|max:100',
               'billing_district' => 'nullable|string|max:100',
               'billing_tax_number' => $request->customer_type === 'individual' ? 'required|digits:11' : 'required|digits:10',
               'billing_tax_office' => $request->customer_type === 'corporate' ? 'required|string|max:100' : 'nullable|string|max:100',
               'billing_email' => 'required|email|max:255',

               // İletişim
               'preferred_contact_method' => 'nullable|string|in:email,phone,sms',
               'email_marketing' => 'boolean',
               'sms_marketing' => 'boolean',

               // Atama
               'assigned_agent_id' => 'nullable|exists:users,id',

               // Finansal
               'credit_limit' => 'nullable|numeric|min:0',
               'payment_term_days' => 'nullable|integer|min:0',
               'default_discount_rate' => 'nullable|numeric|min:0|max:100',

               // Diğer
               'referral_source' => 'nullable|string|max:100',
               'internal_notes' => 'nullable|string',
          ];

          // Dinamik Zorunlu Alanlar (EAV için)
          $customAttributes = [
               'billing_address' => 'Fatura Adresi',
               'billing_email' => 'Fatura E-posta Adresi',
               'billing_tax_number' => $request->customer_type === 'individual' ? 'T.C. Kimlik Numarası' : 'Vergi Numarası',
               'billing_tax_office' => 'Fatura Vergi Dairesi',
          ];
          foreach ($requiredFields as $field) {
               $rules['custom_fields.' . $field->id] = 'required';
               $customAttributes['custom_fields.' . $field->id] = $field->label;
          }

          $validated = $request->validate($rules, [], $customAttributes);

          DB::beginTransaction();
          try {
               $customer->update(collect($validated)->except(['custom_fields', 'company_ids'])->toArray());

               // Bağlı şirketleri senkronla: kişi ise pivot güncellenir, şirkete dönüştürüldüyse temizlenir
               if (!$isCorporate) {
                    $customer->companies()->sync($this->resolveCompanyIds($request->input('company_ids', []), $agencyId));
               } else {
                    $customer->companies()->detach();
               }

               if ($request->has('custom_fields')) {
                    foreach ($request->custom_fields as $defId => $value) {
                         if ($value !== null && $value !== '') {
                              if (is_array($value)) {
                                   $value = json_encode(array_values($value));
                              }
                              CustomerFieldValue::setValue($customer->id, (int) $defId, $value);
                         } else {
                              CustomerFieldValue::where('customer_id', $customer->id)
                                   ->where('field_definition_id', $defId)
                                   ->delete();
                         }
                    }
               }

               DB::commit();
               return back()->with('success', 'Müşteri bilgileri başarıyla güncellendi.');
          } catch (\Exception $e) {
               DB::rollBack();
               return back()->with('error', 'Güncelleme sırasında hata oluştu: ' . $e->getMessage());
          }
     }

     // ─── DELETE ───────────────────────────────────────────────────────────────

     public function destroy(Customer $customer)
     {
          $this->authorizeAgency($customer);

          DB::beginTransaction();
          try {
               $customer->activities()->delete();
               $customer->delete();
               DB::commit();
          } catch (\Exception $e) {
               DB::rollBack();
               return back()->with('error', 'Müşteri silinirken bir hata oluştu.');
          }

          return redirect()
               ->route('agency.customers.index')
               ->with('success', 'Müşteri başarıyla silindi.');
     }

     // ─── QUICK ACTIONS ────────────────────────────────────────────────────────

     public function toggleStatus(Customer $customer)
     {
          $this->authorizeAgency($customer);

          $newStatus = $customer->status === 'active' ? 'inactive' : 'active';
          $customer->update(['status' => $newStatus]);

          return response()->json([
               'success' => true,
               'status' => $newStatus,
               'label' => $customer->fresh()->status_label,
               'message' => $newStatus === 'active' ? 'Müşteri aktif edildi.' : 'Müşteri pasif edildi.',
          ]);
     }

     public function toggleBlacklist(Request $request, Customer $customer)
     {
          $this->authorizeAgency($customer);

          if ($customer->blacklisted) {
               $customer->update([
                    'blacklisted' => false,
                    'blacklist_reason' => null,
                    'blacklisted_at' => null,
                    'blacklisted_by' => null,
                    'status' => 'active',
               ]);
               $message = 'Müşteri kara listeden çıkarıldı.';
          } else {
               $request->validate([
                    'blacklist_reason' => 'required|string|max:500',
               ]);

               $customer->update([
                    'blacklisted' => true,
                    'blacklist_reason' => $request->blacklist_reason,
                    'blacklisted_at' => now(),
                    'blacklisted_by' => Auth::id(),
                    'status' => 'blocked',
               ]);
               $message = 'Müşteri kara listeye alındı.';
          }

          return back()->with('success', $message);
     }

     public function updateLoyaltyPoints(Request $request, Customer $customer)
     {
          $this->authorizeAgency($customer);

          $request->validate([
               'points' => 'required|integer|min:1',
               'operation' => 'required|in:add,deduct',
               'note' => 'nullable|string|max:255',
          ]);

          if ($request->operation === 'add') {
               $customer->addLoyaltyPoints($request->points);
               $message = "{$request->points} puan eklendi.";
          } else {
               $customer->deductLoyaltyPoints($request->points);
               $message = "{$request->points} puan düşüldü.";
          }

          return back()->with('success', $message);
     }

     public function assignAgent(Request $request, Customer $customer)
     {
          $this->authorizeAgency($customer);

          $request->validate([
               'agent_id' => 'nullable|exists:users,id',
          ]);

          $customer->update(['assigned_agent_id' => $request->agent_id]);

          return response()->json([
               'success' => true,
               'message' => $request->agent_id ? 'Temsilci atandı.' : 'Temsilci ataması kaldırıldı.',
          ]);
     }

     public function bulkDelete(Request $request)
     {
          $request->validate([
               'ids' => 'required|array',
               'ids.*' => 'integer|exists:customers,id',
          ]);

          $agencyId = Auth::user()->currentAgencyId();

          DB::beginTransaction();
          try {
               $customers = Customer::byAgency($agencyId)
                    ->whereIn('id', $request->ids)
                    ->get();

               foreach ($customers as $customer) {
                    $customer->activities()->delete();
                    $customer->delete();
               }

               DB::commit();
          } catch (\Exception $e) {
               DB::rollBack();
               return response()->json(['success' => false, 'message' => 'Silme sırasında hata oluştu.'], 500);
          }

          return response()->json([
               'success' => true,
               'message' => count($request->ids) . ' müşteri silindi.',
          ]);
     }

     public function bulkStatus(Request $request)
     {
          $request->validate([
               'ids' => 'required|array',
               'ids.*' => 'integer|exists:customers,id',
               'status' => 'required|in:active,inactive,blocked,potential',
          ]);

          Customer::byAgency(Auth::user()->currentAgencyId())
               ->whereIn('id', $request->ids)
               ->update(['status' => $request->status]);

          return response()->json([
               'success' => true,
               'message' => count($request->ids) . ' müşterinin durumu güncellendi.',
          ]);
     }

     /** SQL ifadesini Türkçe karaktere ve büyük/küçük harfe duyarsız hale getirir. */
     private function trNormalizedSql(string $expr): string
     {
          return \App\Support\TurkishSearch::normalizedSql($expr);
     }

     /** Aranan metni aynı normalizasyonla kelimelere böler. */
     private function searchTokens(string $term): array
     {
          return \App\Support\TurkishSearch::tokens($term);
     }

     public function search(Request $request)
     {
          $agencyId = Auth::user()->currentAgencyId();

          // Ad, soyad, firma, TC/pasaport no, telefon ve e-posta tek metinde aranır
          $haystack = $this->trNormalizedSql("CONCAT_WS(' ', first_name, last_name, company_name, national_id, phone, emails)");
          $tokens = $this->searchTokens((string) $request->get('q', ''));

          $customers = Customer::byAgency($agencyId)
               ->where(function ($q) use ($tokens, $haystack) {
                    foreach ($tokens as $token) {
                         $escaped = addcslashes($token, '\\%_');
                         $q->whereRaw("{$haystack} LIKE ?", ["%{$escaped}%"]);
                    }
               })
               ->active()
               ->limit(20)
               ->get(['id', 'first_name', 'last_name', 'company_name', 'emails', 'phone', 'national_id', 'customer_type'])
               ->map(function ($c) {
                    $sub = implode(' · ', array_filter([$c->email, $c->phone]));
                    return [
                         'id' => $c->id,
                         'text' => $c->full_name . ($sub ? " — {$sub}" : ''),
                         'type' => $c->customer_type,
                    ];
               });

          return response()->json(['results' => $customers]);
     }

     /** AJAX Hızlı Önizleme (Drawer için) */
     public function quickView(Customer $customer)
     {
          $this->authorizeAgency($customer);

          $customer->load([
               'assignedAgent',
               'passengers',
               'customerDocuments.type',
               'customerDocuments.creator',
               'sales' => function($q) {
                    $q->with(['productType'])->latest('start_date');
               },
               'customFieldValues.fieldDefinition'
          ]);

          $recentActivities = CustomerActivity::where('customer_id', $customer->id)
               ->with(['performedBy', 'assignedTo'])
               ->latest('activity_date')
               ->limit(10)
               ->get();

          $activityStats = [
               'total' => CustomerActivity::where('customer_id', $customer->id)->count(),
               'pending' => CustomerActivity::where('customer_id', $customer->id)->pending()->count(),
               'follow_up' => CustomerActivity::where('customer_id', $customer->id)->requiresFollowUp()->count(),
               'complaints' => CustomerActivity::where('customer_id', $customer->id)->complaint()->count(),
          ];

          $agencyId = Auth::user()->currentAgencyId();
          $documentTypes = CustomerDocumentType::byAgency($agencyId)->active()->orderBy('sort_order')->get();
          
          // Get all custom field definitions to show empty ones too
          $definitions = CustomerFieldDefinition::byAgency($agencyId)
               ->active()
               ->orderBy('sort_order')
               ->get();

          // Financial summary
          $financial = [
               'total_spent' => $customer->sales->sum('total_amount'),
               'total_paid' => $customer->sales->sum('paid_amount'),
               'balance' => $customer->sales->sum('remaining_amount'),
               'bookings_count' => $customer->sales->count(),
          ];

          // Şirket kartları (corporate müşteriler) — kişiye şirket bağlamak için liste
          $companies = Customer::byAgency($agencyId)
               ->corporate()
               ->orderBy('company_name')
               ->get();

          // Kişi ise: bağlı şirketleri ve aynı şirketlerdeki meslektaşları
          // Şirket ise: bağlı çalışanları
          $linkedCompanies = collect();
          $members = collect();
          $colleagues = collect();

          if ($customer->customer_type === 'corporate') {
               $members = $customer->members()->orderBy('first_name')->get();
          } else {
               $linkedCompanies = $customer->companies()->get();
               $companyIds = $linkedCompanies->pluck('id');
               if ($companyIds->isNotEmpty()) {
                    $colleagueIds = DB::table('company_customer')
                         ->whereIn('company_id', $companyIds)
                         ->where('customer_id', '!=', $customer->id)
                         ->pluck('customer_id')
                         ->unique();
                    $colleagues = Customer::byAgency($agencyId)->whereIn('id', $colleagueIds)->get();
               }
          }

          return view('agency.customers.quick-view', compact('customer', 'recentActivities', 'activityStats', 'documentTypes', 'definitions', 'financial', 'companies', 'linkedCompanies', 'members', 'colleagues'))->render();
     }

     public function updateField(Request $request, Customer $customer)
     {
          $this->authorizeAgency($customer);

          $request->validate([
               'field' => 'required|string',
               'value' => 'nullable',
          ]);

          $field = $request->field;
          $value = $request->value;

          if (str_starts_with($field, 'custom_field_')) {
               $defId = (int) str_replace('custom_field_', '', $field);
               $def = CustomerFieldDefinition::where('agency_id', $customer->agency_id)->findOrFail($defId);
               
               if ($def->field_type === 'multiselect' && is_array($value)) {
                    $value = json_encode(array_values($value));
               }

               CustomerFieldValue::setValue($customer->id, $defId, $value);

               return response()->json([
                    'success' => true,
                    'message' => 'Özel alan güncellendi.',
                    'value' => $value,
                    'display_value' => $def->formatValue($value)
               ]);
          }

          $allowedFields = [
               'first_name', 'middle_name', 'last_name', 'emails', 'email_alt', 'phone', 'phone_alt',
               'national_id', 'passport_number', 'passport_expiry',
               'birth_date', 'birth_place', 'gender', 'nationality', 'address', 'city',
               'district', 'country', 'postal_code', 'status', 'priority',
               'customer_type', 'company_name', 'company_type', 'company_tax_number',
               'company_tax_office', 'company_position', 'internal_notes',
               'preferred_contact_method', 'referral_source',
               'billing_address', 'billing_city', 'billing_district',
               'billing_tax_number', 'billing_tax_office', 'billing_email',
               'credit_limit', 'payment_term_days'
          ];

          if (!in_array($field, $allowedFields)) {
               return response()->json(['success' => false, 'message' => 'Bu alan güncellenemez.'], 422);
          }

          if ($field === 'emails' && $value) {
                if (is_string($value)) {
                    $value = array_filter(array_map('trim', explode(',', $value)));
                }
                $request->merge(['value' => $value]);
                $request->validate(['value' => 'array', 'value.*' => 'email|max:255']);
          }

          if (in_array($field, ['birth_date', 'passport_expiry']) && $value) {
               $request->validate(['value' => 'date']);
          }

          if ($field === 'billing_address') {
               $request->validate(['value' => 'required|string'], [], ['value' => 'Fatura Adresi']);
          }
          if ($field === 'billing_email') {
               $request->validate(['value' => 'required|email|max:255'], [], ['value' => 'Fatura E-posta Adresi']);
          }
          if ($field === 'billing_tax_number') {
               $request->validate([
                    'value' => $customer->customer_type === 'individual' ? 'required|digits:11' : 'required|digits:10'
               ], [], ['value' => $customer->customer_type === 'individual' ? 'T.C. Kimlik Numarası' : 'Vergi Numarası']);
          }
          if ($field === 'billing_tax_office') {
               $request->validate([
                    'value' => $customer->customer_type === 'corporate' ? 'required|string|max:100' : 'nullable|string|max:100'
               ], [], ['value' => 'Fatura Vergi Dairesi']);
          }

          try {
               $customer->update([$field => $value]);

               $displayValue = $value;
               if ($field === 'status') $displayValue = $customer->fresh()->status_label;
               if ($field === 'priority') $displayValue = $customer->fresh()->priority_label;
               if ($field === 'gender') $displayValue = $value ? ['male' => 'Erkek', 'female' => 'Kadın', 'other' => 'Diğer'][$value] : '—';
               if ($field === 'preferred_contact_method') $displayValue = $value ? ucfirst($value) : '—';

               return response()->json([
                    'success' => true,
                    'message' => 'Güncellendi.',
                    'value' => $value,
                    'display_value' => $displayValue
               ]);
          } catch (\Exception $e) {
               return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
          }
     }

     protected function authorizeAgency(Customer $customer): void
     {
          if ($customer->agency_id !== Auth::user()->currentAgencyId()) {
               abort(403, 'Bu müşteriye erişim yetkiniz yok.');
          }
     }

     /**
      * Verilen şirket id'lerini güvenli hale getirir:
      * yalnızca aynı acenteye ait ve customer_type = corporate olan kayıtlar kabul edilir.
      */
     protected function resolveCompanyIds(array $ids, int $agencyId): array
     {
          $ids = array_filter(array_map('intval', $ids));
          if (empty($ids)) {
               return [];
          }

          return Customer::byAgency($agencyId)
               ->corporate()
               ->whereIn('id', $ids)
               ->pluck('id')
               ->all();
     }
}
