<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Helpers\Auth;
use App\Helpers\Url;
use App\Models\ForumCategory;
use App\Models\ForumTopic;
use App\Models\ForumPost;
use App\Models\AuditLog;

class ForumController extends Controller
{
    public function __construct()
    {
        parent::__construct();
    }

    private function isModerator()
    {
        $role = Auth::user()->role ?? '';
        return $role === 'admin' || $role === 'editor';
    }

    private function handleMediaUpload($fieldName)
    {
        if (empty($_FILES[$fieldName]) || $_FILES[$fieldName]['error'] !== UPLOAD_ERR_OK) {
            return null;
        }

        $file = $_FILES[$fieldName];
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        $allowed = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'zip'];

        if (!in_array($ext, $allowed)) {
            return null;
        }

        $filename = 'forum_' . uniqid() . '_' . time() . '.' . $ext;
        $base = Url::getBaseUrl();
        $dest = $_SERVER['DOCUMENT_ROOT'] . $base . '/uploads/forum/' . $filename;
        move_uploaded_file($file['tmp_name'], $dest);

        return json_encode([
            'filename' => $filename,
            'original_name' => $file['name'],
            'type' => $ext,
            'size' => $file['size'],
            'path' => '/uploads/forum/' . $filename,
        ]);
    }

    public function index()
    {
        $categoryModel = new ForumCategory();
        $topicModel = new ForumTopic();
        $categories = $categoryModel->getActive();
        $recentTopics = $topicModel->getRecent(5);

        $this->view('forum/index', [
            'categories' => $categories,
            'recentTopics' => $recentTopics,
        ]);
    }

    public function category($params)
    {
        $catId = $params['id'] ?? null;
        $page = $_GET['page'] ?? 1;

        $categoryModel = new ForumCategory();
        $topicModel = new ForumTopic();

        $category = $categoryModel->find($catId);
        if (!$category) {
            $_SESSION['error'] = 'Category not found';
            $this->redirect('/forum');
        }

        $topics = $topicModel->getByCategory($catId, (int)$page);

        $this->view('forum/category', [
            'category' => $category,
            'topics' => $topics,
            'page' => (int)$page,
        ]);
    }

    public function topic($params)
    {
        $topicId = $params['id'] ?? null;
        $topicModel = new ForumTopic();
        $postModel = new ForumPost();

        $topic = $topicModel->getWithPosts($topicId);
        if (!$topic) {
            $_SESSION['error'] = 'Topic not found';
            $this->redirect('/forum');
        }

        $topicModel->incrementViews($topicId);
        $posts = $postModel->getByTopic($topicId);

        $this->view('forum/topic', [
            'topic' => $topic,
            'posts' => $posts,
        ]);
    }

    public function createTopic($params)
    {
        Auth::requireLogin();
        $catId = $params['id'] ?? null;
        $categoryModel = new ForumCategory();
        $category = $categoryModel->find($catId);

        if (!$category) {
            $_SESSION['error'] = 'Category not found';
            $this->redirect('/forum');
        }

        $this->view('forum/create_topic', ['category' => $category]);
    }

    public function storeTopic()
    {
        Auth::requireLogin();

        $categoryId = $_POST['category_id'] ?? null;
        $title = $_POST['title'] ?? '';
        $body = $_POST['body'] ?? '';

        if (empty($title) || empty($body)) {
            $_SESSION['error'] = 'Title and body are required';
            $this->redirect('/forum/category/' . $categoryId);
        }

        $media = $this->handleMediaUpload('media');

        $topicModel = new ForumTopic();
        $topicId = $topicModel->create([
            'category_id' => $categoryId,
            'user_id' => Auth::id(),
            'title' => $title,
            'body' => $body,
            'media' => $media,
            'last_post_at' => date('Y-m-d H:i:s'),
            'last_post_by' => Auth::id(),
        ]);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'forum.create_topic', 'forum_topics', $topicId, "Created forum topic: {$title}");

        $_SESSION['success'] = 'Topic created successfully';
        $this->redirect('/forum/topic/' . $topicId);
    }

    public function reply($params)
    {
        Auth::requireLogin();

        $topicId = $params['id'] ?? null;

        $topicModel = new ForumTopic();
        $topic = $topicModel->find($topicId);

        if (!$topic || $topic->status !== 'active') {
            $_SESSION['error'] = 'Topic not found';
            $this->redirect('/forum');
        }

        if ($topic->is_locked && !$this->isModerator()) {
            $_SESSION['error'] = 'This topic is locked';
            $this->redirect('/forum/topic/' . $topicId);
        }

        $body = $_POST['body'] ?? '';

        if (empty($body)) {
            $_SESSION['error'] = 'Reply body is required';
            $this->redirect('/forum/topic/' . $topicId);
        }

        $media = $this->handleMediaUpload('media');

        $postModel = new ForumPost();
        $postModel->create([
            'topic_id' => $topicId,
            'user_id' => Auth::id(),
            'body' => $body,
            'media' => $media,
        ]);

        $topicModel->update($topicId, [
            'last_post_at' => date('Y-m-d H:i:s'),
            'last_post_by' => Auth::id(),
        ]);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'forum.reply', 'forum_posts', $topicId, "Replied to forum topic");

        $_SESSION['success'] = 'Reply posted successfully';
        $this->redirect('/forum/topic/' . $topicId);
    }

    public function deletePost($params)
    {
        Auth::requireLogin();
        if (!$this->isModerator()) {
            $_SESSION['error'] = 'Access denied';
            $this->redirect('/forum');
        }

        $postId = $params['id'] ?? null;
        $postModel = new ForumPost();
        $post = $postModel->find($postId);

        if (!$post) {
            $_SESSION['error'] = 'Post not found';
            $this->redirect('/forum');
        }

        $postModel->softDelete($postId);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'forum.delete_post', 'forum_posts', $postId, "Deleted forum post #{$postId} in topic #{$post->topic_id}");

        $_SESSION['success'] = 'Post deleted';
        $this->redirect('/forum/topic/' . $post->topic_id);
    }

    public function deleteTopic($params)
    {
        Auth::requireLogin();
        if (!$this->isModerator()) {
            $_SESSION['error'] = 'Access denied';
            $this->redirect('/forum');
        }

        $topicId = $params['id'] ?? null;
        $topicModel = new ForumTopic();
        $topic = $topicModel->find($topicId);

        if (!$topic) {
            $_SESSION['error'] = 'Topic not found';
            $this->redirect('/forum');
        }

        $topicModel->softDelete($topicId);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'forum.delete_topic', 'forum_topics', $topicId, "Deleted forum topic: {$topic->title}");

        $_SESSION['success'] = 'Topic deleted';
        $this->redirect('/forum/category/' . $topic->category_id);
    }

    public function togglePin($params)
    {
        Auth::requireLogin();
        if (!$this->isModerator()) {
            $_SESSION['error'] = 'Access denied';
            $this->redirect('/forum');
        }

        $topicId = $params['id'] ?? null;
        $topicModel = new ForumTopic();
        $topic = $topicModel->find($topicId);

        if (!$topic) {
            $_SESSION['error'] = 'Topic not found';
            $this->redirect('/forum');
        }

        $topicModel->togglePin($topicId);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'forum.toggle_pin', 'forum_topics', $topicId, "Toggled pin on topic: {$topic->title}");

        $_SESSION['success'] = 'Topic pin status toggled';
        $this->redirect('/forum/category/' . $topic->category_id);
    }

    public function toggleLock($params)
    {
        Auth::requireLogin();
        if (!$this->isModerator()) {
            $_SESSION['error'] = 'Access denied';
            $this->redirect('/forum');
        }

        $topicId = $params['id'] ?? null;
        $topicModel = new ForumTopic();
        $topic = $topicModel->find($topicId);

        if (!$topic) {
            $_SESSION['error'] = 'Topic not found';
            $this->redirect('/forum');
        }

        $topicModel->toggleLock($topicId);

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'forum.toggle_lock', 'forum_topics', $topicId, "Toggled lock on topic: {$topic->title}");

        if ($topic->is_locked) {
            $_SESSION['success'] = 'Topic unlocked';
        } else {
            $_SESSION['success'] = 'Topic locked';
        }
        $this->redirect('/forum/category/' . $topic->category_id);
    }
}
