<?php
declare(strict_types=1);

namespace App\Community;

use PDO;

final class HomeFeedService
{
    public function __construct(private readonly PDO $pdo) {}

    /** @return array{items:list<array<string,mixed>>,filter:string} */
    public function feed(string $filter = 'all', int $limit = 20): array
    {
        $filter = in_array($filter, ['all','questions','discussions','unanswered'], true) ? $filter : 'all';
        $limit = max(1, min(50, $limit));
        $items = [];
        if ($filter !== 'discussions') $items = array_merge($items, $this->questions($filter === 'unanswered', $limit));
        if (!in_array($filter, ['questions','unanswered'], true)) $items = array_merge($items, $this->topics($limit));
        usort($items, static fn(array $a,array $b): int => strcmp((string)($b['activity_at']??''),(string)($a['activity_at']??'')) ?: ((int)($b['id']??0) <=> (int)($a['id']??0)));
        return ['items'=>array_slice($items,0,$limit),'filter'=>$filter];
    }

    /** @return list<array<string,mixed>> */
    private function questions(bool $unanswered, int $limit): array
    {
        $extra = $unanswered ? ' AND q.answers_count=0' : '';
        $stmt=$this->pdo->query(
            "SELECT q.id,q.slug,q.title,q.body,q.votes_count,q.answers_count,q.views_count,q.best_answer_id,q.created_at,q.updated_at,
                    COALESCE(c.name,'') category_name,COALESCE(c.slug,'') category_slug,
                    CASE WHEN q.is_anonymous=1 OR u.id IS NULL THEN '' ELSE COALESCE(u.name,'') END author_name,
                    CASE WHEN q.is_anonymous=1 OR u.id IS NULL THEN '' ELSE COALESCE(u.username,'') END author_username,
                    CASE WHEN q.is_anonymous=1 OR u.id IS NULL THEN '' ELSE COALESCE(u.avatar_url,'') END author_avatar_url,
                    CASE WHEN q.is_anonymous=1 OR u.id IS NULL THEN 0 ELSE u.id END author_user_id,
                    GROUP_CONCAT(DISTINCT CONCAT(t.name,'|',t.slug) ORDER BY t.name SEPARATOR '~~') tag_pairs
             FROM questions q
             LEFT JOIN categories c ON c.id=q.category_id
             LEFT JOIN users u ON u.id=q.user_id
             LEFT JOIN question_tags qt ON qt.question_id=q.id
             LEFT JOIN tags t ON t.id=qt.tag_id
             WHERE q.status='published'{$extra}
             GROUP BY q.id
             ORDER BY COALESCE(q.updated_at,q.created_at) DESC,q.id DESC LIMIT {$limit}"
        );
        $rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
        foreach($rows as &$row){
            $row['type']='question';
            $row['activity_at']=(string)($row['updated_at']?:$row['created_at']);
            $row['tags']=$this->decodeTags((string)($row['tag_pairs']??'')); unset($row['tag_pairs']);
        }
        return $rows;
    }

    /** @return list<array<string,mixed>> */
    private function topics(int $limit): array
    {
        $stmt=$this->pdo->query(
            "SELECT t.id,t.slug,t.title,t.body,t.kind,t.is_pinned,t.is_locked,t.comments_count,t.views_count,t.created_at,t.updated_at,t.last_activity_at,
                    COALESCE(c.name,'') category_name,COALESCE(c.slug,'') category_slug,
                    COALESCE(u.name,'') author_name,COALESCE(u.username,'') author_username,COALESCE(u.avatar_url,'') author_avatar_url,COALESCE(u.id,0) author_user_id
             FROM topics t LEFT JOIN categories c ON c.id=t.category_id LEFT JOIN users u ON u.id=t.user_id
             WHERE t.status='published'
             ORDER BY COALESCE(t.last_activity_at,t.updated_at,t.created_at) DESC,t.id DESC LIMIT {$limit}"
        );
        $rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
        foreach($rows as &$row){$row['type']='discussion';$row['activity_at']=(string)($row['last_activity_at']?:($row['updated_at']?:$row['created_at']));$row['tags']=[];}
        return $rows;
    }

    /** @return list<array{name:string,slug:string}> */
    private function decodeTags(string $pairs): array
    {
        $result=[]; foreach(array_filter(explode('~~',$pairs)) as $pair){[$name,$slug]=array_pad(explode('|',$pair,2),2,'');if($name!==''&&$slug!=='')$result[]=['name'=>$name,'slug'=>$slug];} return $result;
    }
}
