<?php

declare(strict_types=1);

namespace App\Repositories;

use App\Database;
use PDO;

final class PostRepository
{
    private PDO $db;

    public function __construct()
    {
        $this->db = Database::connection();
    }

    public function latest(int $limit = 3): array
    {
        $statement = $this->db->prepare(
            "SELECT posts.id, posts.title, posts.slug, posts.category, posts.excerpt, posts.published_at,
                (SELECT file_path FROM post_images WHERE post_id = posts.id ORDER BY sort_order, id LIMIT 1) AS image_path,
                (SELECT alt_text FROM post_images WHERE post_id = posts.id ORDER BY sort_order, id LIMIT 1) AS image_alt
             FROM posts
             WHERE posts.status = 'published' AND posts.deleted_at IS NULL AND posts.published_at <= NOW()
             ORDER BY published_at DESC, id DESC
             LIMIT :limit"
        );
        $statement->bindValue(':limit', $limit, PDO::PARAM_INT);
        $statement->execute();
        return $statement->fetchAll();
    }

    public function paginate(int $page, int $perPage, ?string $category = null): array
    {
        $where = "posts.status = 'published' AND posts.deleted_at IS NULL AND posts.published_at <= NOW()";
        $params = [];
        if ($category !== null && $category !== '') {
            $where .= ' AND posts.category = :category';
            $params['category'] = $category;
        }

        $count = $this->db->prepare("SELECT COUNT(*) FROM posts WHERE {$where}");
        $count->execute($params);
        $total = (int) $count->fetchColumn();

        $offset = max(0, ($page - 1) * $perPage);
        $query = $this->db->prepare(
            "SELECT posts.id, posts.title, posts.slug, posts.category, posts.excerpt, posts.published_at,
                (SELECT file_path FROM post_images WHERE post_id = posts.id ORDER BY sort_order, id LIMIT 1) AS image_path,
                (SELECT alt_text FROM post_images WHERE post_id = posts.id ORDER BY sort_order, id LIMIT 1) AS image_alt
             FROM posts WHERE {$where}
             ORDER BY published_at DESC, id DESC
             LIMIT :limit OFFSET :offset"
        );
        foreach ($params as $key => $value) {
            $query->bindValue(':' . $key, $value);
        }
        $query->bindValue(':limit', $perPage, PDO::PARAM_INT);
        $query->bindValue(':offset', $offset, PDO::PARAM_INT);
        $query->execute();

        return ['items' => $query->fetchAll(), 'total' => $total];
    }

    public function findPublishedBySlug(string $slug): ?array
    {
        $statement = $this->db->prepare(
            "SELECT posts.id, posts.title, posts.slug, posts.category, posts.excerpt, posts.body, posts.author, posts.published_at,
                (SELECT file_path FROM post_images WHERE post_id = posts.id ORDER BY sort_order, id LIMIT 1) AS image_path,
                (SELECT alt_text FROM post_images WHERE post_id = posts.id ORDER BY sort_order, id LIMIT 1) AS image_alt
             FROM posts
             WHERE posts.slug = :slug AND posts.status = 'published' AND posts.deleted_at IS NULL AND posts.published_at <= NOW()
             LIMIT 1"
        );
        $statement->execute(['slug' => $slug]);
        $post = $statement->fetch();
        return $post ?: null;
    }
}
