<?php

declare(strict_types=1);

namespace App\Framework\Deployment\Ssl\ValueObjects;

use DateTimeImmutable;

/**
 * SSL Certificate Status - validity and health information
 */
final readonly class CertificateStatus
{
    public function __construct(
        public bool $exists,
        public bool $isValid,
        public ?DateTimeImmutable $notBefore,
        public ?DateTimeImmutable $notAfter,
        public ?string $issuer,
        public ?string $subject,
        public ?int $daysUntilExpiry,
        public bool $isExpiring, // < 30 days
        public bool $isExpired,
        public array $errors = []
    ) {}

    public static function notFound(): self
    {
        return new self(
            exists: false,
            isValid: false,
            notBefore: null,
            notAfter: null,
            issuer: null,
            subject: null,
            daysUntilExpiry: null,
            isExpiring: false,
            isExpired: false,
            errors: ['Certificate files not found']
        );
    }

    public static function fromCertificateData(
        DateTimeImmutable $notBefore,
        DateTimeImmutable $notAfter,
        string $issuer,
        string $subject
    ): self {
        $now = new DateTimeImmutable();
        $daysUntilExpiry = $now->diff($notAfter)->days;
        $isExpired = $notAfter < $now;
        $isExpiring = !$isExpired && $daysUntilExpiry < 30;
        $isValid = !$isExpired && $notBefore <= $now;

        return new self(
            exists: true,
            isValid: $isValid,
            notBefore: $notBefore,
            notAfter: $notAfter,
            issuer: $issuer,
            subject: $subject,
            daysUntilExpiry: $daysUntilExpiry,
            isExpiring: $isExpiring,
            isExpired: $isExpired
        );
    }

    public function needsRenewal(): bool
    {
        return $this->isExpiring || $this->isExpired || !$this->isValid;
    }

    public function getHealthStatus(): string
    {
        return match (true) {
            $this->isExpired => 'expired',
            $this->isExpiring => 'expiring',
            !$this->isValid => 'invalid',
            !$this->exists => 'missing',
            default => 'healthy',
        };
    }

    public function toArray(): array
    {
        return [
            'exists' => $this->exists,
            'is_valid' => $this->isValid,
            'not_before' => $this->notBefore?->format('Y-m-d H:i:s'),
            'not_after' => $this->notAfter?->format('Y-m-d H:i:s'),
            'issuer' => $this->issuer,
            'subject' => $this->subject,
            'days_until_expiry' => $this->daysUntilExpiry,
            'is_expiring' => $this->isExpiring,
            'is_expired' => $this->isExpired,
            'needs_renewal' => $this->needsRenewal(),
            'health_status' => $this->getHealthStatus(),
            'errors' => $this->errors,
        ];
    }
}
