<?php
declare(strict_types=1);

namespace App\Models;

use PDO;

class CommunityComment extends BaseModel
{
    protected string $table = 'community_comments';

    public function createForPost(int $postId, int $userId, string $content, string $status, int $riskScore = 0, ?int $parentId = null): array
    {
        $status = in_array($status, ['published', 'pending_review', 'blocked', 'deleted'], true) ? $status : 'published';
        $riskScore = min(100, max(0, $riskScore));

        $statement = $this->db()->prepare(
            'INSERT INTO community_comments
                (post_id, user_id, parent_id, content, status, risk_score, created_at, updated_at)
             VALUES
                (:post_id, :user_id, :parent_id, :content, :status, :risk_score, NOW(), NOW())'
        );
        $statement->execute([
            'post_id' => $postId,
            'user_id' => $userId,
            'parent_id' => $parentId,
            'content' => $content,
            'status' => $status,
            'risk_score' => $riskScore,
        ]);

        return $this->findDetailed((int) $this->db()->lastInsertId()) ?? [];
    }

    public function listForPost(int $postId, int $limit = 40): array
    {
        $limit = min(max($limit, 1), 100);
        $statement = $this->db()->prepare($this->baseSelect() . ' WHERE cc.post_id = :post_id AND cc.status IN ("published", "visible") AND cc.deleted_at IS NULL ORDER BY cc.parent_id IS NOT NULL ASC, cc.created_at DESC LIMIT :limit');
        $statement->bindValue('post_id', $postId, PDO::PARAM_INT);
        $statement->bindValue('limit', $limit, PDO::PARAM_INT);
        $statement->execute();

        return array_map(fn (array $row): array => $this->normalize($row), $statement->fetchAll());
    }

    public function findDetailed(int $commentId): ?array
    {
        $statement = $this->db()->prepare($this->baseSelect() . ' WHERE cc.id = :id LIMIT 1');
        $statement->execute(['id' => $commentId]);
        $row = $statement->fetch();

        return $row ? $this->normalize($row) : null;
    }

    public function softDelete(int $commentId, int $userId, bool $isAdmin = false): bool
    {
        $sql = 'UPDATE community_comments SET status = "deleted", deleted_at = NOW(), updated_at = NOW() WHERE id = :id';
        $params = ['id' => $commentId];
        if (!$isAdmin) {
            $sql .= ' AND user_id = :user_id';
            $params['user_id'] = $userId;
        }

        $statement = $this->db()->prepare($sql);
        $statement->execute($params);

        return $statement->rowCount() > 0;
    }

    private function baseSelect(): string
    {
        return 'SELECT cc.*,
                       u.username,
                       COALESCE(NULLIF(up.display_name, ""), NULLIF(u.nickname, ""), u.username, "User") AS display_name,
                       COALESCE(NULLIF(up.nickname, ""), u.username) AS nickname,
                       COALESCE(NULLIF(up.avatar, ""), "") AS avatar
                FROM community_comments cc
                LEFT JOIN users u ON u.id = cc.user_id
                LEFT JOIN user_profiles up ON up.user_id = u.id';
    }

    private function normalize(array $row): array
    {
        return [
            'id' => (int) ($row['id'] ?? 0),
            'post_id' => (int) ($row['post_id'] ?? 0),
            'user_id' => (int) ($row['user_id'] ?? 0),
            'parent_id' => isset($row['parent_id']) && $row['parent_id'] !== null ? (int) $row['parent_id'] : null,
            'content' => (string) ($row['content'] ?? ''),
            'status' => (string) ($row['status'] ?? 'published'),
            'risk_score' => (int) ($row['risk_score'] ?? 0),
            'created_at' => (string) ($row['created_at'] ?? ''),
            'updated_at' => (string) ($row['updated_at'] ?? ''),
            'username' => (string) ($row['username'] ?? 'user'),
            'display_name' => (string) ($row['display_name'] ?? 'User'),
            'nickname' => (string) ($row['nickname'] ?? $row['username'] ?? 'user'),
            'avatar' => (string) ($row['avatar'] ?? ''),
        ];
    }
}
