<?php
/* Conciliación Yape (AGESCONT) - ahora sobre MySQL + sesión.
   ?action=conciliar (POST pdf) -> analiza (no escribe)
   ?action=confirm   (POST json)-> marca Pagado + aprende alias */
session_start();
header('Content-Type: application/json; charset=utf-8');
$cfg = require __DIR__ . '/db_config.php';
$pdo = new PDO("mysql:host={$cfg['host']};dbname={$cfg['dbname']};charset=utf8mb4", $cfg['user'], $cfg['pass'], [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);
function resp($ok, $data = null, $msg = '', $code = 200) { http_response_code($code); echo json_encode(['success'=>$ok,'data'=>$data,'message'=>$msg], JSON_UNESCAPED_UNICODE); exit; }
if (empty($_SESSION['uid'])) resp(false, null, 'No autenticado', 401);

$YAPE_STOP = ['SRL','SR','LTDA','CIA','COMPANY','COMPANIA','EMPRESARIALES','SERVICE','LOGISTIC','AND','DEL','LOS','LAS'];
function ynorm($s) { $s = @iconv('UTF-8','ASCII//TRANSLIT//IGNORE',$s); $s = preg_replace('/[^A-Za-z0-9 ]/',' ',$s); return strtoupper(trim(preg_replace('/\s+/',' ',$s))); }
function ytokens($s) { global $YAPE_STOP; $o=[]; foreach (explode(' ', ynorm($s)) as $t) { if (strlen($t)>=3 && !in_array($t,$YAPE_STOP)) $o[$t]=1; } return array_keys($o); }
function yamount($s) { return floatval(str_replace(',','.',str_replace('.','',$s))); }
function ypayer($d) { return trim(preg_replace('/^[A-Z]{2,5}\s*-\s*/','',trim($d))); }
function yfiso($f) { $x=explode('/',$f); return count($x)==3? sprintf('%s-%s-%s',$x[2],$x[1],$x[0]):$f; }
function yparse($text) {
    $rows=[]; $idx=-1;
    foreach (explode("\n",$text) as $line) {
        $t=trim($line); if ($t==='') continue;
        if (preg_match('#^(\d{2}/\d{2}/\d{4})\s+(\d{2}:\d{2}:\d{2})\s+(\d+)\s+(.*?)\s+([+\-])\s*Bs\s*([\d.,]+)\s+Bs\s*([\d.,]+)$#u',$t,$m)) {
            $mid=trim($m[4]); $parts=preg_split('/\s{2,}/',$mid);
            $rows[]=['fecha'=>$m[1],'hora'=>$m[2],'yapeId'=>$m[3],'desc'=>$parts[0]??'','detalle'=>count($parts)>1?implode(' ',array_slice($parts,1)):'','sign'=>$m[5],'monto'=>yamount($m[6])];
            $idx=count($rows)-1;
        } elseif ($idx>=0 && strpos($t,'Bs')===false && stripos($t,'verific')===false && stripos($t,'Direcc')===false && stripos($t,'supervis')===false && stripos($t,'ayuda')===false) {
            $cont=preg_split('/\s{2,}/',$t);
            $rows[$idx]['desc']=trim($rows[$idx]['desc'].' '.($cont[0]??''));
            if (count($cont)>1) $rows[$idx]['detalle']=trim($rows[$idx]['detalle'].' '.implode(' ',array_slice($cont,1)));
        }
    }
    return $rows;
}

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

if ($action === 'conciliar') {
    if (empty($_FILES['pdf']['tmp_name']) || !is_uploaded_file($_FILES['pdf']['tmp_name'])) resp(false, null, 'No se recibió el PDF', 400);
    $text = shell_exec('pdftotext -layout ' . escapeshellarg($_FILES['pdf']['tmp_name']) . ' - 2>/dev/null');
    if (!$text) resp(false, null, 'No se pudo leer el PDF', 500);
    $ingresos = array_values(array_filter(yparse($text), fn($r) => $r['sign'] === '+'));

    $clientes = $pdo->query("SELECT id, razon_social FROM clientes")->fetchAll();
    $pend = $pdo->query("SELECT pk, cliente_id, concepto, monto, fecha_vencimiento FROM pagos WHERE estado='Pendiente'")->fetchAll();
    $aliases = [];
    foreach ($pdo->query("SELECT pagador_norm, cliente_id FROM yape_aliases") as $a) $aliases[$a['pagador_norm']] = $a['cliente_id'];
    $refset = [];
    foreach ($pdo->query("SELECT ref_yape FROM pagos WHERE ref_yape IS NOT NULL") as $r) $refset[$r['ref_yape']] = true;

    $cliTokens=[]; $df=[]; $cliName=[];
    foreach ($clientes as $c) { $tk=ytokens($c['razon_social']); $cliTokens[$c['id']]=$tk; $cliName[$c['id']]=$c['razon_social']; foreach ($tk as $t) $df[$t]=($df[$t]??0)+1; }

    $props=[];
    foreach ($ingresos as $r) {
        $pn=ypayer($r['desc']); $pnNorm=ynorm($pn); $amt=$r['monto']; $ptoks=ytokens($pn);
        $prop=['yapeId'=>$r['yapeId'],'fecha'=>$r['fecha'],'fechaIso'=>yfiso($r['fecha']),'pagador'=>$pn,'pagadorNorm'=>$pnNorm,'monto'=>$amt,'detalle'=>$r['detalle'],'estado'=>'sin','clienteId'=>null,'clienteNombre'=>'','pagoId'=>null,'concepto'=>'','nCandMonto'=>0,'incluir'=>false];
        if (isset($refset[$r['yapeId']])) { $prop['estado']='ya'; $props[]=$prop; continue; }
        $cid=$aliases[$pnNorm]??null; $viaAlias=$cid!==null; $best=null;
        if ($cid===null) {
            foreach ($cliTokens as $kcid=>$tk) {
                if (!$tk) continue; $shared=array_values(array_intersect($ptoks,$tk)); if (!$shared) continue;
                $strong=array_filter($shared, fn($t)=>($df[$t]??99)<=3);
                if (count($strong)>=1 || count($shared)>=3) { $score=0; foreach ($shared as $t) $score+=1.0/max(1,($df[$t]??1)); if ($best===null||$score>$best['score']) $best=['cid'=>$kcid,'score'=>$score,'shared'=>count($shared)]; }
            }
            if ($best) $cid=$best['cid'];
        }
        $sharedBest = $viaAlias ? 99 : ($best['shared'] ?? 0);
        $pendAmt=array_values(array_filter($pend, fn($p)=>abs((float)$p['monto']-$amt)<0.01)); $prop['nCandMonto']=count($pendAmt);
        if ($cid!==null) {
            $prop['clienteId']=$cid; $prop['clienteNombre']=$cliName[$cid]??'';
            $cpend=array_values(array_filter($pend, fn($p)=>$p['cliente_id']==$cid));
            $exact=array_values(array_filter($cpend, fn($p)=>abs((float)$p['monto']-$amt)<0.01));
            $pick=$exact?$exact[0]:($cpend?$cpend[0]:null);
            if ($pick) { $prop['pagoId']=(int)$pick['pk']; $prop['concepto']=$pick['concepto']; }
            if ($exact && $viaAlias) { $prop['estado']='auto'; $prop['incluir']=true; }
            elseif ($exact && $sharedBest>=2) { $prop['estado']='alta'; $prop['incluir']=true; }
            else { $prop['estado']='media'; }
        } else {
            if (count($pendAmt)===1) { $prop['estado']='media_monto'; $prop['pagoId']=(int)$pendAmt[0]['pk']; $prop['clienteId']=$pendAmt[0]['cliente_id']; $prop['clienteNombre']=$cliName[$pendAmt[0]['cliente_id']]??''; $prop['concepto']=$pendAmt[0]['concepto']; }
            elseif (count($pendAmt)>1) { $prop['estado']='ambiguo'; }
        }
        $props[]=$prop;
    }
    $cliOut=[]; foreach ($clientes as $c) $cliOut[]=['id'=>$c['id'],'nombre'=>$c['razon_social']];
    usort($cliOut, fn($a,$b)=>strcmp($a['nombre'],$b['nombre']));
    $pendOut=[]; foreach ($pend as $p) $pendOut[]=['id'=>(int)$p['pk'],'clienteId'=>$p['cliente_id'],'monto'=>(float)$p['monto'],'concepto'=>$p['concepto'],'fechaVencimiento'=>$p['fecha_vencimiento']];
    resp(true, ['ingresos'=>count($ingresos),'propuestas'=>$props,'clientes'=>$cliOut,'pendientes'=>$pendOut], 'Extracto analizado');
}

elseif ($action === 'confirm') {
    $in = json_decode(file_get_contents('php://input'), true);
    if (!$in || empty($in['items'])) resp(false, null, 'No se recibieron items', 400);
    $used=[]; foreach ($pdo->query("SELECT ref_yape FROM pagos WHERE ref_yape IS NOT NULL") as $r) $used[$r['ref_yape']]=true;
    $upd = $pdo->prepare("UPDATE pagos SET estado='Pagado', metodo_pago='Yape', fecha=?, ref_yape=?,
        data=JSON_SET(data,'$.estado','Pagado','$.metodoPago','Yape','$.fecha',?,'$.refYape',?) WHERE pk=?");
    $al = $pdo->prepare("INSERT INTO yape_aliases (pagador_norm,cliente_id) VALUES (?,?) ON DUPLICATE KEY UPDATE cliente_id=VALUES(cliente_id)");
    $aplicados=0; $aprendidos=0; $omitidos=0;
    $pdo->beginTransaction();
    foreach ($in['items'] as $it) {
        $pk=$it['pagoId']??null; $yapeId=$it['yapeId']??null; $cid=$it['clienteId']??null; $fecha=$it['fechaIso']??null;
        if (!$pk) { $omitidos++; continue; }
        if ($yapeId && isset($used[$yapeId])) { $omitidos++; continue; }
        $upd->execute([$fecha, $yapeId, $fecha, $yapeId, $pk]);
        if ($upd->rowCount() > 0) { $aplicados++; if ($yapeId) $used[$yapeId]=true; }
        if ($cid && !empty($it['pagadorNorm'])) { $al->execute([$it['pagadorNorm'], $cid]); $aprendidos++; }
    }
    $pdo->commit();
    resp(true, ['aplicados'=>$aplicados,'aprendidos'=>$aprendidos,'omitidos'=>$omitidos], "Conciliados: $aplicados");
}

else { resp(false, null, 'Acción inválida', 400); }
