<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

/**
 * Gallery Model
 *
 * Represents a gallery collection belonging to an organization.
 * Contains multiple images with titles and descriptions.
 * Tracks creation by users and maintains publication status.
 *
 * @property int $id
 * @property int $organization_id
 * @property int $gallery_type_id
 * @property string $title
 * @property string|null $description
 * @property int $image_count
 * @property bool $is_published
 * @property int $sort_order
 * @property int|null $created_by
 * @property int|null $updated_by
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property \Illuminate\Support\Carbon|null $deleted_at
 */
class Gallery extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'galleries';

    // =========================================================================
    // ATTRIBUTES & CASTING
    // =========================================================================

    protected $fillable = [
        'organization_id',
        'gallery_type_id',
        'title',
        'description',
        'image_count',
        'is_published',
        'sort_order',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'image_count'   => 'integer',
        'is_published'  => 'boolean',
        'sort_order'    => 'integer',
        'created_at'    => 'datetime',
        'updated_at'    => 'datetime',
        'deleted_at'    => 'datetime',
    ];

    protected $attributes = [
        'image_count'  => 0,
        'is_published' => true,
        'sort_order'   => 0,
    ];

    // =========================================================================
    // RELATIONSHIPS
    // =========================================================================

    /**
     * Get the organization this gallery belongs to.
     */
    public function organization(): BelongsTo
    {
        return $this->belongsTo(Organization::class, 'organization_id');
    }

    /**
     * Get the gallery type.
     */
    public function type(): BelongsTo
    {
        return $this->belongsTo(GalleryType::class, 'gallery_type_id');
    }

    /**
     * Get all images in this gallery.
     */
    public function images(): HasMany
    {
        return $this->hasMany(GalleryImage::class, 'gallery_id');
    }

    /**
     * Get the user who created this gallery.
     */
    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * Get the user who last updated this gallery.
     */
    public function updater(): BelongsTo
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

    // =========================================================================
    // QUERY SCOPES
    // =========================================================================

    /**
     * Scope to filter only published galleries.
     */
    public function scopePublished($query)
    {
        return $query->where('is_published', true);
    }

    /**
     * Scope to search by title or description.
     */
    public function scopeSearch($query, string $search)
    {
        return $query->where('title', 'like', "%{$search}%")
                     ->orWhere('description', 'like', "%{$search}%");
    }

    /**
     * Scope to filter by organization.
     */
    public function scopeOfOrganization($query, int $organizationId)
    {
        return $query->where('organization_id', $organizationId);
    }

    /**
     * Scope to filter by gallery type.
     */
    public function scopeOfType($query, int $typeId)
    {
        return $query->where('gallery_type_id', $typeId);
    }

    /**
     * Scope to order by sort order, then by creation date.
     */
    public function scopeOrdered($query)
    {
        return $query->orderBy('sort_order', 'asc')
                     ->orderBy('created_at', 'desc');
    }

    // =========================================================================
    // MODEL EVENTS
    // =========================================================================

    protected static function booted(): void
    {
        static::deleting(function (Gallery $gallery) {
            // Delete all related images when gallery is deleted
            foreach ($gallery->images as $image) {
                $image->delete();
            }
        });
    }

    // =========================================================================
    // HELPER METHODS
    // =========================================================================

    /**
     * Add an image to this gallery.
     */
    public function addImage(array $data): GalleryImage
    {
        return $this->images()->create($data);
    }

    /**
     * Increment image count.
     */
    public function incrementImageCount(): void
    {
        $this->increment('image_count');
    }

    /**
     * Decrement image count.
     */
    public function decrementImageCount(): void
    {
        if ($this->image_count > 0) {
            $this->decrement('image_count');
        }
    }

    /**
     * Recalculate image count from actual images.
     */
    public function syncImageCount(): void
    {
        $this->update(['image_count' => $this->images()->count()]);
    }

    /**
     * Check if gallery has any images.
     */
    public function hasImages(): bool
    {
        return $this->image_count > 0;
    }
}
