<?php

require_once BASE_PATH . '/app/controllers/admin/AdminBaseController.php';
require_once BASE_PATH . '/app/models/Post.php';
require_once BASE_PATH . '/app/models/GalleryItem.php';

class AdminContentController extends AdminBaseController
{
    private Post $postModel;
    private GalleryItem $galleryModel;

    public function __construct()
    {
        parent::__construct();
        $this->requireAdmin();
        $this->postModel = new Post();
        $this->galleryModel = new GalleryItem();
    }

    public function index(): void
    {
        require BASE_PATH . '/app/views/admin/content/index.php';
    }

    public function products(): void
    {
        $search = trim($_GET['search'] ?? '');
        $status = trim($_GET['status'] ?? '');
        if (!in_array($status, ['', 'active', 'hidden', 'out_of_stock'], true)) {
            $status = '';
        }

        $page = max(1, (int) ($_GET['page'] ?? 1));
        $perPage = 20;
        $totalItems = $this->productModel->countForOwner($search, $status);
        $totalPages = max(1, (int) ceil($totalItems / $perPage));
        $page = min($page, $totalPages);
        $items = $this->productModel->getForOwner(
            $search,
            $status,
            $perPage,
            ($page - 1) * $perPage
        );
        $type = 'products';

        require BASE_PATH . '/app/views/admin/content/list.php';
    }

    public function posts(): void
    {
        $search = trim($_GET['search'] ?? '');
        $status = trim($_GET['status'] ?? '');
        if (!in_array($status, ['', 'draft', 'published', 'hidden'], true)) {
            $status = '';
        }

        $page = max(1, (int) ($_GET['page'] ?? 1));
        $perPage = 20;
        $totalItems = $this->postModel->countForOwner($search, $status);
        $totalPages = max(1, (int) ceil($totalItems / $perPage));
        $page = min($page, $totalPages);
        $items = $this->postModel->getForOwner(
            $search,
            $status,
            $perPage,
            ($page - 1) * $perPage
        );
        $type = 'posts';

        require BASE_PATH . '/app/views/admin/content/list.php';
    }

    public function gallery(): void
    {
        $search = trim($_GET['search'] ?? '');
        $status = trim($_GET['status'] ?? '');
        if (!in_array($status, ['', 'visible', 'hidden'], true)) {
            $status = '';
        }

        $page = max(1, (int) ($_GET['page'] ?? 1));
        $perPage = 20;
        $totalItems = $this->galleryModel->countForAdmin($search, $status);
        $totalPages = max(1, (int) ceil($totalItems / $perPage));
        $page = min($page, $totalPages);
        $items = $this->galleryModel->getForAdmin(
            $search,
            $status,
            $perPage,
            ($page - 1) * $perPage
        );
        $type = 'gallery';

        require BASE_PATH . '/app/views/admin/content/list.php';
    }

    public function reviews(): void
    {
        $search = trim($_GET['search'] ?? '');
        $status = trim($_GET['status'] ?? '');
        if (!in_array($status, ['', 'visible', 'hidden'], true)) {
            $status = '';
        }

        $page = max(1, (int) ($_GET['page'] ?? 1));
        $perPage = 20;
        $totalItems = $this->reviewModel->countForOwner($search, $status);
        $totalPages = max(1, (int) ceil($totalItems / $perPage));
        $page = min($page, $totalPages);
        $items = $this->reviewModel->getForOwner(
            $search,
            $status,
            $perPage,
            ($page - 1) * $perPage
        );
        $type = 'reviews';

        require BASE_PATH . '/app/views/admin/content/list.php';
    }

