<?php
declare(strict_types=1);

namespace Controllers;

use Helpers\Auth;
use Helpers\Request;
use Helpers\Response;
use Config\Database;

final class AdminUserController
{
    private function admin(): void
    {
        $u = Auth::requireUser();
        if (!Auth::isAdmin($u)) throw new \RuntimeException('Admin access required');
    }

    public function index(): never
    {
        try {
            $this->admin();
            $q = Request::query();
            $db = Database::connection();
            $where = ['1=1']; $params = [];
            if (!empty($q['search'])) {
                $where[] = '(name LIKE :s OR email LIKE :s OR phone LIKE :s)';
                $params['s'] = '%' . $q['search'] . '%';
            }
            if (!empty($q['role'])) { $where[] = 'role=:role'; $params['role'] = $q['role']; }
            $limit = max(1, min(100, (int)($q['limit'] ?? 50)));
            $offset = max(0, ((int)($q['page'] ?? 1) - 1) * $limit);
            $sql = 'SELECT id,name,email,phone,role,status,created_at FROM users WHERE ' . implode(' AND ', $where) . ' ORDER BY created_at DESC LIMIT ' . $limit . ' OFFSET ' . $offset;
            $stmt = $db->prepare($sql);
            $stmt->execute($params);
            Response::success($stmt->fetchAll());
        } catch (\Throwable $e) {
            Response::error($e->getMessage(), str_contains($e->getMessage(), 'Admin') || str_contains($e->getMessage(), 'Auth') ? 401 : 500);
        }
    }

    public function show(string $id): never
    {
        try {
            $this->admin();
            $db = Database::connection();
            $stmt = $db->prepare('SELECT id,name,email,phone,role,status,created_at FROM users WHERE id=:id LIMIT 1');
            $stmt->execute(['id' => (int)$id]);
            $user = $stmt->fetch();
            if (!$user) Response::error('User not found', 404);
            $oStmt = $db->prepare('SELECT id,order_number,total_amount,order_status,payment_status,created_at FROM orders WHERE user_id=:uid ORDER BY created_at DESC LIMIT 20');
            $oStmt->execute(['uid' => (int)$id]);
            $user['orders'] = $oStmt->fetchAll();
            Response::success($user);
        } catch (\Throwable $e) {
            Response::error($e->getMessage(), str_contains($e->getMessage(), 'Admin') || str_contains($e->getMessage(), 'Auth') ? 401 : 500);
        }
    }

    public function updateRole(string $id): never
    {
        try {
            $this->admin();
            $data = Request::input();
            $role = $data['role'] ?? '';
            if (!in_array($role, ['customer', 'admin', 'manager'], true)) {
                Response::error('Invalid role', 422);
            }
            $db = Database::connection();
            $stmt = $db->prepare('UPDATE users SET role=:role WHERE id=:id');
            $stmt->execute(['role' => $role, 'id' => (int)$id]);
            Response::success([], 'User role updated');
        } catch (\Throwable $e) {
            Response::error($e->getMessage(), str_contains($e->getMessage(), 'Admin') || str_contains($e->getMessage(), 'Auth') ? 401 : 500);
        }
    }

    public function updateStatus(string $id): never
    {
        try {
            $this->admin();
            $data = Request::input();
            $status = $data['status'] ?? '';
            if (!in_array($status, ['active', 'inactive'], true)) {
                Response::error('Invalid status', 422);
            }
            $db = Database::connection();
            $stmt = $db->prepare('UPDATE users SET status=:status WHERE id=:id');
            $stmt->execute(['status' => $status, 'id' => (int)$id]);
            Response::success([], 'User status updated');
        } catch (\Throwable $e) {
            Response::error($e->getMessage(), str_contains($e->getMessage(), 'Admin') || str_contains($e->getMessage(), 'Auth') ? 401 : 500);
        }
    }
}
