<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\DB;
use App\Services\SefazService;

class ReprocessController extends Controller
{
    public function run(): void
    {
        $now = date('Y-m-d H:i:s');
        $rows = DB::pdo()->prepare("SELECT id, request, retries FROM sefaz_failed WHERE next_retry_at <= ? ORDER BY id ASC LIMIT 50");
        $rows->execute([$now]);
        $list = $rows->fetchAll();
        foreach ($list as $r) {
            $xml = $r['request'];
            $env = \App\Config\Config::get('env');
            $url = \App\Config\Config::get("sefaz.$env.distribuicao");
            $cert = ['path'=>'', 'password'=>''];
            $res = self::retrySoap($url, $xml, $cert);
            if ($res['status'] >= 200 && $res['status'] < 300 && !empty($res['body'])) {
                $del = DB::pdo()->prepare("DELETE FROM sefaz_failed WHERE id = ?");
                $del->execute([$r['id']]);
            } else {
                $upd = DB::pdo()->prepare("UPDATE sefaz_failed SET retries = retries + 1, next_retry_at = ? WHERE id = ?");
                $upd->execute([date('Y-m-d H:i:s', time() + 600), $r['id']]);
            }
        }
        echo 'reprocess-ok';
    }

    private static function retrySoap(string $url, string $xml, array $cert): array
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml; charset=utf-8']);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if (!empty($cert['path'])) {
            curl_setopt($ch, CURLOPT_SSLCERT, $cert['path']);
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'P12');
            curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $cert['password']);
        }
        $body = (string)curl_exec($ch);
        $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return ['status' => $status, 'body' => $body];
    }
}
