<?php
require_once '../../config.php';
require_once '../../functions.php';

header('Content-Type: application/json');

// Check method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['status' => 'error', 'message' => 'Method Not Allowed']);
    exit;
}

// Check Auth
if (!isset($_SESSION['user_id']) && !isset($_SESSION['admin_id'])) {
    http_response_code(401);
    echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
    exit;
}

// Determine user/admin ID
$user_id = $_SESSION['user_id'] ?? null;
// If admin is logged in but user_id is set (e.g. admin impersonating), prioritize role check if needed.
// For now, if admin_id is set and user_id is null, act as admin.
$is_admin = isset($_SESSION['admin_id']);
$role = $is_admin ? 'admin' : 'user';

$mobile_number = $_POST['mobile_number'] ?? '';
$contact_groups = $_POST['contact_group'] ?? [];
$msg_body = $_POST['message'] ?? '';

// Validate Input: Either mobile_number OR contact_group must be provided
if ((empty($mobile_number) && empty($contact_groups)) || empty($msg_body)) {
    echo json_encode(['status' => 'error', 'message' => 'Please provide either Mobile Numbers or Contact Groups, and a Message.']);
    exit;
}

// ---------------------------------------------------------
// NEW: Handle Multiple Numbers (Array or Comma Separated)
// ---------------------------------------------------------
$recipients = [];

if (is_array($mobile_number)) {
    // If sent as array (e.g. from Select2 multiple)
    $recipients = $mobile_number;
} else {
    // If comma or space separated
    // Replace spaces with commas to normalize if needed, or just explode
    $mobile_number = str_replace(' ', ',', $mobile_number);
    $recipients = explode(',', $mobile_number);
}

// Filter empty and trim
$recipients = array_map('trim', $recipients);
$recipients = array_filter($recipients); // Remove empty
$recipients = array_unique($recipients); // Duplicate check

