<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\Collection;
use Illuminate\Support\Arr;

class CollectionLifecycleService
{
    public function resolveState(Collection $collection): string
    {
        if ($collection->moderation_status === Collection::MODERATION_HIDDEN) {
            return Collection::LIFECYCLE_HIDDEN;
        }

        if ($collection->moderation_status === Collection::MODERATION_RESTRICTED) {
            return Collection::LIFECYCLE_RESTRICTED;
        }

        if ($collection->moderation_status === Collection::MODERATION_UNDER_REVIEW) {
            return Collection::LIFECYCLE_UNDER_REVIEW;
        }

        if ($collection->expired_at && $collection->expired_at->lte(now())) {
            return Collection::LIFECYCLE_EXPIRED;
        }

        if ($collection->archived_at !== null) {
            return Collection::LIFECYCLE_ARCHIVED;
        }

        if ($collection->published_at && $collection->published_at->isFuture()) {
            return Collection::LIFECYCLE_SCHEDULED;
        }

        if ($collection->visibility === Collection::VISIBILITY_PRIVATE) {
            return Collection::LIFECYCLE_DRAFT;
        }

        if ($collection->is_featured) {
            return Collection::LIFECYCLE_FEATURED;
        }

        return Collection::LIFECYCLE_PUBLISHED;
    }

    public function syncState(Collection $collection): Collection
    {
        $nextState = $this->resolveState($collection->fresh());
        $collection->forceFill(['lifecycle_state' => $nextState])->save();

        return $collection->fresh();
    }

    public function applyAttributes(Collection $collection, array $attributes): Collection
    {
        $collection->forceFill(Arr::only($attributes, [
            'lifecycle_state',
            'archived_at',
            'expired_at',
            'published_at',
            'unpublished_at',
        ]))->save();

        return $this->syncState($collection);
    }

    public function syncScheduledCollections(): array
    {
        $expired = Collection::query()
            ->whereNotNull('expired_at')
            ->where('expired_at', '<=', now())
            ->where('lifecycle_state', '!=', Collection::LIFECYCLE_EXPIRED)
            ->update([
                'lifecycle_state' => Collection::LIFECYCLE_EXPIRED,
                'is_featured' => false,
                'featured_at' => null,
                'updated_at' => now(),
            ]);

        $scheduled = Collection::query()
            ->whereNotNull('published_at')
            ->where('published_at', '<=', now())
            ->whereIn('lifecycle_state', [Collection::LIFECYCLE_DRAFT, Collection::LIFECYCLE_SCHEDULED])
            ->where('moderation_status', Collection::MODERATION_ACTIVE)
            ->where('visibility', '!=', Collection::VISIBILITY_PRIVATE)
            ->update([
                'lifecycle_state' => Collection::LIFECYCLE_PUBLISHED,
                'updated_at' => now(),
            ]);

        return [
            'expired' => $expired,
            'scheduled' => $scheduled,
        ];
    }
}
