<?php

declare(strict_types=1);

namespace App\Framework\LiveComponents\Polling;

use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Core\ValueObjects\MethodName;
use App\Framework\Core\ValueObjects\Duration;

/**
 * Value Object representing the result of a poll execution.
 */
final readonly class PollResult
{
    private function __construct(
        public ClassName $className,
        public MethodName $methodName,
        public bool $success,
        public mixed $data = null,
        public ?\Throwable $error = null,
        public ?Duration $executionTime = null,
        public ?string $reason = null
    ) {}

    /**
     * Create successful result.
     */
    public static function success(
        ClassName $className,
        MethodName $methodName,
        mixed $data,
        Duration $executionTime
    ): self {
        return new self(
            className: $className,
            methodName: $methodName,
            success: true,
            data: $data,
            executionTime: $executionTime
        );
    }

    /**
     * Create failed result.
     */
    public static function failed(
        ClassName $className,
        MethodName $methodName,
        \Throwable $error,
        Duration $executionTime
    ): self {
        return new self(
            className: $className,
            methodName: $methodName,
            success: false,
            error: $error,
            executionTime: $executionTime
        );
    }

    /**
     * Create result for poll not found.
     */
    public static function notFound(ClassName $className, MethodName $methodName): self
    {
        return new self(
            className: $className,
            methodName: $methodName,
            success: false,
            reason: 'Poll not found'
        );
    }

    /**
     * Create result for disabled poll.
     */
    public static function disabled(ClassName $className, MethodName $methodName): self
    {
        return new self(
            className: $className,
            methodName: $methodName,
            success: false,
            reason: 'Poll is disabled'
        );
    }

    /**
     * Get poll identifier.
     */
    public function getPollId(): string
    {
        return $this->className->getFullyQualified() . '::' . $this->methodName->toString();
    }

    /**
     * Check if execution was successful.
     */
    public function isSuccess(): bool
    {
        return $this->success;
    }

    /**
     * Check if execution failed.
     */
    public function isFailed(): bool
    {
        return !$this->success;
    }

    /**
     * Convert to array for serialization.
     */
    public function toArray(): array
    {
        return [
            'poll_id' => $this->getPollId(),
            'class' => $this->className->getFullyQualified(),
            'method' => $this->methodName->toString(),
            'success' => $this->success,
            'data' => $this->data,
            'error' => $this->error?->getMessage(),
            'execution_time_ms' => $this->executionTime?->toMilliseconds(),
            'reason' => $this->reason
        ];
    }
}