    public function updateProductStatus(): void
    {
        $this->requirePost();
        $this->validateCsrf();

        $productId = (int) ($_POST['product_id'] ?? 0);
        $action = trim($_POST['action'] ?? '');
        $product = $this->productModel->findAnyById($productId);

        if (!$product) {
            $this->invalidContentAction('Sản phẩm không tồn tại.', 'products');
        }

        if ($action === 'hide'
            && in_array($product['status'], ['active', 'out_of_stock'], true)) {
            $newStatus = 'hidden';
            $logAction = 'admin.product.hide';
        } elseif ($action === 'restore' && $product['status'] === 'hidden') {
            $newStatus = (int) $product['stock_quantity'] > 0
                ? 'active'
                : 'out_of_stock';
            $logAction = 'admin.product.restore';
        } else {
            $this->invalidContentAction('Thao tác sản phẩm không hợp lệ.', 'products');
        }

        $this->mutateAndLog(
            fn () => $this->productModel->updateModerationStatus($productId, $newStatus),
            $logAction,
            'product',
            $productId,
            [
                'old_status' => $product['status'],
                'new_status' => $newStatus
            ]
        );
        $this->flashSuccess('Đã cập nhật trạng thái sản phẩm.');
        $this->redirect('admin/moderation/products');
    }

    public function updatePostStatus(): void
    {
        $this->requirePost();
        $this->validateCsrf();

        $postId = (int) ($_POST['post_id'] ?? 0);
        $action = trim($_POST['action'] ?? '');
        $post = $this->postModel->findById($postId);

        if (!$post) {
            $this->invalidContentAction('Bài viết không tồn tại.', 'posts');
        }

        if ($action === 'hide' && $post['status'] === 'published') {
            $newStatus = 'hidden';
            $logAction = 'admin.post.hide';
        } elseif ($action === 'restore'
            && $post['status'] === 'hidden'
            && !empty($post['published_at'])) {
            $newStatus = 'published';
            $logAction = 'admin.post.restore';
        } else {
            $this->invalidContentAction(
                'Chỉ có thể khôi phục bài viết đã từng được xuất bản.',
                'posts'
            );
        }

        $this->mutateAndLog(
            fn () => $this->postModel->updateModerationStatus($postId, $newStatus),
            $logAction,
            'post',
            $postId,
            [
                'old_status' => $post['status'],
                'new_status' => $newStatus
            ]
        );
        $this->flashSuccess('Đã cập nhật trạng thái bài viết.');
        $this->redirect('admin/moderation/posts');
    }

    public function updateGalleryStatus(): void
    {
        $this->requirePost();
        $this->validateCsrf();

        $galleryId = (int) ($_POST['gallery_id'] ?? 0);
        $status = trim($_POST['status'] ?? '');
        $item = $this->galleryModel->findById($galleryId);
        $visible = $status === 'visible';

        if (!$item || !in_array($status, ['visible', 'hidden'], true)) {
            $this->invalidContentAction('Dữ liệu Gallery không hợp lệ.', 'gallery');
        }

        if ((int) $item['is_visible'] === (int) $visible) {
            $this->invalidContentAction('Gallery đã ở trạng thái được chọn.', 'gallery');
        }

        $this->mutateAndLog(
            fn () => $this->galleryModel->setVisibility($galleryId, $visible),
            $visible ? 'admin.gallery.show' : 'admin.gallery.hide',
            'gallery',
            $galleryId,
            [
                'old_status' => (int) $item['is_visible'] === 1 ? 'visible' : 'hidden',
                'new_status' => $status
            ]
        );
        $this->flashSuccess('Đã cập nhật trạng thái Gallery.');
        $this->redirect('admin/moderation/gallery');
    }

    public function updateReviewStatus(): void
    {
        $this->requirePost();
        $this->validateCsrf();

        $reviewId = (int) ($_POST['review_id'] ?? 0);
        $status = trim($_POST['status'] ?? '');
        $review = $this->reviewModel->findById($reviewId);

        if (!$review || !in_array($status, ['visible', 'hidden'], true)
            || $review['status'] === $status) {
            $this->invalidContentAction('Dữ liệu đánh giá không hợp lệ.', 'reviews');
        }

        $this->mutateAndLog(
            fn () => $this->reviewModel->updateModerationStatus($reviewId, $status),
            $status === 'hidden' ? 'admin.review.hide' : 'admin.review.show',
            'review',
            $reviewId,
            [
                'old_status' => $review['status'],
                'new_status' => $status
            ]
        );
        $this->flashSuccess('Đã cập nhật trạng thái đánh giá.');
        $this->redirect('admin/moderation/reviews');
    }

    private function invalidContentAction(string $message, string $route): never
    {
        $this->flashError($message);
        $this->redirect('admin/moderation/' . $route);
    }
}
