<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class DashboardPreference extends Model
{
    public const MAX_PINNED_SPACES = 8;

    /**
     * @var list<string>
     */
    private const ALLOWED_PINNED_SPACES = [
        '/dashboard/profile',
        '/dashboard/notifications',
        '/dashboard/comments/received',
        '/dashboard/followers',
        '/dashboard/following',
        '/dashboard/favorites',
        '/dashboard/artworks',
        '/dashboard/gallery',
        '/dashboard/awards',
        '/creator/stories',
        '/studio',
    ];

    protected $table = 'dashboard_preferences';
    protected $primaryKey = 'user_id';
    public $incrementing = false;
    protected $keyType = 'int';

    protected $fillable = [
        'user_id',
        'pinned_spaces',
        'studio_preferences',
    ];

    protected function casts(): array
    {
        return [
            'pinned_spaces' => 'array',
            'studio_preferences' => 'array',
        ];
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    /**
     * @param array<int, mixed> $hrefs
     * @return list<string>
     */
    public static function sanitizePinnedSpaces(array $hrefs): array
    {
        $allowed = array_fill_keys(self::ALLOWED_PINNED_SPACES, true);
        $sanitized = [];

        foreach ($hrefs as $href) {
            if (! is_string($href) || ! isset($allowed[$href])) {
                continue;
            }

            if (in_array($href, $sanitized, true)) {
                continue;
            }

            $sanitized[] = $href;

            if (count($sanitized) >= self::MAX_PINNED_SPACES) {
                break;
            }
        }

        return $sanitized;
    }

    /**
     * @return list<string>
     */
    public static function pinnedSpacesForUser(User $user): array
    {
        $preference = static::query()->find($user->id);
        $spaces = $preference?->pinned_spaces;

        return is_array($spaces) ? static::sanitizePinnedSpaces($spaces) : [];
    }
}
