<?php
namespace Misuzu\Auth;

use Index\DateTime;
use Index\Data\IDbResult;
use Index\Net\IPAddress;
use Misuzu\ClientInfo;

class SessionInfo {
    public function __construct(
        private string $id,
        private string $userId,
        private string $token,
        private string $firstRemoteAddr,
        private ?string $lastRemoteAddr,
        private string $userAgent,
        private string $clientInfo,
        private string $countryCode,
        private int $expires,
        private bool $bumpExpires,
        private int $created,
        private ?int $lastActive,
    ) {}

    public static function fromResult(IDbResult $result): SessionInfo {
        return new SessionInfo(
            id: $result->getString(0),
            userId: $result->getString(1),
            token: $result->getString(2),
            firstRemoteAddr: $result->getString(3),
            lastRemoteAddr: $result->getStringOrNull(4),
            userAgent: $result->getString(5),
            clientInfo: $result->getString(6),
            countryCode: $result->getString(7),
            expires: $result->getInteger(8),
            bumpExpires: $result->getBoolean(9),
            created: $result->getInteger(10),
            lastActive: $result->getIntegerOrNull(11),
        );
    }

    public function getId(): string {
        return $this->id;
    }

    public function getUserId(): string {
        return $this->userId;
    }

    public function getToken(): string {
        return $this->token;
    }

    public function getFirstRemoteAddressRaw(): string {
        return $this->firstRemoteAddr;
    }

    public function getFirstRemoteAddress(): IPAddress {
        return IPAddress::parse($this->firstRemoteAddr);
    }

    public function hasLastRemoteAddress(): bool {
        return $this->lastRemoteAddr !== null;
    }

    public function getLastRemoteAddressRaw(): string {
        return $this->lastRemoteAddr;
    }

    public function getLastRemoteAddress(): ?IPAddress {
        return $this->lastRemoteAddr === null ? null : IPAddress::parse($this->lastRemoteAddr);
    }

    public function getUserAgentString(): string {
        return $this->userAgent;
    }

    public function getClientInfoRaw(): string {
        return $this->clientInfo;
    }

    public function getClientInfo(): ClientInfo {
        return ClientInfo::decode($this->clientInfo);
    }

    public function getCountryCode(): string {
        return $this->countryCode;
    }

    public function getExpiresTime(): int {
        return $this->expires;
    }

    public function getExpiresAt(): DateTime {
        return DateTime::fromUnixTimeSeconds($this->expires);
    }

    public function shouldBumpExpires(): bool {
        return $this->bumpExpires;
    }

    public function hasExpired(): bool {
        return $this->expires < time();
    }

    public function getCreatedTime(): int {
        return $this->created;
    }

    public function getCreatedAt(): DateTime {
        return DateTime::fromUnixTimeSeconds($this->created);
    }

    public function hasLastActive(): bool {
        return $this->lastActive !== null;
    }

    public function getLastActiveTime(): ?int {
        return $this->lastActive;
    }

    public function getLastActiveAt(): ?DateTime {
        return $this->lastActive === null ? null : DateTime::fromUnixTimeSeconds($this->lastActive);
    }
}
