<?php
require_once 'config/database.php';
require_once 'utils/helpers.php';

try {

    // Get and verify token
    $token = Helpers::getBearerToken();
    $userData = Helpers::verifyJWT($token);

    if (!$userData) {
        Helpers::sendResponse(false, 'Unauthorized access', null, 401);
    }

    $database = new Database();
    $db = $database->getConnection();

    // Verify admin access
    $query = "SELECT ur.role_level, ur.can_manage_rewards 
              FROM users u 
              JOIN user_roles ur ON u.role_id = ur.id 
              WHERE u.id = :user_id";
    $stmt = $db->prepare($query);
    $stmt->bindParam(':user_id', $userData['user_id']);
    $stmt->execute();
    $userRole = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$userRole || !$userRole['can_manage_rewards']) {
        Helpers::sendResponse(false, 'Unauthorized. Rewards management access required.', null, 403);
    }

    // GET: Retrieve rewards
    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        $includeInactive = isset($_GET['include_inactive']) ? filter_var($_GET['include_inactive'], FILTER_VALIDATE_BOOLEAN) : false;
        $rewardTypeFilter = isset($_GET['reward_type']) ? intval($_GET['reward_type']) : 0;

        $whereConditions = [];
        $params = [];

        if (!$includeInactive) {
            $whereConditions[] = "r.is_active = TRUE";
        }

        if ($rewardTypeFilter > 0) {
            $whereConditions[] = "r.reward_type_id = :reward_type";
            $params[':reward_type'] = $rewardTypeFilter;
        }

        $whereClause = count($whereConditions) > 0 ? 'WHERE ' . implode(' AND ', $whereConditions) : '';

        $query = "SELECT r.id, r.name, r.description, r.reward_type_id, 
                         rt.name as reward_type, rt.requires_certificate,
                         r.certificate_template, r.is_active, r.created_at, r.updated_at,
                         COUNT(DISTINCT sr.id) as services_count,
                         COUNT(DISTINCT usr.user_id) as users_earned,
                         SUM(CASE WHEN usr.is_redeemed = FALSE 
                             AND usr.attendance_count >= sr.attendance_required 
                             THEN 1 ELSE 0 END) as pending_redemptions
                  FROM rewards r
                  JOIN reward_types rt ON r.reward_type_id = rt.id
                  LEFT JOIN service_rewards sr ON r.id = sr.reward_id
                  LEFT JOIN users_service_rewards usr ON sr.id = usr.service_reward_id
                  $whereClause
                  GROUP BY r.id
                  ORDER BY r.created_at DESC";

        $stmt = $db->prepare($query);
        foreach ($params as $key => $value) {
            $stmt->bindValue($key, $value);
        }
        $stmt->execute();

        $rewards = $stmt->fetchAll(PDO::FETCH_ASSOC);

        Helpers::sendResponse(true, 'Rewards retrieved successfully', [
            'rewards' => $rewards,
            'count' => count($rewards)
        ]);
    }

    // POST: Create new reward
    elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $data = json_decode(file_get_contents("php://input"));

        // Validate required fields
        if (empty($data->name) || empty($data->reward_type_id)) {
            Helpers::sendResponse(false, 'Reward name and reward type are required', null, 400);
        }

        // Validate reward type exists
        $query = "SELECT id, requires_certificate FROM reward_types WHERE id = :type_id";
        $stmt = $db->prepare($query);
        $stmt->bindParam(':type_id', $data->reward_type_id);
        $stmt->execute();
        $rewardType = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$rewardType) {
            Helpers::sendResponse(false, 'Invalid reward type', null, 400);
        }

        // Insert new reward
        $query = "INSERT INTO rewards 
                  (name, description, reward_type_id, certificate_template, is_active, created_at) 
                  VALUES 
                  (:name, :description, :reward_type_id, :certificate_template, TRUE, NOW())";

        $stmt = $db->prepare($query);
        $stmt->bindParam(':name', $data->name);
        $description = $data->description ?? '';
        $stmt->bindParam(':description', $description);
        $stmt->bindParam(':reward_type_id', $data->reward_type_id);
        $certificateTemplate = $data->certificate_template ?? null;
        $stmt->bindParam(':certificate_template', $certificateTemplate);

        if ($stmt->execute()) {
            $newRewardId = $db->lastInsertId();

            // Log admin activity
            $logQuery = "INSERT INTO admin_logs 
                        (admin_id, action, action_type, target_type, target_id, details, ip_address, created_at) 
                        VALUES 
                        (:admin_id, 'create_reward', 'create', 'reward', :reward_id, :details, :ip, NOW())";

            $details = json_encode(['name' => $data->name, 'reward_type_id' => $data->reward_type_id]);
            $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';

            $stmt = $db->prepare($logQuery);
            $stmt->bindParam(':admin_id', $userData['user_id']);
            $stmt->bindParam(':reward_id', $newRewardId);
            $stmt->bindParam(':details', $details);
            $stmt->bindParam(':ip', $ip);
            $stmt->execute();

            Helpers::sendResponse(true, 'Reward created successfully', [
                'reward_id' => $newRewardId
            ], 201);
        } else {
            Helpers::sendResponse(false, 'Failed to create reward', null, 500);
        }
    }

    // PUT: Update reward
    elseif ($_SERVER['REQUEST_METHOD'] === 'PUT') {
        $rewardId = isset($_GET['id']) ? intval($_GET['id']) : null;

        if (!$rewardId) {
            Helpers::sendResponse(false, 'Reward ID is required', null, 400);
        }

        $data = json_decode(file_get_contents("php://input"));

        // Check if reward exists
        $query = "SELECT id FROM rewards WHERE id = :reward_id";
        $stmt = $db->prepare($query);
        $stmt->bindParam(':reward_id', $rewardId);
        $stmt->execute();

        if ($stmt->rowCount() === 0) {
            Helpers::sendResponse(false, 'Reward not found', null, 404);
        }

        // Build dynamic update query
        $updateFields = [];
        $params = [':reward_id' => $rewardId];

        if (isset($data->name)) {
            $updateFields[] = "name = :name";
            $params[':name'] = $data->name;
        }

        if (isset($data->description)) {
            $updateFields[] = "description = :description";
            $params[':description'] = $data->description;
        }

        if (isset($data->reward_type_id)) {
            // Validate reward type
            $checkQuery = "SELECT id FROM reward_types WHERE id = :type_id";
            $checkStmt = $db->prepare($checkQuery);
            $checkStmt->bindParam(':type_id', $data->reward_type_id);
            $checkStmt->execute();

            if ($checkStmt->rowCount() === 0) {
                Helpers::sendResponse(false, 'Invalid reward type', null, 400);
            }

            $updateFields[] = "reward_type_id = :reward_type_id";
            $params[':reward_type_id'] = $data->reward_type_id;
        }

        if (isset($data->certificate_template)) {
            $updateFields[] = "certificate_template = :certificate_template";
            $params[':certificate_template'] = $data->certificate_template;
        }

        if (isset($data->is_active)) {
            $updateFields[] = "is_active = :is_active";
            $params[':is_active'] = (bool)$data->is_active;
        }

        if (empty($updateFields)) {
            Helpers::sendResponse(false, 'No fields to update', null, 400);
        }

        $updateFields[] = "updated_at = NOW()";

        $query = "UPDATE rewards SET " . implode(', ', $updateFields) . " WHERE id = :reward_id";
        $stmt = $db->prepare($query);

        foreach ($params as $key => $value) {
            $stmt->bindValue($key, $value);
        }

        if ($stmt->execute()) {
            // Log admin activity
            $logQuery = "INSERT INTO admin_logs 
                        (admin_id, action, action_type, target_type, target_id, details, ip_address, created_at) 
                        VALUES 
                        (:admin_id, 'update_reward', 'update', 'reward', :reward_id, :details, :ip, NOW())";

            $details = json_encode($data);
            $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';

            $stmt = $db->prepare($logQuery);
            $stmt->bindParam(':admin_id', $userData['user_id']);
            $stmt->bindParam(':reward_id', $rewardId);
            $stmt->bindParam(':details', $details);
            $stmt->bindParam(':ip', $ip);
            $stmt->execute();

            Helpers::sendResponse(true, 'Reward updated successfully');
        } else {
            Helpers::sendResponse(false, 'Failed to update reward', null, 500);
        }
    }

    // DELETE: Delete reward
    elseif ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
        $rewardId = isset($_GET['id']) ? intval($_GET['id']) : null;

        if (!$rewardId) {
            Helpers::sendResponse(false, 'Reward ID is required', null, 400);
        }

        // Check if reward has been earned by users
        $query = "SELECT COUNT(*) as count 
                  FROM users_service_rewards usr
                  JOIN service_rewards sr ON usr.service_reward_id = sr.id
                  WHERE sr.reward_id = :reward_id AND usr.is_redeemed = TRUE";
        $stmt = $db->prepare($query);
        $stmt->bindParam(':reward_id', $rewardId);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($result['count'] > 0) {
            Helpers::sendResponse(false, 'Cannot delete reward that has been redeemed by users. Consider archiving instead.', null, 400);
        }

        // Get reward info before deletion
        $query = "SELECT name FROM rewards WHERE id = :reward_id";
        $stmt = $db->prepare($query);
        $stmt->bindParam(':reward_id', $rewardId);
        $stmt->execute();
        $reward = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$reward) {
            Helpers::sendResponse(false, 'Reward not found', null, 404);
        }

        // Delete reward
        $query = "DELETE FROM rewards WHERE id = :reward_id";
        $stmt = $db->prepare($query);
        $stmt->bindParam(':reward_id', $rewardId);

        if ($stmt->execute()) {
            // Log admin activity
            $logQuery = "INSERT INTO admin_logs 
                        (admin_id, action, action_type, target_type, target_id, details, ip_address, created_at) 
                        VALUES 
                        (:admin_id, 'delete_reward', 'delete', 'reward', :reward_id, :details, :ip, NOW())";

            $details = json_encode(['name' => $reward['name']]);
            $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';

            $stmt = $db->prepare($logQuery);
            $stmt->bindParam(':admin_id', $userData['user_id']);
            $stmt->bindParam(':reward_id', $rewardId);
            $stmt->bindParam(':details', $details);
            $stmt->bindParam(':ip', $ip);
            $stmt->execute();

            Helpers::sendResponse(true, 'Reward deleted successfully');
        } else {
            Helpers::sendResponse(false, 'Failed to delete reward', null, 500);
        }
    } else {
        Helpers::sendResponse(false, 'Method not allowed', null, 405);
    }
} catch (PDOException $e) {
    ErrorLogger::logDatabaseError($e, $userData['user_id'] ?? 'unknown', [
        'endpoint' => 'admin/rewards',
        'user_id' => $userData['user_id'] ?? 'unknown'
    ]);
    Helpers::sendResponse(false, 'Database error in rewards management: ' . $e->getMessage(), null, 500);
} catch (Exception $e) {
    ErrorLogger::logError($e, [
        'endpoint' => 'admin/rewards',
        'user_id' => $userData['user_id'] ?? 'unknown'
    ]);
    Helpers::sendResponse(false, 'Error in rewards management: ' . $e->getMessage(), null, 500);
}
