<?php

declare(strict_types=1);

namespace App\Framework\Http\Cookies;

final readonly class Cookie
{
    public function __construct(
        public string $name,
        public string $value,
        public ?int $expires = null,
        public string $path = '/',
        public ?string $domain = '',
        public bool $secure = false,
        public bool $httpOnly = false,
        public SameSite $sameSite = SameSite::Lax,
        public bool $partitioned = false,
    ) {
        // CHIPS (Cookies Having Independent Partitioned State) requirements:
        // Partitioned cookies MUST have Secure=true AND SameSite=None
        if ($this->partitioned && (!$this->secure || $this->sameSite !== SameSite::None)) {
            throw new \InvalidArgumentException(
                'Partitioned cookies require Secure=true and SameSite=None'
            );
        }
    }

    public function toHeaderString(): string
    {
        $cookie = urlencode($this->name) . '=' . urlencode($this->value);

        if ($this->expires !== null && $this->expires > 0) {
            $cookie .= '; Expires=' . gmdate('D, d-M-Y H:i:s T', $this->expires);
        }

        if ($this->path) {
            $cookie .= '; Path=' . $this->path;
        }

        if ($this->domain) {
            $cookie .= '; Domain=' . $this->domain;
        }

        if ($this->secure) {
            $cookie .= '; Secure';
        }

        if ($this->httpOnly) {
            $cookie .= '; HttpOnly';
        }

        $cookie .= '; SameSite=' . $this->sameSite->value;

        if ($this->partitioned) {
            $cookie .= '; Partitioned';
        }

        return $cookie;
    }

    public function __toString(): string
    {
        return $this->toHeaderString();
    }
}
