<?php

namespace App\Models;

use App\Traits\UploadsMedia;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Announcement extends BaseModel
{
    use UploadsMedia;

    protected $fillable = [
        'title',
        'message',
        'attachments',
        'publish_at',
        'notified_at',
        'target_type',
        'created_by',
    ];

    protected $casts = [
        'attachments' => 'array',
        'publish_at' => 'datetime',
        'notified_at' => 'datetime',
    ];

    /**
     * The creator of the announcement.
     */
    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * Targeted departments for the announcement.
     */
    public function departments(): BelongsToMany
    {
        return $this->belongsToMany(Department::class, 'announcement_department');
    }

    /**
     * Targeted roles for the announcement.
     */
    public function roles(): BelongsToMany
    {
        return $this->belongsToMany(Role::class, 'announcement_role');
    }

    /**
     * Targeted users (specific employees) for the announcement.
     */
    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'announcement_user');
    }

    /**
     * Users who have read the announcement.
     */
    public function readByUsers(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'announcement_user_read')
            ->withPivot('read_at');
    }

    /**
     * Scope for published announcements.
     */
    public function scopePublished(Builder $query): Builder
    {
        return $query->whereNotNull('publish_at')
            ->where('publish_at', '<=', now());
    }

    /**
     * Scope for announcements visible to a specific user.
     */
    public function scopeVisibleTo(Builder $query, User $user): Builder
    {
        return $query->where(function ($q) use ($user) {
            $q->where('target_type', 'all')
                ->orWhere(function ($sq) use ($user) {
                    $sq->where('target_type', 'department')
                        ->whereHas('departments', function ($dq) use ($user) {
                            $dq->where('id', $user->employeeProfile?->department_id);
                        });
                })
                ->orWhere(function ($sq) use ($user) {
                    $sq->where('target_type', 'role')
                        ->whereHas('roles', function ($rq) use ($user) {
                            // Simplified role check - assuming roles relationship exists on User
                            $rq->whereIn('roles.id', $user->roles->pluck('id'));
                        });
                })
                ->orWhere(function ($sq) use ($user) {
                    $sq->where('target_type', 'user')
                        ->whereHas('users', function ($uq) use ($user) {
                            $uq->where('users.id', $user->id);
                        });
                });
        });
    }

    /**
     * Helper to check if a user has read this announcement.
     */
    public function isReadBy(User $user): bool
    {
        return $this->readByUsers()->where('user_id', $user->id)->exists();
    }
}
