<?php
header('Content-Type: application/json');
header('Cache-Control: no-store');

require __DIR__ . '/config.php';

define('SMS_LOG_FILE', __DIR__ . '/sms_debug.log');

function logSms(string $label, $data): void {
    $line = '[' . date('Y-m-d H:i:s') . '] ' . $label . ': ' . (is_string($data) ? $data : json_encode($data, JSON_PRETTY_PRINT)) . "\n";
    file_put_contents(SMS_LOG_FILE, $line, FILE_APPEND);
}

function sgRequest(string $method, string $path, array $body = []): array {
    $url = SMS_GW_URL . $path;
    logSms("REQUEST $method", $url);
    if ($body) logSms("REQUEST BODY", $body);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_USERPWD        => SMS_GW_USER . ':' . SMS_GW_PASS,
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json', 'Accept: application/json'],
        CURLOPT_CUSTOMREQUEST  => strtoupper($method),
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_SSL_VERIFYPEER => true,
    ]);
    if ($body) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));

    $raw     = curl_exec($ch);
    $code    = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlErr = curl_error($ch);
    curl_close($ch);

    logSms("RESPONSE CODE", $code);
    logSms("RESPONSE BODY", $raw ?: '(empty)');
    if ($curlErr) logSms("CURL ERROR", $curlErr);

    return ['code' => $code, 'body' => json_decode($raw, true), 'raw' => $raw, 'curl_error' => $curlErr];
}

function formatPhone(string $raw): ?string {
    $digits = preg_replace('/[^\d]/', '', $raw);
    logSms("PHONE RAW", $raw);
    logSms("PHONE DIGITS", $digits);

    if (strlen($digits) < 10 || strlen($digits) > 15) {
        logSms("PHONE INVALID", "digit count: " . strlen($digits) . " value: '$raw'");
        return null;
    }
    if (strlen($digits) === 10) $digits = '1' . $digits;

    $formatted = '+' . $digits;
    logSms("PHONE FORMATTED", $formatted);
    return $formatted;
}

