<?php

namespace App\Entity;

use App\Repository\AppLogRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: AppLogRepository::class)]
#[ORM\Index(columns: ['created_at'], name: 'idx_applog_created')]
class AppLog
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
    private ?User $user = null;

    #[ORM\Column(length: 10)]
    private string $method;

    #[ORM\Column(length: 500)]
    private string $url;

    #[ORM\Column(length: 255)]
    private string $route;

    #[ORM\Column(type: 'text')]
    private string $action;

    #[ORM\Column(length: 50, nullable: true)]
    private ?string $ip = null;

    #[ORM\Column(length: 128)]
    private string $hmac;

    #[ORM\Column]
    private \DateTimeImmutable $createdAt;

    public function __construct(string $method, string $url, string $route, string $action, string $hmacSecret, ?User $user = null, ?string $ip = null)
    {
        $this->method = $method;
        $this->url = $url;
        $this->route = $route;
        $this->action = $action;
        $this->user = $user;
        $this->ip = $ip;
        $this->createdAt = new \DateTimeImmutable(date('Y-m-d H:i:s'));
        $this->hmac = $this->generateHmac($hmacSecret);
    }

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

    public function getUser(): ?User
    {
        return $this->user;
    }

    public function getMethod(): string
    {
        return $this->method;
    }

    public function getUrl(): string
    {
        return $this->url;
    }

    public function getRoute(): string
    {
        return $this->route;
    }

    public function getAction(): string
    {
        return $this->action;
    }

    public function getIp(): ?string
    {
        return $this->ip;
    }

    public function getHmac(): string
    {
        return $this->hmac;
    }

    public function getCreatedAt(): \DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function verifyHmac(string $hmacSecret): bool
    {
        return hash_equals($this->hmac, $this->generateHmac($hmacSecret));
    }

    private function generateHmac(string $secret): string
    {
        $payload = implode('|', [
            $this->method,
            $this->url,
            $this->route,
            $this->action,
            $this->ip ?? '',
            null !== $this->user ? (string) $this->user->getId() : '',
            $this->createdAt->format('Y-m-d\TH:i:s'),
        ]);

        return hash_hmac('sha256', $payload, $secret);
    }
}
