<?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;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;

class Guide extends Model
{
    use HasFactory, SoftDeletes, LogsActivity;

    protected $fillable = [
        'name',
        'description',
        'category',
        'tags',
        'status',
        'created_by',
        'published_at',
    ];

    protected function casts(): array
    {
        return [
            'tags' => 'array',
            'published_at' => 'datetime',
        ];
    }

    public function pages()
    {
        return $this->hasMany(GuidePage::class);
    }

    public function edges()
    {
        return $this->hasMany(GuidePageEdge::class);
    }

    public function entryPage()
    {
        return $this->hasOne(GuidePage::class)
            ->whereNotIn('guide_pages.id', function ($q) {
                $q->select('to_page_id')
                    ->from('guide_page_edges')
                    ->whereColumn('guide_page_edges.guide_id', 'guide_pages.guide_id');
            });
    }

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

    public function stations()
    {
        return $this->belongsToMany(Station::class);
    }

    public function scopePublished($query)
    {
        return $query->where('status', 'published');
    }

    public function scopeCategory($query, string $category)
    {
        return $query->where('category', $category);
    }

    /**
     * 按用户线站过滤：全局 Guide（无线站关联）+ 用户线站关联的 Guide
     */
    public function scopeAccessibleBy(Builder $query, User $user): Builder
    {
        if (!$user->hasStationRestriction()) {
            return $query;
        }

        $stationIds = $user->getAccessibleStationIds();

        return $query->where(function (Builder $q) use ($stationIds) {
            $q->whereDoesntHave('stations')
                ->orWhereHas('stations', fn($sq) => $sq->whereIn('stations.id', $stationIds));
        });
    }

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logOnly(['name', 'description', 'category', 'status'])
            ->logOnlyDirty()
            ->setDescriptionForEvent(fn(string $eventName) => "指引已{$eventName}");
    }
}
