<?php

namespace Media\Repositories;

use App\Framework\Database\Connection;
use App\Framework\Database\ConnectionInterface;
use Media\Entities\Image;

class ImageRepository
{
    public function __construct(
        private ConnectionInterface $db
    ) {

    }

    public function save(Image $image): Image
    {
        $query = "INSERT INTO images "
             . "(filename, original_filename, mime_type, file_size, width, height, hash, upload_path, created_at) "
             . "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";

        $this->db->execute(
            $query,
            [
                $image->filename,
                $image->originalFilename,
                $image->mimeType,
                $image->fileSize,
                $image->width,
                $image->height,
                $image->hash,
                $image->uploadPath,
                $image->createdAt->format('Y-m-d H:i:s'),
            ]
        );

        $image->id = (int)$this->db->lastInsertId();

        return $image;
    }

    public function update(Image $image): void
    {
        $query = "UPDATE images SET "
             . "filename = ?, original_filename = ?, mime_type = ?, file_size = ?, "
             . "width = ?, height = ?, hash = ?, upload_path = ?, updated_at = CURRENT_TIMESTAMP "
             . "WHERE id = ?;";

        $this->db->execute(
            $query,
            [
                $image->filename,
                $image->originalFilename,
                $image->mimeType,
                $image->fileSize,
                $image->width,
                $image->height,
                $image->hash,
                $image->uploadPath,
                $image->id,
            ]
        );
    }

    public function findById(int $id): ?Image
    {
        $query = "SELECT * FROM images WHERE id = ?;";
        $result = $this->db->query($query, [$id])->fetch();

        if (null === $result) {
            return null;
        }

        return $this->mapToEntity($result);
    }

    public function findByHash(string $hash): ?Image
    {
        $query = "SELECT * FROM images WHERE hash = ?;";
        $result = $this->db->query($query, [$hash])->fetch();

        if (!$result) {
            return null;
        }

        return $this->mapToEntity($result);
    }

    private function mapToEntity(array $data): Image
    {
        return new Image(
            id: (int)$data['id'],
            filename: $data['filename'],
            originalFilename: $data['original_filename'],
            mimeType: $data['mime_type'],
            fileSize: (int)$data['file_size'],
            width: (int)$data['width'],
            height: (int)$data['height'],
            hash: $data['hash'],
            uploadPath: $data['upload_path'],
            createdAt: new \DateTimeImmutable($data['created_at']),
            updatedAt: $data['updated_at'] ? new \DateTimeImmutable($data['updated_at']) : null,
        );
    }
}
