<?php
require '../core/bootstrap.php';

//logMessage("worker started", "SUCCESS");

$db = db();

set_time_limit(0);

// ambil 1 job dan kunci
$db->beginTransaction();

$stmtJobClaim = $db->query("
    SELECT * FROM jobs
    WHERE status='pending'
    ORDER BY id ASC
    LIMIT 1
    FOR UPDATE
");

$job = $stmtJobClaim->fetch(PDO::FETCH_ASSOC);

if (!$job) {
    $db->commit();
    sleep(2);
    logMessage("tidak ada job yang pending", "SUCCESS");
    return;
}

$jobId = $job['id'];

$db->prepare("
    UPDATE jobs SET status='running'
    WHERE id=?
")->execute([$jobId]);

$db->commit();

$stmtPayload = $db->prepare("SELECT payload FROM jobs WHERE id=:id");
$stmtPayload->execute(['id'=>$jobId]);
$payload = json_decode($stmtPayload->fetchColumn(), true);
$campaignId = $payload['campaign_id'];

$stmtTarget = $db->prepare("
    SELECT w.id, p.phone_number, p.name  
    FROM wa_message w
    JOIN phone_book p ON w.phone_id = p.id
    JOIN campaigns c ON c.id=w.campaign_id
    WHERE w.campaign_id = :campaign_id
      AND w.is_sent = 0 AND retry_count < 5
      AND c.status IN ('pending','running')
    ORDER BY p.phone_number
    LIMIT :limit
");

$stmtTarget->bindValue('campaign_id', $campaignId, PDO::PARAM_INT);
$stmtTarget->bindValue('limit', $payload['limit'], PDO::PARAM_INT);
$stmtTarget->execute();

$targets = $stmtTarget->fetchAll(PDO::FETCH_ASSOC);
$total = count($targets);

$stmtTemplate = $db->prepare("
    SELECT id, message
    FROM templates
    WHERE campaign_id = :campaign_id
");
$stmtTemplate->execute(['campaign_id' => $campaignId]);
$templates = $stmtTemplate->fetchAll(PDO::FETCH_ASSOC);

$stmtClaim = $db->prepare("
    UPDATE wa_message 
    SET is_sent = 1 ,job_id = ?, template_id = ?,sent_at = NOW()
    WHERE id = ? 
      AND is_sent = 0
");

$phoneBlast = '081217088900';
$tokenBlast = 'Esg5UkYzwNtBqBUs2CoZ'; //nanti ambil dari master token
//$phoneAdmin = $payload['admin_number'];
$phoneAdmin = '082233410100';
$tokenAdmin = 'X9FmkoTvkT5PispHBvmP'; //nanti ambil dari master token

$done = 0;
$sent = 0;
$jeda = 5; //berapa kali untuk berhenti dulu
$terkirims = [];
$logTerkirim = []; // menampung semua, termasuk dikirim dari nomer mana: 10100: 082244852244 14:58:25
$nomerCount = []; // berisi nomer dan jumlah wa terkirim
// 10100: 082244852244 14:58:25
// 10100 14:58:25 082244852244 
// 10100 14:58:55 085290304000
// 10100 14:59:25 0817300230
$tokenIndex = rand(0,1);
logMessage("Job #$jobId started with $total row", "SUCCESS");

// membuat $tokens sesuai nomer yang didaftar di payloadnya campaign
// cari dulu nomer-nomernya, kemudian lookup di config
$stmtPayloadCampaign = $db->prepare("SELECT payload FROM campaigns WHERE id=:id");
$stmtPayloadCampaign->execute(['id'=>$campaignId]);
$PayloadCampaign = json_decode($stmtPayloadCampaign->fetchColumn(), true);

$tokensMaster = config('sender');
/*
foreach($PayloadCampaign['sender'] as $nomer) {
    $tokens[] = ['nomer' => $nomer,'token' => $tokensMaster[$nomer]];
}
*/
$tokens = array_map(function($nomer) use ($tokensMaster) {
    return [
        'nomer' => $nomer,
        'token' => $tokensMaster[$nomer] ?? null
    ];
}, $PayloadCampaign['sender']);

// Mengambil semua 'nomer' saja, lalu menjadikannya key dengan isi 0
$nomerCount = array_fill_keys(array_column($tokens, 'nomer'), 0);

//$tokens = $tokensRaw[array_rand($tokensRaw)];
//echo '  nomer:' . $tokens[1]['nomer'];
//echo '  token:' . $tokens[1]['token'];
//logMessage(var_dump($tokens));
//die();

// keperluan telegram
$chatId = config("services")['telegram']['super_group'];
$topicId = 2;
//$messageId = reportTelegramProgress(0, 'persiapan', $chatId);
//logMessage("messageId =  $messageId", "SUCCESS");
$messageId = null;

$waktuMulai = microtime(true);
$suksesKirim = 1;

foreach ($targets as $t) {
    $done++;
    $phoneNumber = $t['phone_number'];
    $template = $templates[array_rand($templates)];
    $stmtClaim->execute([$jobId,$template['id'],$t['id']]);

    // agar ketika lapor ketua masih menggunakan nomer lama
    $tokenBlast=$tokens[$tokenIndex]['token'];
    $phoneBlast=$tokens[$tokenIndex]['nomer'];

    $tglJam = date('Y-m-d H:i:s');
    //$jam = substr($tglJam,-8); //2026-02-16 14:58:25 diambil 14:58:25 saja
    $terkirim = substr($tglJam,-8) . " " . substr($phoneBlast,-5) . " " . $phoneNumber;
    $logTerkirim[] = $terkirim;
    if ($stmtClaim->rowCount() === 0) {
        // gagal klaim (sudah dikirim worker lain)
        $terkirims[] = $terkirim . " 🤷🏻‍♂️";

        if (!empty($logTerkirim)) {
            $logTerkirim[count($logTerkirim) - 1] .= ' 🤷🏻‍♂️';
        }
        continue;
    }

    $sent++;
    //$detailProgress = $phoneNumber . " [$tglJam]";
    $terkirims[] = $terkirim;

    $raw = $template['message'];
    $message = spinText(replaceName($raw,$t['name']));

    $nomerCount[$phoneBlast] ??= 0; // "Jika belum ada, isi dengan 0"
    $nomerCount[$phoneBlast]++; // Menambah +1 secara otomatis pada key nomor tersebut

    $result = sendWa(
        $tokenBlast,
        $phoneNumber,
        $message,
    );
    
    // kirim log ke telegram
    //$logTeleText = "to: " . $phoneNumber . "\nfr: .." . substr($phoneBlast,-5) . "\n" . $tglJam;
    //$teleLog = sendTele($chatId,$logTeleText, $topicId);


    if (statusKirim($result) <> true) {
        //$tokenIndex = gantiToken($tokens,$tokenIndex);
        //harusnya ketika ada gagal, ada lapor ketua,,,
        $suksesKirim = 0;
        
        //dikembalikan lagi ke is_sent = 0
        $db->prepare("
            UPDATE wa_message SET is_sent = 0,retry_count = retry_count + 1 WHERE id = ?
            ")->execute([$t['id']]);
    } else {
        $suksesKirim = 1;
    }
    
    
    //logMessage("Send to " . $phoneNumber . ": " . $message, "SUCCESS");
    logMessage($terkirim, "SUCCESS");

    
    $percent = intval(($done / $total) * 100);
    $percentText = number_format($percent,1,',','.') . ' %';

    //echo $percentText;
    //$newMessageId = reportTelegramProgress($percent, $detailProgress, $chatId, $messageId);
    $messageId =  reportProgress($jobId,$percent, $terkirim, $chatId, $messageId);
    //echo $detailProgress;
    // update progress job
    
    $db->prepare("
        UPDATE jobs SET total=?,done=?, progress=?
        WHERE id=?
    ")->execute([$total,$done, $percent, $jobId]);

    // delay random
    sleep(rand($payload['min_delay'], $payload['max_delay']));

    $jedaRandom = rand($jeda-1,$jeda+1);
    if ($sent % $jeda == 0) {
        //pancingan
        $kemajuan = "$sent dari $total ($percentText)" . " dari  $phoneBlast\n> Job #$jobId";
        laporAdmin($terkirims,$tokenBlast,$phoneBlast,$tokenAdmin, $phoneAdmin,$jobId,$done,$total);
        // laporKetua($terkirims,$tokenBlast,$phoneBlast,$tokenAdmin, $phoneAdmin,$kemajuan);
        $terkirims = [];
    }
    if ($sent % ($jeda*2) == 0 or $terkirim == 0) {
        $tokenIndex = gantiToken($tokens,$tokenIndex);
        $sent = 0; //tujuannya agar ketika ada yang diskoneect, device berikutnya dpat job utuh
    }
}
$waktuSelesai = microtime(true);


if(count($terkirims) > 0) {
    //jika masih ada sisa
    laporAdmin($terkirims,$tokenBlast,$phoneBlast,$tokenAdmin, $phoneAdmin,$jobId,$done,$total);
    //$kemajuan = "$sent dari $total ( $percentText ) dari " . $phoneBlast;
    //laporKetua($terkirims,$tokenBlast,$phoneBlast,$tokenAdmin, $phoneAdmin,$kemajuan);
}
$db->prepare("
    UPDATE jobs SET status=?
    WHERE id=?
")->execute(['finished', $jobId]);

$selisihDetik = round($waktuSelesai - $waktuMulai);

$menit = floor($selisihDetik / 60);
$detik = $selisihDetik % 60;

$durasi = "$menit menit $detik detik";

$mulaiFormatted = date("H:i:s", (int)$waktuMulai);
$selesaiFormatted = date("H:i:s", (int)$waktuSelesai);

$text = "📌 <b>REPORT JOB #$jobId</b>\n";
$text .= "--------------------------------\n";
$text .= "✅ Status: <b>SELESAI</b>\n";
$text .= "🚀 Mulai: <code>$mulaiFormatted</code>\n";
$text .= "🏁 Selesai: <code>$selesaiFormatted</code>\n";
$text .= "⏳ Durasi: <b>$durasi</b>\n";
$text .= "📱 Device:";
foreach($tokens as $t) {
    $nmrSndr = $t['nomer'];
    $text .= "\n  📞 $nmrSndr: " . $nomerCount[$nmrSndr] ;
 }
$text .= "\n🤑 Terkirim: " . count($logTerkirim) . " cust.\n";
$text .= "--------------------------------\n";
$text .= "" . implode("\n", $logTerkirim) . "";

// Kirim ke Telegram...
return sendTele($chatId,$text, $topicId);


// Fungsi pembantu (helper) untuk merapikan teks laporan
function laporKetua(array $daftarNomor, $tokenBlast, $phoneBlast, $tokenAdmin, $phoneAdmin, $ket = '')
{
    $listNomor = "* " . implode("\n* ", $daftarNomor);
    $pesanLaporan = "Sudah terkirim ke:\n" . $listNomor . (!empty($ket) ? "\n" . $ket : "");

    // Kirim menggunakan WhatsAppService
    //$this->waService->sendMessage($phoneadmin, $pesanLaporan, $token);
    $result = sendWa(
        $tokenBlast,
        $phoneAdmin,
        $pesanLaporan,
    );
    
    sleep(rand(3,5));
    $result = sendWa(
        $tokenBlast,
        '120363424804528965@g.us',
        $pesanLaporan,
    );
    
    sleep(rand(3,9));
    $pesanLaporan = "_" . $ket . "_ ??\n\n terima kasih...";
    $result = sendWa(
        $tokenAdmin,
        $phoneBlast,
        $pesanLaporan,
    );
    // $this->waService->sendMessage($phoneblast, $pesanLaporan, $tokenAdmin);
    // dump($tokenadm);
}

function laporAdmin(array $daftarNomor, $tokenBlast, $phoneBlast, $tokenAdmin, $phoneAdmin, $jobId, $done, $total)
{
    $terbilang = new TerbilangJawa();
    $wag = '120363424804528965@g.us';
    $persen = $done / $total * 100;
    $persen = round($persen,0,PHP_ROUND_HALF_UP);

    // kirim ke admin dulu
    $pesanLaporan ="{opo wis|ntuk|sampe} " . $terbilang->ngoko($persen) . " persen {?|ta?|wisan?}";
    $result = sendWa(
        $tokenAdmin,
        $wag,
        spinText($pesanLaporan),
    );
    sleep(rand(25,35));
    //logMessage("ngoko: $pesanLaporan" , "SUCCESS");
    $pesanLaporan  = "{nggih|leres|nggih leres}, angsal " . $terbilang->krama($done) . " saking " . $terbilang->krama($total) . "\n";
    if($daftarNomor) {
        $pesanLaporan .= "{saking|mulai} " . $daftarNomor[0] . "{ngantos|ndugi} " . $daftarNomor[count($daftarNomor)-1];
    }
    //logMessage("kromo: $pesanLaporan" , "SUCCESS");
    $result2 = sendWa(
        $tokenBlast,
        $wag,
        spinText($pesanLaporan),
    );
    //logMessage("result2: " . print_r($result2, true) , "SUCCESS");
    
}

function gantiToken($tokens,$tokenIndex) {
    $tokenIndex++;
    if ($tokenIndex >= count($tokens)) {
        $tokenIndex = 0;
    }
    return $tokenIndex;
}