function getEmployees(PDO $pdo, array $voterIds, ?string $filter): array {
    $EMP_TABLE = 'empvotetest';
    $VBM_LIKE  = '%2026 MAY MUNICIPAL ELECTION%';

    if (!empty($voterIds)) {
        $ph   = implode(',', array_fill(0, count($voterIds), '?'));
        $stmt = $pdo->prepare("SELECT `VoterID`, `First Name`, `Last Name`, `Cell Phone`
                               FROM `$EMP_TABLE`
                               WHERE `VoterID` IN ($ph)
                               AND `Cell Phone` IS NOT NULL AND `Cell Phone` != ''");
        $stmt->execute($voterIds);
    } else {
        $joinSql  = "LEFT JOIN (
                        SELECT voter_id FROM (
                            SELECT voterid AS voter_id FROM voted
                            UNION ALL
                            SELECT id AS voter_id FROM vbmreturns
                            WHERE `Election` LIKE ? AND `Ballot Counted Status`='Received'
                        ) cv GROUP BY voter_id
                     ) votes ON votes.voter_id = e.`VoterID`";
        $whereMap = ['voted' => 'votes.voter_id IS NOT NULL', 'notvoted' => 'votes.voter_id IS NULL'];
        $extra    = isset($whereMap[$filter]) ? "AND " . $whereMap[$filter] : "";

        $stmt = $pdo->prepare("SELECT e.`VoterID`, e.`First Name`, e.`Last Name`, e.`Cell Phone`
                               FROM `$EMP_TABLE` e $joinSql
                               WHERE e.`Cell Phone` IS NOT NULL AND e.`Cell Phone` != '' $extra");
        $stmt->execute([$VBM_LIKE]);
    }

    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

try {
    $action = $_GET['action'] ?? '';

    // ── ACTION: debug_employees ─────────────────────────────────────────────
    if ($action === 'debug_employees') {
        $filter    = $_GET['filter'] ?? 'all';
        $voterIds  = !empty($_GET['voter_ids']) ? explode(',', $_GET['voter_ids']) : [];
        $employees = getEmployees($pdo, $voterIds, $filter);

        $preview = array_map(function($e) {
            $digits    = preg_replace('/[^\d]/', '', $e['Cell Phone'] ?? '');
            $formatted = null;
            if (strlen($digits) === 10)      $formatted = '+1' . $digits;
            elseif (strlen($digits) >= 11)   $formatted = '+' . $digits;

            return [
                'voter_id'        => $e['VoterID'],
                'name'            => $e['First Name'] . ' ' . $e['Last Name'],
                'phone_raw'       => $e['Cell Phone'],
                'phone_formatted' => $formatted,
                'will_skip'       => $formatted === null ? 'YES — bad number' : 'no',
            ];
        }, $employees);

        echo json_encode([
            'filter'      => $filter,
            'total_found' => count($employees),
            'will_send'   => count(array_filter($preview, fn($p) => $p['will_skip'] === 'no')),
            'will_skip'   => count(array_filter($preview, fn($p) => $p['will_skip'] !== 'no')),
            'employees'   => $preview,
        ], JSON_PRETTY_PRINT);
        exit;
    }

    // ── ACTION: test_single ─────────────────────────────────────────────────
    if ($action === 'test_single') {
        $rawPhone = trim($_GET['phone'] ?? '');
        $message  = trim($_GET['message'] ?? 'Test message from emp dashboard');
        if (!$rawPhone) throw new Exception("Phone number required. Add ?phone=2015551234 to URL.");
        $phone = formatPhone($rawPhone);
        if (!$phone) throw new Exception("Could not format phone number: '$rawPhone'");

        $res = sgRequest('POST', '/message', [
            'message'            => $message,
            'phoneNumbers'       => [$phone],
            'withDeliveryReport' => true,
        ]);

        echo json_encode([
            'success'         => $res['code'] >= 200 && $res['code'] < 300,
            'phone_raw'       => $rawPhone,
            'phone_formatted' => $phone,
            'http_code'       => $res['code'],
            'api_response'    => $res['body'],
            'curl_error'      => $res['curl_error'] ?: null,
        ], JSON_PRETTY_PRINT);
        exit;
    }

    // ── ACTION: get_log ─────────────────────────────────────────────────────
    if ($action === 'get_log') {
        header('Content-Type: text/plain');
        $lines = (int)($_GET['lines'] ?? 100);
        if (!file_exists(SMS_LOG_FILE)) {
            echo "No log file yet.\nExpected: " . SMS_LOG_FILE;
        } else {
            echo implode('', array_slice(file(SMS_LOG_FILE), -$lines));
        }
        exit;
    }

    // ── ACTION: clear_log ───────────────────────────────────────────────────
    if ($action === 'clear_log') {
        file_put_contents(SMS_LOG_FILE, '');
        echo json_encode(['success' => true, 'message' => 'Log cleared.']);
        exit;
    }

    // ── ACTION: send_sms ────────────────────────────────────────────────────
    if ($action === 'send_sms') {
        $rawBody = file_get_contents('php://input');
        logSms("SEND_SMS RAW POST BODY", $rawBody ?: '(empty — nothing received from page)');

        $input = json_decode($rawBody, true);
        logSms("SEND_SMS PARSED INPUT", $input ?? 'null — json_decode failed');

        if (!$input) {
            throw new Exception("No data received from the page. Raw body was: " . substr($rawBody, 0, 200));
        }

        $messageTemplate = trim($input['message'] ?? '');
        $intervalSec     = max(0, (int)($input['interval_seconds'] ?? 0));
        $filter          = $input['filter'] ?? 'all';
        $voterIds        = $input['voter_ids'] ?? [];

        logSms("SEND_SMS PARAMS", [
            'message_length'  => strlen($messageTemplate),
            'interval'        => $intervalSec,
            'filter'          => $filter,
            'voter_ids_count' => count($voterIds),
        ]);

        if (empty($messageTemplate)) throw new Exception("Message text is required.");

        $employees = getEmployees($pdo, $voterIds, $filter);
        logSms("EMPLOYEES FOUND", count($employees));

        if (empty($employees)) {
            $total     = $pdo->query("SELECT COUNT(*) FROM `empvotetest`")->fetchColumn();
            $withPhone = $pdo->query("SELECT COUNT(*) FROM `empvotetest` WHERE `Cell Phone` IS NOT NULL AND `Cell Phone` != ''")->fetchColumn();
            throw new Exception("No employees found. Total in table: $total, with phone: $withPhone, filter used: '$filter'");
        }

        $results = [];
        $sent    = 0;
        $failed  = 0;
        $skipped = 0;
        $now     = new DateTime();

        foreach ($employees as $i => $emp) {
            $phone = formatPhone($emp['Cell Phone'] ?? '');

            if (!$phone) {
                $skipped++;
                $results[] = [
                    'voter_id'  => $emp['VoterID'],
                    'phone_raw' => $emp['Cell Phone'],
                    'status'    => 'skipped',
                    'error'     => 'Unparseable phone: "' . $emp['Cell Phone'] . '"',
                ];
                continue;
            }

            $text = str_replace(
                ['{firstName}', '{lastName}', '{voterID}'],
                [$emp['First Name'], $emp['Last Name'], $emp['VoterID']],
                $messageTemplate
            );

            $payload = [
                'message'            => $text,
                'phoneNumbers'       => [$phone],
                'withDeliveryReport' => true,
            ];

            if ($intervalSec > 0 && $i > 0) {
                $delaySec              = $i * $intervalSec;
                $schedAt               = (clone $now)->modify("+{$delaySec} seconds");
                $payload['scheduleAt'] = $schedAt->format(DateTime::ATOM);
            }

            $res = sgRequest('POST', '/message', $payload);

            if ($res['code'] >= 200 && $res['code'] < 300) {
                $sent++;
                $msgId     = $res['body']['id'] ?? null;
                $results[] = [
                    'voter_id'   => $emp['VoterID'],
                    'phone'      => $phone,
                    'status'     => 'queued',
                    'message_id' => $msgId,
                ];

                if ($msgId) {
                    try {
                        $pdo->prepare("INSERT IGNORE INTO sms_log (message_id, voter_id, phone, message_text, sent_at)
                                       VALUES (?, ?, ?, ?, NOW())")
                            ->execute([$msgId, $emp['VoterID'], $phone, $text]);
                    } catch (Throwable $e) { /* sms_log table may not exist yet */ }
                }
            } else {
                $failed++;
                $errMsg    = $res['body']['message'] ?? $res['raw'];
                $results[] = [
                    'voter_id'  => $emp['VoterID'],
                    'phone'     => $phone,
                    'status'    => 'error',
                    'http_code' => $res['code'],
                    'error'     => $errMsg,
                ];
            }
        }

        logSms("BULK SEND COMPLETE", "sent=$sent failed=$failed skipped=$skipped");

        echo json_encode([
            'success' => true,
            'total'   => count($employees),
            'sent'    => $sent,
            'failed'  => $failed,
            'skipped' => $skipped,
            'results' => $results,
        ]);
        exit;
    }

    // ── ACTION: get_inbox ───────────────────────────────────────────────────
    if ($action === 'get_inbox') {
        $limit  = min((int)($_GET['limit'] ?? 50), 200);
        $offset = (int)($_GET['offset'] ?? 0);
        $res    = sgRequest('GET', "/inbox?limit={$limit}&offset={$offset}");
        echo json_encode($res['body'] ?? []);
        exit;
    }

    // ── ACTION: get_message_status ──────────────────────────────────────────
    if ($action === 'get_message_status') {
        $msgId = trim($_GET['id'] ?? '');
        if (!$msgId) throw new Exception("Message ID required.");
        $res = sgRequest('GET', "/message/{$msgId}");
        echo json_encode($res['body'] ?? []);
        exit;
    }

    throw new Exception("Unknown action: '$action'");

} catch (Throwable $e) {
    logSms("EXCEPTION", $e->getMessage());
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}