<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Models\Product;
use App\Models\Category;
use App\Models\Order;
use App\Models\User;

class AdminController extends Controller
{
    private Product $productModel;
    private Category $categoryModel;
    private Order $orderModel;
    private User $userModel;

    public function __construct()
    {
        $this->productModel = new Product();
        $this->categoryModel = new Category();
        $this->orderModel = new Order();
        $this->userModel = new User();
    }

    public function dashboard(): void
    {
        $this->requireAdmin();

        $stats = [
            'total_products' => $this->productModel->count(),
            'active_products' => $this->productModel->count(['is_available' => true]),
            'total_orders' => $this->orderModel->count(),
            'total_users' => $this->userModel->count(),
            'revenue' => $this->orderModel->getStats()['revenue']
        ];

        $this->view('admin/dashboard', [
            'stats' => $stats,
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function products(): void
    {
        $this->requireAdmin();

        $showAll = $this->getQuery('show_all') === '1';
        $products = $this->productModel->getAllForAdmin($showAll);

        $this->view('admin/products/index', [
            'products' => $products,
            'showAll' => $showAll,
            'message' => $this->getQuery('message'),
            'error' => $this->getQuery('error'),
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function addProduct(): void
    {
        $this->requireAdmin();

        $categories = $this->categoryModel->getActive();

        $this->view('admin/products/form', [
            'product' => null,
            'categories' => $categories,
            'action' => 'add',
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function storeProduct(): void
    {
        $this->requireAdmin();

        $data = [
            'name' => $this->getPost('name'),
            'category_id' => (int) $this->getPost('category_id'),
            'description' => $this->getPost('description'),
            'price' => (float) $this->getPost('price'),
            'old_price' => $this->getPost('old_price') ? (float) $this->getPost('old_price') : null,
            'sku' => $this->getPost('sku'),
            'stock_quantity' => (int) $this->getPost('stock_quantity', 0),
            'is_available' => $this->getPost('is_available') ? true : false,
            'is_featured' => $this->getPost('is_featured') ? true : false,
            'image_url' => $this->getPost('image_url'),
            'color' => $this->getPost('color'),
            'material' => $this->getPost('material'),
            'card_size' => $this->getPost('card_size', 'small')
        ];

        try {
            $this->productModel->createProduct($data);
            $this->redirect('/admin/products?message=' . urlencode('Товар успешно добавлен'));
        } catch (\Exception $e) {
            $this->redirect('/admin/products/add?error=' . urlencode($e->getMessage()));
        }
    }

    public function editProduct(int $id): void
    {
        $this->requireAdmin();

        $product = $this->productModel->find($id);
        
        if (!$product) {
            $this->redirect('/admin/products?error=' . urlencode('Товар не найден'));
            return;
        }

        $categories = $this->categoryModel->getActive();

        $this->view('admin/products/form', [
            'product' => $product,
            'categories' => $categories,
            'action' => 'edit',
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function updateProduct(int $id): void
    {
        $this->requireAdmin();

        $data = [
            'name' => $this->getPost('name'),
            'category_id' => (int) $this->getPost('category_id'),
            'description' => $this->getPost('description'),
            'price' => (float) $this->getPost('price'),
            'old_price' => $this->getPost('old_price') ? (float) $this->getPost('old_price') : null,
            'stock_quantity' => (int) $this->getPost('stock_quantity', 0),
            'is_available' => $this->getPost('is_available') ? true : false,
            'image_url' => $this->getPost('image_url'),
            'color' => $this->getPost('color'),
            'material' => $this->getPost('material')
        ];

        try {
            $this->productModel->updateProduct($id, $data);
            $this->redirect('/admin/products?message=' . urlencode('Товар обновлен'));
        } catch (\Exception $e) {
            $this->redirect('/admin/products/edit/' . $id . '?error=' . urlencode($e->getMessage()));
        }
    }

    public function deleteProduct(int $id): void
    {
        $this->requireAdmin();

        $this->productModel->update($id, ['is_available' => false]);
        $this->redirect('/admin/products?message=' . urlencode('Товар скрыт'));
    }

    public function removeProduct(int $id): void
    {
        $this->requireAdmin();

        $product = $this->productModel->find($id);
        
        if (!$product) {
            $this->redirect('/admin/products?error=' . urlencode('Товар не найден'));
            return;
        }

        // Удаляем только если товара нет на складе
        if ($product['stock_quantity'] > 0) {
            $this->redirect('/admin/products?error=' . urlencode('Нельзя удалить товар, который есть на складе'));
            return;
        }

        // Полное удаление из БД
        $this->productModel->delete($id);
        $this->redirect('/admin/products?message=' . urlencode('Товар удален из базы данных'));
    }

    public function categories(): void
    {
        $this->requireAdmin();

        $categories = $this->categoryModel->getAllWithProductCount();

        $this->view('admin/categories/index', [
            'categories' => $categories,
            'message' => $this->getQuery('message'),
            'error' => $this->getQuery('error'),
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function addCategory(): void
    {
        $this->requireAdmin();

        $parentCategories = $this->categoryModel->getParent();

        $this->view('admin/categories/form', [
            'category' => null,
            'parentCategories' => $parentCategories,
            'action' => 'add',
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function storeCategory(): void
    {
        $this->requireAdmin();

        $data = [
            'name' => $this->getPost('name'),
            'parent_id' => $this->getPost('parent_id') ? (int) $this->getPost('parent_id') : null,
            'description' => $this->getPost('description'),
            'sort_order' => (int) $this->getPost('sort_order', 0),
            'is_active' => $this->getPost('is_active') ? true : false
        ];

        try {
            $this->categoryModel->createCategory($data);
            $this->redirect('/admin/categories?message=' . urlencode('Категория добавлена'));
        } catch (\Exception $e) {
            $this->redirect('/admin/categories/add?error=' . urlencode($e->getMessage()));
        }
    }

    public function editCategory(int $id): void
    {
        $this->requireAdmin();

        $category = $this->categoryModel->find($id);
        
        if (!$category) {
            $this->redirect('/admin/categories?error=' . urlencode('Категория не найдена'));
            return;
        }

        $parentCategories = $this->categoryModel->getParent();

        $this->view('admin/categories/form', [
            'category' => $category,
            'parentCategories' => $parentCategories,
            'action' => 'edit',
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function updateCategory(int $id): void
    {
        $this->requireAdmin();

        $data = [
            'name' => $this->getPost('name'),
            'parent_id' => $this->getPost('parent_id') ? (int) $this->getPost('parent_id') : null,
            'description' => $this->getPost('description'),
            'sort_order' => (int) $this->getPost('sort_order', 0),
            'is_active' => $this->getPost('is_active') ? true : false
        ];

        try {
            $this->categoryModel->updateCategory($id, $data);
            $this->redirect('/admin/categories?message=' . urlencode('Категория обновлена'));
        } catch (\Exception $e) {
            $this->redirect('/admin/categories/edit/' . $id . '?error=' . urlencode($e->getMessage()));
        }
    }

    public function deleteCategory(int $id): void
    {
        $this->requireAdmin();

        $result = $this->categoryModel->safeDelete($id);

        if ($result['deleted']) {
            $this->redirect('/admin/categories?message=' . urlencode('Категория удалена'));
        } else {
            $msg = $result['reason'] === 'has_products' 
                ? 'Категория скрыта (содержит товары)' 
                : 'Категория скрыта (имеет дочерние категории)';
            $this->redirect('/admin/categories?message=' . urlencode($msg));
        }
    }

    public function orders(): void
    {
        $this->requireAdmin();

        $orders = $this->orderModel->getAllForAdmin();

        $this->view('admin/orders/index', [
            'orders' => $orders,
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function orderDetails(int $id): void
    {
        $this->requireAdmin();

        $order = $this->orderModel->getWithDetails($id);

        if (!$order) {
            $this->redirect('/admin/orders?error=' . urlencode('Заказ не найден'));
            return;
        }

        $this->view('admin/orders/details', [
            'order' => $order,
            'user' => $this->getCurrentUser()
        ], 'admin');
    }

    public function updateOrderStatus(int $id): void
    {
        $this->requireAdmin();

        $status = $this->getPost('status');
        $this->orderModel->updateStatus($id, $status);

        $this->redirect('/admin/orders/' . $id);
    }

    public function users(): void
    {
        $this->requireAdmin();

        $users = $this->userModel->getAllPaginated();

        $this->view('admin/users/index', [
            'users' => $users,
            'user' => $this->getCurrentUser()
        ], 'admin');
    }
}
