<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Models\Review;
use App\Models\Product;

class ReviewController extends Controller
{
    private Review $reviewModel;
    private Product $productModel;

    public function __construct()
    {
        $this->reviewModel = new Review();
        $this->productModel = new Product();
    }

    /**
     * Create a new review (POST /reviews)
     */
    public function create(): void
    {
        // Require authentication
        if (!$this->isAuthenticated()) {
            $this->json([
                'success' => false,
                'message' => 'Требуется авторизация'
            ], 401);
            return;
        }

        // Admins cannot leave reviews
        if ($this->isAdmin()) {
            $this->json([
                'success' => false,
                'message' => 'Администраторы не могут оставлять отзывы'
            ], 403);
            return;
        }

        $productId = (int) $this->getPost('product_id', 0);
        $rating = (int) $this->getPost('rating', 0);
        $comment = trim($this->getPost('comment', ''));
        $user = $this->getCurrentUser();

        // Validate product ID
        if ($productId <= 0) {
            $this->json([
                'success' => false,
                'message' => 'Неверный ID товара'
            ], 400);
            return;
        }

        // Check if product exists
        $product = $this->productModel->find($productId);
        if (!$product) {
            $this->json([
                'success' => false,
                'message' => 'Товар не найден'
            ], 404);
            return;
        }

        // Validate rating
        if ($rating < 1 || $rating > 5) {
            $this->json([
                'success' => false,
                'message' => 'Рейтинг должен быть от 1 до 5'
            ], 400);
            return;
        }

        // Check if user can review
        if (!$this->reviewModel->userCanReview($user['id'], $productId)) {
            $this->json([
                'success' => false,
                'message' => 'Вы уже оставили отзыв на этот товар'
            ], 400);
            return;
        }

        // Create review
        $reviewId = $this->reviewModel->createReview([
            'product_id' => $productId,
            'user_id' => $user['id'],
            'rating' => $rating,
            'comment' => $comment,
            'is_approved' => true
        ]);

        if ($reviewId) {
            // Get updated product info
            $updatedProduct = $this->productModel->find($productId);
            
            $this->json([
                'success' => true,
                'message' => 'Спасибо за ваш отзыв!',
                'review_id' => $reviewId,
                'product_rating' => $updatedProduct['rating'] ?? 0,
                'product_review_count' => $updatedProduct['review_count'] ?? 0
            ]);
        } else {
            $this->json([
                'success' => false,
                'message' => 'Ошибка при создании отзыва'
            ], 500);
        }
    }

    /**
     * Update a review (POST /reviews/{id})
     */
    public function update(int $id): void
    {
        // Require authentication
        if (!$this->isAuthenticated()) {
            $this->json([
                'success' => false,
                'message' => 'Требуется авторизация'
            ], 401);
            return;
        }

        $user = $this->getCurrentUser();
        $review = $this->reviewModel->find($id);

        if (!$review) {
            $this->json([
                'success' => false,
                'message' => 'Отзыв не найден'
            ], 404);
            return;
        }

        // Check ownership (only owner or admin can update)
        if ($review['user_id'] !== $user['id'] && !$this->isAdmin()) {
            $this->json([
                'success' => false,
                'message' => 'У вас нет прав для редактирования этого отзыва'
            ], 403);
            return;
        }

        $rating = (int) $this->getPost('rating', 0);
        $comment = trim($this->getPost('comment', ''));

        // Validate rating
        if ($rating < 1 || $rating > 5) {
            $this->json([
                'success' => false,
                'message' => 'Рейтинг должен быть от 1 до 5'
            ], 400);
            return;
        }

        // Update review
        $success = $this->reviewModel->updateReview($id, [
            'rating' => $rating,
            'comment' => $comment
        ]);

        if ($success) {
            // Get updated product info
            $updatedProduct = $this->productModel->find($review['product_id']);
            
            $this->json([
                'success' => true,
                'message' => 'Отзыв обновлен',
                'product_rating' => $updatedProduct['rating'] ?? 0,
                'product_review_count' => $updatedProduct['review_count'] ?? 0
            ]);
        } else {
            $this->json([
                'success' => false,
                'message' => 'Ошибка при обновлении отзыва'
            ], 500);
        }
    }

    /**
     * Delete a review (POST /reviews/{id}/delete)
     */
    public function delete(int $id): void
    {
        // Require authentication
        if (!$this->isAuthenticated()) {
            $this->json([
                'success' => false,
                'message' => 'Требуется авторизация'
            ], 401);
            return;
        }

        $user = $this->getCurrentUser();
        $review = $this->reviewModel->find($id);

        if (!$review) {
            $this->json([
                'success' => false,
                'message' => 'Отзыв не найден'
            ], 404);
            return;
        }

        // Check ownership (only owner or admin can delete)
        if ($review['user_id'] !== $user['id'] && !$this->isAdmin()) {
            $this->json([
                'success' => false,
                'message' => 'У вас нет прав для удаления этого отзыва'
            ], 403);
            return;
        }

        $productId = $review['product_id'];
        $success = $this->reviewModel->deleteReview($id);

        if ($success) {
            // Get updated product info
            $updatedProduct = $this->productModel->find($productId);
            
            $this->json([
                'success' => true,
                'message' => 'Отзыв удален',
                'product_rating' => $updatedProduct['rating'] ?? 0,
                'product_review_count' => $updatedProduct['review_count'] ?? 0
            ]);
        } else {
            $this->json([
                'success' => false,
                'message' => 'Ошибка при удалении отзыва'
            ], 500);
        }
    }

    /**
     * Get reviews for a product (GET /reviews/product/{id})
     */
    public function getByProduct(int $productId): void
    {
        $product = $this->productModel->find($productId);
        
        if (!$product) {
            $this->json([
                'success' => false,
                'message' => 'Товар не найден'
            ], 404);
            return;
        }

        $reviews = $this->reviewModel->getByProduct($productId, true);
        $distribution = $this->reviewModel->getRatingDistribution($productId);

        $this->json([
            'success' => true,
            'reviews' => $reviews,
            'rating_distribution' => $distribution,
            'average_rating' => $product['rating'] ?? 0,
            'total_reviews' => $product['review_count'] ?? 0
        ]);
    }

    /**
     * Toggle review approval (admin only) (POST /reviews/{id}/toggle-approval)
     */
    public function toggleApproval(int $id): void
    {
        $this->requireAdmin();

        $review = $this->reviewModel->find($id);
        if (!$review) {
            $this->json([
                'success' => false,
                'message' => 'Отзыв не найден'
            ], 404);
            return;
        }

        $success = $this->reviewModel->toggleApproval($id);

        if ($success) {
            $updatedReview = $this->reviewModel->find($id);
            $this->json([
                'success' => true,
                'message' => 'Статус отзыва изменен',
                'is_approved' => $updatedReview['is_approved']
            ]);
        } else {
            $this->json([
                'success' => false,
                'message' => 'Ошибка при изменении статуса'
            ], 500);
        }
    }
}

