<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Domain extends Model
{
    /** @use HasFactory<\Database\Factories\DomainFactory> */
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'domain_hash',
        'name',
        'allowed_types',
        'is_active',
        'is_archived',
    ];

    protected function casts(): array
    {
        return [
            'allowed_types' => 'array',
            'is_active' => 'boolean',
            'is_archived' => 'boolean',
        ];
    }

    protected static function booted(): void
    {
        static::creating(function (Domain $domain) {
            if (empty($domain->domain_hash)) {
                $domain->domain_hash = bin2hex(random_bytes(32));
            }
        });
    }

    public function mailboxes()
    {
        return $this->hasMany(Mailbox::class, 'domain_hash', 'domain_hash');
    }

    /**
     * Scope to domains accessible by the given user tier.
     * For guests (null user), only 'public' domains are returned.
     *
     * Uses MySQL's JSON_CONTAINS to check if the domain's `allowed_types`
     * array includes ANY of the user's allowed types.
     *
     * Usage:
     *   Domain::accessibleBy(auth()->user())->get();     // logged-in
     *   Domain::accessibleBy(null)->get();                // guest
     *   Domain::accessibleBy($user)->where('is_active', true)->get();
     */
    public function scopeAccessibleBy(Builder $query, ?User $user = null): Builder
    {
        $types = $user ? $user->allowedDomainTypes() : User::guestDomainTypes();

        return $query->where(function (Builder $q) use ($types) {
            foreach ($types as $type) {
                $q->orWhereJsonContains('allowed_types', $type);
            }
        });
    }
}
