<?php
    use Phalcon\Cli\Task;
    // use Phalcon\Queue\Beanstalk;
    use Phalcon\Db;

    class EncryptTask extends Task {
        public function mainAction() {
            $limit = 500;
            $concurrency = 20;
            // $queue = new Beanstalk($this->config["beanstalk_config"]);
            try {
                while (true) {
                    $rows = $this->db->fetchAll(
                        // "SELECT um_id, phone FROM jaga.um_user
                        "SELECT uuid FROM public.dummy
                         WHERE enc_uuid IS NULL 
                         ORDER BY uuid ASC 
                         LIMIT :limit",
                         Db::FETCH_ASSOC,
                        ['limit' => $limit]
                    );
                    if (empty($rows)) {
                        echo "Done.\n";
                        break;
                    }
                    $this->processChunk($rows, $concurrency);
                }
            } catch(\Exception $e) {
                $this->logger->addItem("type_of_log", "background_job_exception");
                $this->logger->addItem("error_message", $e->getMessage());
                $this->logger->error();
            }
            
        }

        private function processChunk(array $rows, int $concurrency)
        {
            $chunks = array_chunk($rows, $concurrency);
            foreach ($chunks as $batch) {
                $this->processBatch($batch);
            }
        }

        private function processBatch(array $rows)
        {
            $mh = curl_multi_init();
            $handles = [];

            $wsop_url = getenv("WSOP_URL");
            $wsop_kid = getenv("WSOP_KID");

            // 1. Add ALL handles first
            foreach ($rows as $row) {
                $ch = curl_init($wsop_url . "encrypt");

                curl_setopt_array($ch, [
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_POST => true,
                    CURLOPT_POSTFIELDS => json_encode([
                        'kid' => $wsop_kid,
                        'alg' => 'RSA-OAEP',
                        'plaintext' => $row['uuid']
                    ]),
                    CURLOPT_HTTPHEADER => [
                        'Content-Type: application/json'
                    ],
                    CURLOPT_TIMEOUT => 10,
                    CURLOPT_SSL_VERIFYPEER => false,
                    CURLOPT_SSL_VERIFYHOST => 0,
                ]);

                curl_multi_add_handle($mh, $ch);

                $handles[] = [
                    'handle' => $ch,
                    'uuid' => $row['uuid']
                ];
            }

            // 2. Execute ALL in parallel
            do {
                $status = curl_multi_exec($mh, $running);
                curl_multi_select($mh, 1.0);
            } while ($running > 0 && $status == CURLM_OK);

            // 3. Process results
            $this->db->begin();

            foreach ($handles as $item) {
                $response = curl_multi_getcontent($item['handle']);
                $error = curl_error($item['handle']);
                $cipher = null;

                if ($error) {
                    $cipher = $this->retry($item['uuid']);
                } else {
                    $json = json_decode($response, true);
                    $cipher = $json['ciphertext'] ?? null;
                }

                if ($cipher) {
                    $this->db->execute(
                        "UPDATE jaga.um_user 
                        SET enc_uuid = :cipher
                        WHERE uuid = :uuid",
                        [
                            'cipher' => $cipher,
                            'uuid' => $item['uuid'],
                        ]
                    );
                } else {
                    echo "Failed UUID: {$item['uuid']} RESPONSE: $response ERROR: $error\n";
                }

                curl_multi_remove_handle($mh, $item['handle']);
                curl_close($item['handle']);
            }

            $this->db->commit();
            curl_multi_close($mh);
        }
    }