<?php

declare(strict_types=1);

namespace App\Application\LiveComponents\NotificationBell;

use App\Application\LiveComponents\LiveComponentState;

/**
 * Type-safe state for NotificationBellComponent
 *
 * Provides compile-time type safety for notification bell state.
 * All properties are readonly and immutable - transformations return new instances.
 */
final readonly class NotificationBellState implements LiveComponentState
{
    public function __construct(
        public string $userId = '',
        public int $unreadCount = 0,
        public array $notifications = []
    ) {
    }

    /**
     * Create from ComponentData (Framework → Domain conversion)
     */
    public static function fromArray(array $data): self
    {
        return new self(
            userId: (string) ($data['user_id'] ?? ''),
            unreadCount: (int) ($data['unread_count'] ?? 0),
            notifications: ($data['notifications'] ?? [])
        );
    }

    /**
     * Create empty state with defaults
     */
    public static function empty(): self
    {
        return new self();
    }

    /**
     * Create with user ID
     */
    public static function forUser(string $userId): self
    {
        return new self(userId: $userId);
    }

    /**
     * Convert to ComponentData (Domain → Framework conversion)
     */
    public function toArray(): array
    {
        return [
            'user_id' => $this->userId,
            'unread_count' => $this->unreadCount,
            'notifications' => $this->notifications,
        ];
    }

    /**
     * Update with new notifications
     */
    public function withNotifications(array $notifications): self
    {
        return new self(
            userId: $this->userId,
            unreadCount: count($notifications),
            notifications: $notifications
        );
    }

    /**
     * Mark all notifications as read
     */
    public function markAllAsRead(): self
    {
        return new self(
            userId: $this->userId,
            unreadCount: 0,
            notifications: []
        );
    }

    /**
     * Mark specific notification as read
     */
    public function markAsRead(string $notificationId): self
    {
        $updatedNotifications = array_filter(
            $this->notifications,
            fn ($notification) => ($notification['id'] ?? '') !== $notificationId
        );

        return new self(
            userId: $this->userId,
            unreadCount: count($updatedNotifications),
            notifications: array_values($updatedNotifications)
        );
    }

    /**
     * Add a new notification
     */
    public function addNotification(array $notification): self
    {
        $notifications = $this->notifications;
        $notifications[] = $notification;

        return new self(
            userId: $this->userId,
            unreadCount: count($notifications),
            notifications: $notifications
        );
    }

    /**
     * Check if there are unread notifications
     */
    public function hasUnread(): bool
    {
        return $this->unreadCount > 0;
    }

}
