<?php

namespace App\Services;

use App\Models\GameAccountUser;
use App\Models\News;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;

class NewsService
{
    /**
     * @return \Illuminate\Support\Collection<int, \App\Models\News>
     */
    public function listForAdmin(): Collection
    {
        return News::query()->ordered()->get();
    }

    /**
     * @return \Illuminate\Support\Collection<int, \App\Models\News>
     */
    public function listForLanding(int $limit = 6): Collection
    {
        return News::query()
            ->published()
            ->ordered()
            ->limit($limit)
            ->get();
    }

    /**
     * @return array{total: int, published: int, draft: int}
     */
    public function stats(): array
    {
        $total = News::query()->count();
        $published = News::query()->published()->count();

        return [
            'total' => $total,
            'published' => $published,
            'draft' => $total - $published,
        ];
    }

    /**
     * @param  array{title: string, body: string, sort_order: int, is_published?: bool}  $attributes
     */
    public function create(array $attributes, ?GameAccountUser $actor, ?\Illuminate\Http\UploadedFile $image = null): News
    {
        $data = [
            ...$this->normalizeAttributes($attributes),
            'created_by_account_id' => $actor?->id,
            'created_by_username' => $actor?->username,
        ];

        if ($image) {
            $data['image_path'] = $image->store('news', 'public');
        }

        return News::query()->create($data);
    }

    /**
     * @param  array{title: string, body: string, sort_order: int, is_published?: bool}  $attributes
     */
    public function update(News $news, array $attributes, ?\Illuminate\Http\UploadedFile $image = null): News
    {
        $data = $this->normalizeAttributes($attributes);

        if ($image) {
            if ($news->image_path) {
                Storage::disk('public')->delete($news->image_path);
            }

            $data['image_path'] = $image->store('news', 'public');
        }

        $news->forceFill($data)->save();

        return $news->refresh();
    }

    public function delete(News $news): void
    {
        if ($news->image_path) {
            Storage::disk('public')->delete($news->image_path);
        }

        $news->delete();
    }

    /**
     * @param  array{title: string, body: string, sort_order: int, is_published?: bool}  $attributes
     * @return array{title: string, body: string, sort_order: int, is_published: bool}
     */
    private function normalizeAttributes(array $attributes): array
    {
        return [
            'title' => trim($attributes['title']),
            'body' => trim($attributes['body']),
            'sort_order' => (int) $attributes['sort_order'],
            'is_published' => (bool) ($attributes['is_published'] ?? false),
        ];
    }


}
