<?php

namespace App\Models;

use App\Models\Event;
use App\Models\Group;
use App\Models\Job;
use App\Models\Marketplace\Product;
use App\Models\Page;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class ReportModule extends Model
{
    use SoftDeletes;

    /**
     * Report status constants.
     */
    public const STATUS_PENDING = 0;
    public const STATUS_RESOLVED = 1;
    public const STATUS_DISMISSED = 2;

    /**
     * Mapping of status labels.
     *
     * @var array<int, string>
     */
    public const STATUS_LABELS = [
        self::STATUS_PENDING => 'Pending',
        self::STATUS_RESOLVED => 'Resolved',
        self::STATUS_DISMISSED => 'Dismissed',
    ];

    /**
     * Mapping of bootstrap badge classes for each status.
     *
     * @var array<int, string>
     */
    public const STATUS_BADGES = [
        self::STATUS_PENDING => 'warning',
        self::STATUS_RESOLVED => 'success',
        self::STATUS_DISMISSED => 'secondary',
    ];

    /**
     * Module configuration map.
     *
     * @var array<string, array<string, class-string<Model>|string>>
     */
    public const MODULE_MAP = [
        'group' => [
            'model' => Group::class,
            'title_column' => 'name',
        ],
        'page' => [
            'model' => Page::class,
            'title_column' => 'page_title',
        ],
        'product' => [
            'model' => Product::class,
            'title_column' => 'title',
        ],
        'event' => [
            'model' => Event::class,
            'title_column' => 'title',
        ],
        'job' => [
            'model' => Job::class,
            'title_column' => 'title',
        ],
    ];

    /**
     * The attributes that aren't mass assignable.
     *
     * @var array<int, string>
     */
    protected $guarded = [];

    /**
     * Attribute casting.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'user_id' => 'integer',
        'module_id' => 'integer',
        'status' => 'integer',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'deleted_at' => 'datetime',
    ];

    /**
     * Reporter relationship.
     */
    public function reporter()
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    /**
     * Scope: pending reports.
     */
    public function scopePending($query)
    {
        return $query->where('status', self::STATUS_PENDING);
    }

    /**
     * Scope: resolved reports.
     */
    public function scopeResolved($query)
    {
        return $query->where('status', self::STATUS_RESOLVED);
    }

    /**
     * Scope: dismissed reports.
     */
    public function scopeDismissed($query)
    {
        return $query->where('status', self::STATUS_DISMISSED);
    }

    /**
     * Accessor: friendly status label.
     */
    public function getStatusLabelAttribute(): string
    {
        return self::STATUS_LABELS[$this->status] ?? 'Unknown';
    }

    /**
     * Accessor: bootstrap badge class for status.
     */
    public function getStatusBadgeAttribute(): string
    {
        return self::STATUS_BADGES[$this->status] ?? 'secondary';
    }

    /**
     * Accessor: formatted module label.
     */
    public function getModuleLabelAttribute(): string
    {
        return ucfirst($this->module_name);
    }

    /**
     * Accessor: resolve associated module record.
     */
    public function getModuleRecordAttribute()
    {
        $config = self::MODULE_MAP[$this->module_name] ?? null;

        if (!$config || empty($this->module_id)) {
            return null;
        }

        return ($config['model'])::find($this->module_id);
    }

    /**
     * Helper to retrieve a human readable module title.
     */
    public function getModuleTitleAttribute(): ?string
    {
        $record = $this->module_record;

        if (!$record) {
            return null;
        }

        $config = self::MODULE_MAP[$this->module_name] ?? null;
        $column = $config['title_column'] ?? null;

        return $column && isset($record->{$column}) 
            ? $record->{$column}
            : ($record->name ?? $record->title ?? sprintf('#%d', $record->getKey()));
    }
}
