<?php

declare(strict_types=1);

namespace App\Controllers;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;
use Medoo\Medoo;
use App\Models\Post;

/**
 * Contrôleur pour les posts.
 */
class PostController
{
    public function __construct(private Twig $view, private Medoo $db)
    {
    }

    /**
     * Affiche la page d'accueil avec tous les articles.
     */
    public function index(Request $req, Response $res): Response
    {
        $rows = $this->db->select('post', '*', ['ORDER' => ['id' => 'DESC']]);
        $posts = array_map(fn ($row) => Post::fromArray($row), $rows ?: []);

        return $this->view->render($res, 'pages/home.twig', ['posts' => $posts]);
    }

    /**
     * Affiche la page d'administration.
     */
    public function admin(Request $req, Response $res): Response
    {
        $rows = $this->db->select('post', '*', ['ORDER' => ['id' => 'DESC']]);
        $posts = array_map(fn ($row) => Post::fromArray($row), $rows ?: []);

        return $this->view->render($res, 'pages/admin.twig', ['posts' => $posts]);
    }

    /**
     * Affiche le formulaire de création/édition.
     */
    public function form(Request $req, Response $res, array $args): Response
    {
        $id = (int)($args['id'] ?? 0);
        $post = null;

        if ($id > 0) {
            $row = $this->db->get('post', '*', ['id' => $id]);
            if (!$row) {
                $res->getBody()->write('Article non trouvé');
                return $res->withStatus(404);
            }
            $post = Post::fromArray($row);
        }

        $action = $id ? "/admin/edit/{$id}" : "/admin/create";
        return $this->view->render($res, 'pages/post_form.twig', [
            'post' => $post,
            'action' => $action,
        ]);
    }

    /**
     * Crée un nouvel article.
     */
    public function create(Request $req, Response $res): Response
    {
        $data = $req->getParsedBody();
        $title = trim((string)($data['title'] ?? ''));
        $content = trim((string)($data['content'] ?? ''));

        // Créer un objet Post pour valider
        try {
            $post = new Post(0, $title, $content);
        } catch (\InvalidArgumentException) {
            // Validation échouée, retour à l'admin
            return $res->withHeader('Location', '/admin')->withStatus(302);
        }

        // Persister en DB
        $this->db->insert('post', [
            'title' => $post->getTitle(),
            'content' => $post->getContent(),
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);

        return $res->withHeader('Location', '/admin')->withStatus(302);
    }

    /**
     * Met à jour un article existant.
     */
    public function update(Request $req, Response $res, array $args): Response
    {
        $id = (int)$args['id'];
        $existing = $this->db->get('post', 'id', ['id' => $id]);

        if (!$existing) {
            $res->getBody()->write('Article non trouvé');
            return $res->withStatus(404);
        }

        $data = $req->getParsedBody();
        $title = trim((string)($data['title'] ?? ''));
        $content = trim((string)($data['content'] ?? ''));

        // Créer un objet Post pour valider
        try {
            $post = new Post($id, $title, $content);
        } catch (\InvalidArgumentException) {
            // Validation échouée, retour à l'admin
            return $res->withHeader('Location', '/admin')->withStatus(302);
        }

        // Persister en DB
        $this->db->update('post', [
            'title' => $post->getTitle(),
            'content' => $post->getContent(),
            'updated_at' => date('Y-m-d H:i:s'),
        ], ['id' => $id]);

        return $res->withHeader('Location', '/admin')->withStatus(302);
    }

    /**
     * Supprime un article.
     */
    public function delete(Request $req, Response $res, array $args): Response
    {
        $id = (int)$args['id'];
        $existing = $this->db->get('post', 'id', ['id' => $id]);

        if (!$existing) {
            $res->getBody()->write('Article non trouvé');
            return $res->withStatus(404);
        }

        $this->db->delete('post', ['id' => $id]);
        return $res->withHeader('Location', '/admin')->withStatus(302);
    }
}
