<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Filament\Livewire;

use App\Models\User;
use App\Services\DberpOfficialNewsFeedService;
use Illuminate\Contracts\View\View;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\On;
use Livewire\Component;
use Livewire\WithoutUrlPagination;
use Livewire\WithPagination;

class OfficialNewsSlideOver extends Component
{
    use WithoutUrlPagination;
    use WithPagination;

    public const MODAL_ID = 'official-news-all';

    public const PAGE_NAME = 'officialNewsPage';

    public function markAsRead(int $newsId): void
    {
        $user = Auth::user();

        if (! $user instanceof User) {
            return;
        }

        app(DberpOfficialNewsFeedService::class)->markAsRead($user, $newsId);
        $this->dispatch('official-news-reads-changed');
    }

    public function markAllAsRead(): void
    {
        $user = Auth::user();

        if (! $user instanceof User) {
            return;
        }

        app(DberpOfficialNewsFeedService::class)->markAllAsRead($user);
        $this->dispatch('official-news-reads-changed');
    }

    #[On('official-news-open-all')]
    public function resetToFirstPage(): void
    {
        $this->resetPage(self::PAGE_NAME);
    }

    #[On('official-news-reads-changed')]
    public function refreshReads(): void
    {
        // 由对端组件派发；重新渲染时已读状态从服务即时查询。
    }

    public function render(): View
    {
        $user = Auth::user();
        $service = app(DberpOfficialNewsFeedService::class);
        $resolvedUser = $user instanceof User ? $user : null;
        $items = $service->panelItemsFor($resolvedUser);

        return view('filament.livewire.official-news-slide-over', [
            'paginatedItems' => $this->paginateItems($items, $service->slideOverPerPage()),
            'unreadCount' => $service->unreadCountFor($resolvedUser),
        ]);
    }

    /**
     * @param  list<array<string, mixed>>  $items
     * @return LengthAwarePaginator<int, array<string, mixed>>
     */
    private function paginateItems(array $items, int $perPage): LengthAwarePaginator
    {
        $total = count($items);
        $lastPage = max(1, (int) ceil($total / $perPage));
        $page = $this->getPage(self::PAGE_NAME);

        if ($page > $lastPage) {
            $page = $lastPage;
            $this->setPage($page, self::PAGE_NAME);
        }

        return new LengthAwarePaginator(
            items: array_slice($items, ($page - 1) * $perPage, $perPage),
            total: $total,
            perPage: $perPage,
            currentPage: $page,
            options: [
                'path' => LengthAwarePaginator::resolveCurrentPath(),
                'pageName' => self::PAGE_NAME,
            ],
        );
    }
}