// ---------------------------------------------------------
// NEW: Expand Groups (grp_ID)
// ---------------------------------------------------------
// ---------------------------------------------------------
// NEW: Handle Separate Contact Groups
// ---------------------------------------------------------
$final_recipients = [];
if (isset($_POST['contact_group']) && is_array($_POST['contact_group'])) {
    foreach ($_POST['contact_group'] as $group_id) {
        $group_id = trim($group_id);
        if (empty($group_id))
            continue;

        // Secure Fetch: Users can only send to their own groups
        if ($role === 'user') {
            $gStmt = $pdo->prepare("
                SELECT m.phone_number 
                FROM contact_group_members m 
                JOIN contact_groups g ON m.group_id = g.id 
                WHERE m.group_id = ? AND g.owner_type = 'user' AND g.owner_id = ?
            ");
            $gStmt->execute([$group_id, $user_id]);
        } else {
            // Admin can send to any group
            $gStmt = $pdo->prepare("SELECT phone_number FROM contact_group_members WHERE group_id = ?");
            $gStmt->execute([$group_id]);
        }
        $members = $gStmt->fetchAll(PDO::FETCH_COLUMN);
        foreach ($members as $m) {
            $final_recipients[] = trim($m);
        }
    }
}

// ---------------------------------------------------------
// Support Legacy Mixed Input (grp_ prefix) - Optional but good for safety
// ---------------------------------------------------------
foreach ($recipients as $item) {
    if (strpos($item, 'grp_') === 0) {
        // It's a group (Legacy/Fallback)
        $group_id = substr($item, 4);
        // Same Security Logic
        if ($role === 'user') {
            $gStmt = $pdo->prepare("
                SELECT m.phone_number 
                FROM contact_group_members m 
                JOIN contact_groups g ON m.group_id = g.id 
                WHERE m.group_id = ? AND g.owner_type = 'user' AND g.owner_id = ?
            ");
            $gStmt->execute([$group_id, $user_id]);
        } else {
            $gStmt = $pdo->prepare("SELECT phone_number FROM contact_group_members WHERE group_id = ?");
            $gStmt->execute([$group_id]);
        }
        $members = $gStmt->fetchAll(PDO::FETCH_COLUMN);
        foreach ($members as $m) {
            $final_recipients[] = trim($m);
        }
    } else {
        $final_recipients[] = $item;
    }
}
$recipients = array_unique($final_recipients);

if (count($recipients) === 0) {
    echo json_encode(['status' => 'error', 'message' => 'No valid recipients found.']);
    exit;
}

try {
    $total_cost = 0;
    $sms_cost_per_unit = 0.05;

    if ($role === 'user') {
        // User Logic: Global Balance is used, no internal deduction.
        // Logic removed as per new requirement.
    }

    $success_count = 0;
    $fail_count = 0;
    $last_response_msg = "";

    // ---------------------------------------------------------
    // NEW: Fetch Active Endpoints
    // ---------------------------------------------------------
    $endpoints = [];
    try {
        $stmt = $pdo->query("SELECT message_data FROM endpoints WHERE status = 1 ORDER BY id ASC");
        $endpoints = $stmt->fetchAll(PDO::FETCH_COLUMN);
    } catch (Exception $e) {
    }

    $num_endpoints = count($endpoints);

    // ---------------------------------------------------------
    // NEW: Get Rotation State (Stateful)
    // ---------------------------------------------------------
    $current_owner_id = ($role === 'user') ? $user_id : ($_SESSION['admin_id'] ?? 1); // Default admin ID 1 if missing
    $current_owner_type = $role;
    $last_endpoint_index = -1;

    if ($num_endpoints > 0) {
        try {
            $stmt = $pdo->prepare("SELECT last_endpoint_index FROM endpoint_state WHERE owner_id = ? AND owner_type = ?");
            $stmt->execute([$current_owner_id, $current_owner_type]);
            $row = $stmt->fetch();
            if ($row) {
                $last_endpoint_index = (int) $row['last_endpoint_index'];
            } else {
                // Initialize if not exists
                $pdo->prepare("INSERT IGNORE INTO endpoint_state (owner_id, owner_type, last_endpoint_index) VALUES (?, ?, -1)")
                    ->execute([$current_owner_id, $current_owner_type]);
            }
        } catch (Exception $e) {
        }
    }

    // Capture the latest index to save back to DB after batch
    $latest_used_index = $last_endpoint_index;

    // ---------------------------------------------------------
    // OPTIMIZATION: CLOSE DB CONNECTION BEFORE SENDING LOOP
    // ---------------------------------------------------------
    // The previous connection is held by $pdo from config.php
    $pdo = null;

    // Buffer for logs to save later
    $sms_results_buffer = [];

    // Loop and Send (NETWORK PHASE - NO DB)
    foreach ($recipients as $recipient_number) {

        $final_msg_body = $msg_body;

        // Apply Endpoint Rotation if available
        if ($num_endpoints > 0) {
            // Strictly sequential: next index is last + 1
            $check_index = $latest_used_index + 1;

            // Wrap around using modulo
            $rotation_idx = $check_index % $num_endpoints;

            $endpoint = $endpoints[$rotation_idx];
            $final_msg_body .= " " . $endpoint;

            // Update local tracker
            $latest_used_index = $check_index;
        }

        // 1. Send SMS API (One by One for robust logging)
        $api_response = send_sms_single($recipient_number, $final_msg_body);
        $status = (strpos($api_response, '202') !== false) ? 'sent' : 'failed';

        // Capture result for logging
        $sms_results_buffer[] = [
            'recipient' => $recipient_number,
            'message' => $final_msg_body,
            'status' => $status,
            'api_response' => $api_response
        ];

        // Capture last message for simple response
        $last_response_msg = get_sms_error_message($api_response);
    }

    // ---------------------------------------------------------
    // OPTIMIZATION: RE-OPEN DB CONNECTION FOR LOGGING
    // ---------------------------------------------------------
    try {
        $dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4";
        $pdo = new PDO($dsn, DB_USER, DB_PASS);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        // If we can't recommend, we lose logs, but SMS was sent.
        // In a real app we might write to a local file as fallback.
        die("Database Re-Connection Failed: " . $e->getMessage());
    }

    // Process Logs (DATABASE PHASE - BATCH/FAST)
    foreach ($sms_results_buffer as $res) {
        $status = $res['status'];

        // Log Result
        $log_user_id = ($role === 'user') ? $user_id : null;
        $owner_id = ($role === 'user') ? $user_id : ($_SESSION['admin_id'] ?? 0);

        log_sms($log_user_id, SMS_SENDER_ID, $res['recipient'], $res['message'], $status, $res['api_response'], $role, $owner_id);

        if ($status === 'sent') {
            $success_count++;
        } else {
            $fail_count++;
        }
    }

    // ---------------------------------------------------------
    // NEW: Save Rotation State
    // ---------------------------------------------------------
    if ($num_endpoints > 0 && $latest_used_index > $last_endpoint_index) {
        try {
            $stmt = $pdo->prepare("UPDATE endpoint_state SET last_endpoint_index = ? WHERE owner_id = ? AND owner_type = ?");
            // Save absolute index to keep rotation valid
            $stmt->execute([$latest_used_index, $current_owner_id, $current_owner_type]);
        } catch (Exception $e) {
        }
    }

    if ($success_count > 0) {
        $msg = "Sent to $success_count recipients.";
        if ($fail_count > 0)
            $msg .= " Failed: $fail_count.";
        echo json_encode(['status' => 'success', 'message' => $msg]);
    } else {
        echo json_encode(['status' => 'error', 'message' => "Failed to send. Last Error: " . $last_response_msg]);
    }

} catch (Exception $e) {
    echo json_encode(['status' => 'error', 'message' => 'Exception: ' . $e->getMessage()]);
}
?>