<?php

namespace App\Models\Chat;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

/**
 * Acentenin dış sohbet erişim ayarı: KENDİ personelinden hangilerine
 * dışarıdan (başka acentelerden) ulaşılabileceğini belirler.
 *
 *   all      → tüm aktif personel (varsayılan; ayar satırı yoksa da geçerli)
 *   selected → seçili roldeki kullanıcılar ∪ tek tek seçilen kullanıcılar
 *   none     → kimseye ulaşılamaz
 */
class ExternalAccessSetting extends Model
{
    use HasFactory;

    protected $table = 'chat_external_settings';

    /** Mod anahtarı → arayüz etiketi. */
    public const MODES = [
        'all' => 'Tüm personel',
        'selected' => 'Seçili roller / kullanıcılar',
        'none' => 'Kimse (dış sohbete kapalı)',
    ];

    protected $fillable = [
        'agency_id',
        'mode',
        'allowed_role_ids',
        'allowed_user_ids',
        'updated_by',
    ];

    protected $casts = [
        'allowed_role_ids' => 'array',
        'allowed_user_ids' => 'array',
    ];

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

    /** Bu acentede dışarıdan ulaşılabilir kullanıcı id'leri (mod "selected" için). */
    public function reachableUserIds(): array
    {
        if ($this->mode === 'none') {
            return [];
        }

        $users = collect($this->allowed_user_ids ?: [])->map(fn ($v) => (int) $v);
        $byRole = static::usersWithRoles((int) $this->agency_id, $this->allowed_role_ids ?: []);

        return $users->concat($byRole)->unique()->values()->all();
    }

    /** Verilen acentede, belirtilen rollerden birine sahip kullanıcı id'leri (takım bazlı roller). */
    public static function usersWithRoles(int $agencyId, array $roleIds): array
    {
        $roleIds = array_values(array_filter(array_map('intval', $roleIds)));
        if (! $roleIds) {
            return [];
        }

        $pivot = config('permission.table_names.model_has_roles');
        $teamKey = config('permission.column_names.team_foreign_key', 'agency_id');

        return DB::table($pivot)
            ->where('model_type', (new User)->getMorphClass())
            ->where($teamKey, $agencyId)
            ->whereIn('role_id', $roleIds)
            ->pluck('model_id')
            ->map(fn ($v) => (int) $v)
            ->unique()
            ->values()
            ->all();
    }

    /**
     * Tablo hazır mı? El sıkışma migration'ı uygulanmadan da mesajlaşma
     * çalışmaya devam etmeli; sonuç istek boyunca önbelleklenir.
     */
    public static function ready(): bool
    {
        static $ready = null;

        if ($ready === null) {
            try {
                $ready = \Illuminate\Support\Facades\Schema::hasTable((new static)->getTable());
            } catch (\Throwable $e) {
                $ready = false;
            }
        }

        return $ready;
    }
}
