<?php

namespace App\Models\Customer;

use App\Models\Agency\Agency;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

class CustomerFieldDefinition extends Model
{
     use HasFactory, SoftDeletes;

     protected $table = 'customer_field_definitions';

     protected $fillable = [
          'agency_id',
          'field_key',
          'label',
          'field_type',
          'options',
          'validation_rules',
          'default_value',
          'is_required',
          'is_searchable',
          'is_filterable',
          'is_visible_in_list',
          'is_active',
          'help_text',
          'sort_order',
          'created_by',
          'updated_by',
     ];

     protected function casts(): array
     {
          return [
               'options' => 'array',
               'is_required' => 'boolean',
               'is_searchable' => 'boolean',
               'is_filterable' => 'boolean',
               'is_visible_in_list' => 'boolean',
               'is_active' => 'boolean',
          ];
     }

     // ─── İLİŞKİLER ───────────────────────────────────────────────────────────

     public function agency()
     {
          return $this->belongsTo(Agency::class);
     }

     /** Bu alan tanımına ait tüm müşteri değerleri */
     public function values()
     {
          return $this->hasMany(CustomerFieldValue::class, 'field_definition_id');
     }

     public function creator()
     {
          return $this->belongsTo(User::class, 'created_by');
     }

     public function updater()
     {
          return $this->belongsTo(User::class, 'updated_by');
     }

     // ─── SCOPE'LAR ────────────────────────────────────────────────────────────

     public function scopeActive($query)
     {
          return $query->where('is_active', true);
     }

     public function scopeByAgency($query, int $agencyId)
     {
          return $query->where('agency_id', $agencyId);
     }

     public function scopeFilterable($query)
     {
          return $query->where('is_filterable', true);
     }

     public function scopeSearchable($query)
     {
          return $query->where('is_searchable', true);
     }

     public function scopeVisibleInList($query)
     {
          return $query->where('is_visible_in_list', true);
     }

     public function scopeOrdered($query)
     {
          return $query->orderBy('sort_order')->orderBy('label');
     }

     // ─── YARDIMCI METODLAR ────────────────────────────────────────────────────

     /** Alan tipi için HTML input type döndürür */
     public function getInputTypeAttribute(): string
     {
          return match ($this->field_type) {
               'number', 'decimal' => 'number',
               'boolean' => 'checkbox',
               'date' => 'date',
               'email' => 'email',
               'phone' => 'tel',
               'url' => 'url',
               'textarea' => 'textarea',
               'select' => 'select',
               'multiselect' => 'select',
               default => 'text',
          };
     }

     /** Alan tipini Türkçe döndürür */
     public function getFieldTypeLabelAttribute(): string
     {
          return [
               'text' => 'Kısa Metin',
               'textarea' => 'Uzun Metin',
               'number' => 'Tam Sayı',
               'decimal' => 'Ondalık Sayı',
               'boolean' => 'Evet / Hayır',
               'date' => 'Tarih',
               'select' => 'Açılır Liste',
               'multiselect' => 'Çoklu Seçim',
               'email' => 'E-posta',
               'phone' => 'Telefon',
               'url' => 'URL',
          ][$this->field_type] ?? $this->field_type;
     }

     /** Verilen ham değeri alan tipine göre formatlar (görüntüleme için) */
     public function formatValue(?string $rawValue): string
     {
          if (is_null($rawValue) || $rawValue === '') {
               return '-';
          }

          return match ($this->field_type) {
               'boolean' => $rawValue ? 'Evet' : 'Hayır',
               'date' => \Carbon\Carbon::parse($rawValue)->format('d.m.Y'),
               'select' => $this->getLabelForOption($rawValue),
               'multiselect' => collect(json_decode($rawValue, true) ?? [])
                    ->map(fn($v) => $this->getLabelForOption($v))
                    ->implode(', '),
               default => $rawValue,
          };
     }

     /** Seçenek listesinden label döndürür */
     protected function getLabelForOption(string $value): string
     {
          if (!$this->options) {
               return $value;
          }

          foreach ($this->options as $option) {
               if (($option['value'] ?? null) === $value) {
                    return $option['label'] ?? $value;
               }
          }

          return $value;
     }

     // ─── BOOT ─────────────────────────────────────────────────────────────────

     protected static function boot(): void
     {
          parent::boot();

          // Label'dan otomatik field_key üret (eğer verilmemişse)
          static::creating(function (CustomerFieldDefinition $def) {
               if (empty($def->field_key)) {
                    $def->field_key = static::generateUniqueKey($def->agency_id, $def->label);
               }

               if (auth()->check()) {
                    $def->created_by = auth()->id();
               }
          });

          static::updating(function (CustomerFieldDefinition $def) {
               if (auth()->check()) {
                    $def->updated_by = auth()->id();
               }
          });
     }

     /** Aynı acentede çakışmayan benzersiz bir key üretir */
     public static function generateUniqueKey(int $agencyId, string $label): string
     {
          $base = Str::slug($label, '_');
          $key = $base;
          $i = 2;

          while (static::where('agency_id', $agencyId)->where('field_key', $key)->exists()) {
               $key = "{$base}_{$i}";
               $i++;
          }

          return $key;
     }
}
