<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;

class HomepageAnnouncement extends Model
{
    use SoftDeletes;

    public const STATUS_DRAFT = 'draft';
    public const STATUS_PUBLISHED = 'published';
    public const STATUS_ARCHIVED = 'archived';

    public const TYPE_ANNOUNCEMENT = 'announcement';
    public const TYPE_LAUNCH = 'launch';
    public const TYPE_NEWS = 'news';
    public const TYPE_WORLD = 'world';
    public const TYPE_EVENT = 'event';
    public const TYPE_NOTICE = 'notice';
    public const TYPE_MAINTENANCE = 'maintenance';

    public const PLACEMENT_HOMEPAGE_AFTER_FEATURED = 'homepage_after_featured';

    public const LINK_TYPE_NONE = 'none';
    public const LINK_TYPE_CUSTOM_URL = 'custom_url';
    public const LINK_TYPE_NEWS = 'news';
    public const LINK_TYPE_WORLD = 'world';
    public const LINK_TYPE_ARTWORK = 'artwork';
    public const LINK_TYPE_COLLECTION = 'collection';
    public const LINK_TYPE_GROUP = 'group';
    public const LINK_TYPE_PROFILE = 'profile';
    public const LINK_TYPE_EXPLORE = 'explore';
    public const LINK_TYPE_UPLOAD = 'upload';

    public const GRADIENT_NOVA_AURORA = 'nova_aurora';
    public const GRADIENT_DEEP_SPACE = 'deep_space';
    public const GRADIENT_SUNRISE = 'sunrise';
    public const GRADIENT_OCEAN_GLOW = 'ocean_glow';
    public const GRADIENT_SPRING_VIBES = 'spring_vibes';
    public const GRADIENT_FANTASY_REALMS = 'fantasy_realms';
    public const GRADIENT_MINIMAL_LIGHT = 'minimal_light';
    public const GRADIENT_DARK_GLASS = 'dark_glass';

    protected $table = 'homepage_announcements';

    protected $fillable = [
        'title',
        'subtitle',
        'badge_text',
        'content_html',
        'type',
        'status',
        'is_active',
        'starts_at',
        'ends_at',
        'primary_link_label',
        'primary_link_type',
        'primary_link_url',
        'primary_link_target_type',
        'primary_link_target_id',
        'secondary_link_label',
        'secondary_link_type',
        'secondary_link_url',
        'secondary_link_target_type',
        'secondary_link_target_id',
        'background_type',
        'background_image',
        'gradient_preset',
        'theme_preset',
        'text_color',
        'overlay_opacity',
        'placement',
        'priority',
        'is_dismissible',
        'dismiss_version',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'is_active' => 'boolean',
        'starts_at' => 'datetime',
        'ends_at' => 'datetime',
        'primary_link_target_id' => 'integer',
        'secondary_link_target_id' => 'integer',
        'overlay_opacity' => 'integer',
        'priority' => 'integer',
        'is_dismissible' => 'boolean',
        'dismiss_version' => 'integer',
    ];

    public static function statuses(): array
    {
        return [
            self::STATUS_DRAFT,
            self::STATUS_PUBLISHED,
            self::STATUS_ARCHIVED,
        ];
    }

    public static function types(): array
    {
        return [
            self::TYPE_ANNOUNCEMENT,
            self::TYPE_LAUNCH,
            self::TYPE_NEWS,
            self::TYPE_WORLD,
            self::TYPE_EVENT,
            self::TYPE_NOTICE,
            self::TYPE_MAINTENANCE,
        ];
    }

    public static function placements(): array
    {
        return [
            self::PLACEMENT_HOMEPAGE_AFTER_FEATURED,
        ];
    }

    public static function linkTypes(): array
    {
        return [
            self::LINK_TYPE_NONE,
            self::LINK_TYPE_CUSTOM_URL,
            self::LINK_TYPE_NEWS,
            self::LINK_TYPE_WORLD,
            self::LINK_TYPE_ARTWORK,
            self::LINK_TYPE_COLLECTION,
            self::LINK_TYPE_GROUP,
            self::LINK_TYPE_PROFILE,
            self::LINK_TYPE_EXPLORE,
            self::LINK_TYPE_UPLOAD,
        ];
    }

    public static function gradientPresets(): array
    {
        return [
            self::GRADIENT_NOVA_AURORA,
            self::GRADIENT_DEEP_SPACE,
            self::GRADIENT_SUNRISE,
            self::GRADIENT_OCEAN_GLOW,
            self::GRADIENT_SPRING_VIBES,
            self::GRADIENT_FANTASY_REALMS,
            self::GRADIENT_MINIMAL_LIGHT,
            self::GRADIENT_DARK_GLASS,
        ];
    }

    public function scopePublished(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_PUBLISHED);
    }

    public function scopeActive(Builder $query): Builder
    {
        return $query->where('is_active', true);
    }

    public function scopeVisibleNow(Builder $query, ?Carbon $now = null): Builder
    {
        $now ??= now();

        return $query
            ->where(function (Builder $builder) use ($now): void {
                $builder->whereNull('starts_at')
                    ->orWhere('starts_at', '<=', $now);
            })
            ->where(function (Builder $builder) use ($now): void {
                $builder->whereNull('ends_at')
                    ->orWhere('ends_at', '>=', $now);
            });
    }

    public function scopeForPlacement(Builder $query, string $placement): Builder
    {
        return $query->where('placement', $placement);
    }

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

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