<?php
declare(strict_types=1);
ignore_user_abort(true);
@set_time_limit(120);
require __DIR__.'/config.php';
$c=require __DIR__.'/config.php';
require_once __DIR__.'/queue-lib.php';

$site=(string)($_SERVER['HTTP_X_MESORA_SITE']??'');$ts=(string)($_SERVER['HTTP_X_MESORA_TIMESTAMP']??'');$sig=(string)($_SERVER['HTTP_X_MESORA_SIGNATURE']??'');
if($site===''||!hash_equals((string)($c['site_id']??''),$site)||!ctype_digit($ts)||abs(time()-(int)$ts)>180||!hash_equals(hash_hmac('sha256',$ts.'.WORKER',(string)$c['shared_secret']),$sig)){http_response_code(403);exit;}
http_response_code(202);header('Content-Type: application/json');echo '{"ok":true}';
if(function_exists('fastcgi_finish_request'))@fastcgi_finish_request();else{@ob_flush();@flush();}
$lock=@fopen(mq_dir().'/.worker.lock','c');if(!$lock||!@flock($lock,LOCK_EX|LOCK_NB))exit;

function w_multipart($method,$params,$filename,$mime,$bytes,&$ct){
 $map=['sendPhoto'=>'photo','sendVoice'=>'voice','sendAudio'=>'audio','sendVideo'=>'video','sendDocument'=>'document'];if(!isset($map[$method]))return false;
 $b='----Mesora'.bin2hex(random_bytes(10));$e="\r\n";$body='';
 foreach($params as $k=>$v){if(is_array($v)||is_object($v))$v=json_encode($v,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);$body.='--'.$b.$e.'Content-Disposition: form-data; name="'.$k.'"'.$e.$e.$v.$e;}
 $fn=preg_replace('/[^A-Za-z0-9._-]/','_',basename($filename));$body.='--'.$b.$e.'Content-Disposition: form-data; name="'.$map[$method].'"; filename="'.$fn.'"'.$e.'Content-Type: '.$mime.$e.$e.$bytes.$e.'--'.$b.'--'.$e;$ct='multipart/form-data; boundary='.$b;return $body;
}
function w_send($c,$job){
 $meta=$job['meta']??[];$file=$job['file']??'';if(!is_file($file))return 'queued file missing';
 $bytes=@file_get_contents($file);if(!is_string($bytes))return 'queued file unreadable';
 $method=(string)($meta['method']??'');$ct='';$body=w_multipart($method,(array)($meta['params']??[]),(string)($meta['name']??'media.bin'),(string)($meta['mime']??'application/octet-stream'),$bytes,$ct);if($body===false)return 'method not allowed';
 $ch=curl_init('https://api.telegram.org/bot'.$c['bot_token'].'/'.$method);
 curl_setopt_array($ch,[CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>$body,CURLOPT_RETURNTRANSFER=>true,CURLOPT_CONNECTTIMEOUT=>7,CURLOPT_TIMEOUT=>35,CURLOPT_IPRESOLVE=>CURL_IPRESOLVE_V4,CURLOPT_HTTP_VERSION=>CURL_HTTP_VERSION_1_1,CURLOPT_HTTPHEADER=>['Content-Type: '.$ct,'Expect:','Connection: close']]);
 $out=curl_exec($ch);$err=curl_error($ch);$code=(int)curl_getinfo($ch,CURLINFO_HTTP_CODE);curl_close($ch);
 $j=is_string($out)?json_decode($out,true):null;if($err!==''||$code<200||$code>=300||!is_array($j)||empty($j['ok']))return $err?:($j['description']??('HTTP '.$code));return true;
}
$processed=0;
if(mt_rand(1,20)===1)ms_cleanup(30);
foreach(mq_jobs() as $jobfile){
 if($processed>=12)break;$job=mq_load($jobfile);if(!$job)continue;if((int)($job['next_at']??0)>time())continue;
 $r=w_send($c,$job);$processed++;
 if($r===true)mq_finish($jobfile,$job);else mq_fail($jobfile,$job,$r);
}
@flock($lock,LOCK_UN);@fclose($lock);
