<?php
/**
 * voucher-grupal.php
 * Gestiona vouchers grupales: listar cobradores, detalle del cobrador y crear voucher grupal.
 *
 * GET  ?action=cobradores              → Lista todos los cobradores con sus grupos
 * GET  ?action=detalle&id_cobrador=X&mes=M&anio=A → Detalle del cobrador con ganancias del período
 * POST action=crear                    → Crea el voucher grupal
 * GET  ?action=buscar_dist&q=texto     → Busca distribuidores para agregar al grupo
 * POST action=add_rel                  → Agrega relación cobrador-distribuidor
 * POST action=del_rel                  → Elimina relación cobrador-distribuidor
 */
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Authorization, Content-Type');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }

require_once __DIR__ . '/../../config.php';

// Verificar token de admin (antes de getDB para detectar error de auth limpiamente)
$headers    = function_exists('getallheaders') ? getallheaders() : [];
$authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';
if (!$authHeader && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
    $authHeader = $_SERVER['HTTP_AUTHORIZATION'];
} elseif (!$authHeader && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
    $authHeader = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
}
if (!preg_match('/Bearer\s+(.+)/i', $authHeader, $m)) {
    http_response_code(401);
    echo json_encode(['error' => 'Token requerido']);
    exit;
}
$adminToken = trim($m[1]);
$db  = getDB();
$now = date('Y-m-d H:i:s');
$stmtSess = $db->prepare("SELECT idusuarios_sist FROM admin_sessions WHERE token = ? AND expira > ? LIMIT 1");
$stmtSess->execute([$adminToken, $now]);
if (!$stmtSess->fetch()) {
    http_response_code(401);
    echo json_encode(['error' => 'Sesión expirada o inválida']);
    exit;
}
$token = $adminToken;

$method = $_SERVER['REQUEST_METHOD'];
$action = $method === 'GET' ? ($_GET['action'] ?? '') : '';
$body   = [];
if ($method === 'POST') {
    $raw = file_get_contents('php://input');
    $body = json_decode($raw, true) ?? [];
    $action = $body['action'] ?? '';
}

// ─────────────────────────────────────────────────────────────
// GET: listar todos los cobradores con conteo de su grupo
// ─────────────────────────────────────────────────────────────
if ($method === 'GET' && $action === 'cobradores') {
    $sql = "
        SELECT
            vg.id_cobrador,
            CONCAT(COALESCE(i.nombre,''), ' ', COALESCE(i.appat,''), ' ', COALESCE(i.apmat,'')) AS nombre_cobrador,
            i.referencia,
            i.rfc,
            COUNT(vg.id) AS total_miembros,
            SUM(CASE WHEN vg.activo = 1 THEN 1 ELSE 0 END) AS miembros_activos
        FROM voucher_grupal vg
        JOIN inversionista i ON i.id_inver = vg.id_cobrador
        GROUP BY vg.id_cobrador, i.nombre, i.appat, i.apmat, i.referencia, i.rfc
        ORDER BY nombre_cobrador ASC
    ";
    $rows = $db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    echo json_encode(['success' => true, 'cobradores' => $rows], JSON_UNESCAPED_UNICODE);
    exit;
}

// ─────────────────────────────────────────────────────────────
// GET: detalle del cobrador — miembros + ganancias del período
// ─────────────────────────────────────────────────────────────
if ($method === 'GET' && $action === 'detalle') {
    $id_cobrador = (int)($_GET['id_cobrador'] ?? 0);
    $mes         = (int)($_GET['mes']  ?? date('n'));
    $anio        = (int)($_GET['anio'] ?? date('Y'));

    if (!$id_cobrador) {
        http_response_code(400);
        echo json_encode(['error' => 'id_cobrador requerido']);
        exit;
    }

    // Datos del cobrador
    $stmtC = $db->prepare("
        SELECT id_inver,
               CONCAT(COALESCE(nombre,''), ' ', COALESCE(appat,''), ' ', COALESCE(apmat,'')) AS nombre_completo,
               referencia, rfc
        FROM inversionista WHERE id_inver = ?
    ");
    $stmtC->execute([$id_cobrador]);
    $cobrador = $stmtC->fetch(PDO::FETCH_ASSOC);

    if (!$cobrador) {
        http_response_code(404);
        echo json_encode(['error' => 'Cobrador no encontrado']);
        exit;
    }

    // Miembros del grupo con sus ganancias en el período (si las tienen)
    $sql = "
        SELECT
            vg.id AS rel_id,
            vg.id_dist,
            vg.activo,
            CONCAT(COALESCE(i.nombre,''), ' ', COALESCE(i.appat,''), ' ', COALESCE(i.apmat,'')) AS nombre_dist,
            i.referencia AS ref_dist,
            i.rfc AS rfc_dist,
            r.idreg,
            r.apagar,
            r._real,
            r.status AS reg_status,
            r.observaciones
        FROM voucher_grupal vg
        JOIN inversionista i ON i.id_inver = vg.id_dist
        LEFT JOIN regs2 r
            ON r.id_inver = vg.id_dist
            AND MONTH(r.fechap) = ?
            AND YEAR(r.fechap)  = ?
            AND r.status IN (0, 5)
        WHERE vg.id_cobrador = ?
        ORDER BY i.nombre ASC, i.appat ASC
    ";
    $stmtM = $db->prepare($sql);
    $stmtM->execute([$mes, $anio, $id_cobrador]);
    $miembros = $stmtM->fetchAll(PDO::FETCH_ASSOC);

    // Regalías del cobrador como distribuidor en el mismo período
    $stmtCobReg = $db->prepare("
        SELECT idreg, apagar, _real, status, observaciones
        FROM regs2
        WHERE id_inver = ?
          AND MONTH(fechap) = ?
          AND YEAR(fechap)  = ?
          AND status IN (0, 5)
        LIMIT 1
    ");
    $stmtCobReg->execute([$id_cobrador, $mes, $anio]);
    $cobrador_reg = $stmtCobReg->fetch(PDO::FETCH_ASSOC);
    // Añadir datos del cobrador al objeto cobrador
    $cobrador['idreg']      = $cobrador_reg ? $cobrador_reg['idreg']      : null;
    $cobrador['apagar']     = $cobrador_reg ? $cobrador_reg['apagar']     : null;
    $cobrador['_real']      = $cobrador_reg ? $cobrador_reg['_real']      : null;
    $cobrador['reg_status'] = $cobrador_reg ? $cobrador_reg['status']     : null;
    $cobrador['observaciones'] = $cobrador_reg ? $cobrador_reg['observaciones'] : null;

    // Total disponible (solo los que tienen apagar > 0 y status=0)
    $total_disponible = 0;
    foreach ($miembros as $m) {
        if ($m['idreg'] && (int)$m['reg_status'] === 0 && (float)$m['apagar'] > 0) {
            $total_disponible += (float)$m['apagar'];
        }
    }
    // Incluir al cobrador si tiene regalías disponibles
    if ($cobrador['idreg'] && (int)$cobrador['reg_status'] === 0 && (float)$cobrador['apagar'] > 0) {
        $total_disponible += (float)$cobrador['apagar'];
    }

    echo json_encode([
        'success'          => true,
        'cobrador'         => $cobrador,
        'miembros'         => $miembros,
        'total_disponible' => round($total_disponible, 2),
        'mes'              => $mes,
        'anio'             => $anio
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

// ─────────────────────────────────────────────────────────────
// GET: buscar distribuidores para agregar al grupo
// ─────────────────────────────────────────────────────────────
if ($method === 'GET' && $action === 'buscar_dist') {
    $q = trim($_GET['q'] ?? '');
    if (strlen($q) < 2) {
        echo json_encode(['success' => true, 'resultados' => []]);
        exit;
    }
    $like = "%$q%";
    $stmt = $db->prepare("
        SELECT id_inver,
               CONCAT(COALESCE(nombre,''), ' ', COALESCE(appat,''), ' ', COALESCE(apmat,'')) AS nombre_completo,
               referencia, rfc
        FROM inversionista
        WHERE nombre LIKE ? OR appat LIKE ? OR referencia LIKE ? OR rfc LIKE ?
        LIMIT 15
    ");
    $stmt->execute([$like, $like, $like, $like]);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    echo json_encode(['success' => true, 'resultados' => $rows], JSON_UNESCAPED_UNICODE);
    exit;
}

// ─────────────────────────────────────────────────────────────
// POST: agregar relación cobrador → distribuidor
// ─────────────────────────────────────────────────────────────
if ($method === 'POST' && $action === 'add_rel') {
    $id_cobrador = (int)($body['id_cobrador'] ?? 0);
    $id_dist     = (int)($body['id_dist']     ?? 0);

    if (!$id_cobrador || !$id_dist) {
        http_response_code(400);
        echo json_encode(['error' => 'id_cobrador e id_dist requeridos']);
        exit;
    }
    if ($id_cobrador === $id_dist) {
        http_response_code(400);
        echo json_encode(['error' => 'El cobrador no puede ser miembro de su propio grupo']);
        exit;
    }

    try {
        $stmt = $db->prepare("
            INSERT INTO voucher_grupal (id_cobrador, id_dist, activo)
            VALUES (?, ?, 1)
            ON DUPLICATE KEY UPDATE activo = 1
        ");
        $stmt->execute([$id_cobrador, $id_dist]);
        echo json_encode(['success' => true, 'mensaje' => 'Relación agregada']);
    } catch (Exception $e) {
        http_response_code(500);
        echo json_encode(['error' => $e->getMessage()]);
    }
    exit;
}

// ─────────────────────────────────────────────────────────────
// POST: eliminar relación cobrador → distribuidor
// ─────────────────────────────────────────────────────────────
if ($method === 'POST' && $action === 'del_rel') {
    $rel_id = (int)($body['rel_id'] ?? 0);
    if (!$rel_id) {
        http_response_code(400);
        echo json_encode(['error' => 'rel_id requerido']);
        exit;
    }
    $stmt = $db->prepare("DELETE FROM voucher_grupal WHERE id = ?");
    $stmt->execute([$rel_id]);
    echo json_encode(['success' => true, 'mensaje' => 'Relación eliminada']);
    exit;
}

// ─────────────────────────────────────────────────────────────
// POST: crear voucher grupal
// ─────────────────────────────────────────────────────────────
if ($method === 'POST' && $action === 'crear') {
    $id_cobrador = (int)($body['id_cobrador'] ?? 0);
    $mes         = (int)($body['mes']  ?? 0);
    $anio        = (int)($body['anio'] ?? 0);
    // idreg_list: array de idreg seleccionados por el admin
    $idreg_list  = array_map('intval', $body['idreg_list'] ?? []);

    if (!$id_cobrador || !$mes || !$anio || empty($idreg_list)) {
        http_response_code(400);
        echo json_encode(['error' => 'Parámetros incompletos']);
        exit;
    }

    // Verificar que todos los idreg pertenecen al grupo del cobrador y tienen status=0 y apagar>0
    $placeholders = implode(',', array_fill(0, count($idreg_list), '?'));
    $stmtV = $db->prepare("
        SELECT r.idreg, r.apagar, r.cd AS id_dist, r.status, r.observaciones
        FROM regs2 r
        JOIN voucher_grupal vg ON vg.id_dist = r.cd AND vg.id_cobrador = ?
        WHERE r.idreg IN ($placeholders)
          AND r.status = 0
          AND r.apagar > 0
          AND MONTH(r.fechap) = ?
          AND YEAR(r.fechap)  = ?
    ");
    $params = array_merge([$id_cobrador], $idreg_list, [$mes, $anio]);
    $stmtV->execute($params);
    $registros = $stmtV->fetchAll(PDO::FETCH_ASSOC);

    // Verificar si el cobrador mismo está en idreg_list (como distribuidor)
    // Su idreg no estará en voucher_grupal, lo buscamos directamente en regs2
    $cobrador_idreg_incluido = false;
    foreach ($idreg_list as $ir) {
        // Ver si este idreg pertenece al cobrador
        $stmtChkCob = $db->prepare("
            SELECT idreg, apagar, id_inver AS id_dist, status, observaciones
            FROM regs2
            WHERE idreg = ?
              AND id_inver = ?
              AND status = 0
              AND apagar > 0
              AND MONTH(fechap) = ?
              AND YEAR(fechap)  = ?
            LIMIT 1
        ");
        $stmtChkCob->execute([$ir, $id_cobrador, $mes, $anio]);
        $cobReg = $stmtChkCob->fetch(PDO::FETCH_ASSOC);
        if ($cobReg) {
            // Agregar el registro del cobrador a la lista
            $cobReg['id_dist'] = $cobReg['id_dist']; // ya tiene id_dist
            $registros[] = $cobReg;
            $cobrador_idreg_incluido = true;
        }
    }

    if (empty($registros)) {
        http_response_code(400);
        echo json_encode(['error' => 'No hay registros válidos para generar el voucher']);
        exit;
    }

    $total_voucher = array_sum(array_column($registros, 'apagar'));
    $total_voucher = round($total_voucher, 2);

    // Generar número de voucher (consec + 2 dígitos aleatorios)
    $maxConsec = (int)$db->query("SELECT COALESCE(MAX(consec), 0) FROM voucher")->fetchColumn();
    $nuevoConsec = $maxConsec + 1;
    $randi1 = rand(0, 9);
    $randi2 = rand(0, 9);
    $idv = $nuevoConsec . $randi1 . $randi2;

    $hoy = date('Y-m-d H:i:s');

    // Datos del cobrador para el voucher
    $stmtCob = $db->prepare("SELECT id_inver FROM inversionista WHERE id_inver = ?");
    $stmtCob->execute([$id_cobrador]);
    $cobrador = $stmtCob->fetch(PDO::FETCH_ASSOC);
    if (!$cobrador) {
        http_response_code(404);
        echo json_encode(['error' => 'Cobrador no encontrado en inversionista']);
        exit;
    }

    $db->beginTransaction();
    try {
        // Insertar voucher a nombre del cobrador
        // referencia = lista de idreg separados por coma para trazabilidad
        $refs = implode(',', array_column($registros, 'idreg'));
        $stmtIns = $db->prepare("
            INSERT INTO voucher (consec, id_inv, total, restante, status, idcd, referencia, fecha_cre, fecha_mod)
            VALUES (?, ?, ?, ?, 0, 1, ?, ?, ?)
        ");
        $stmtIns->execute([$nuevoConsec, $id_cobrador, $total_voucher, $total_voucher, $refs, $hoy, $hoy]);

        // Actualizar cada registro en regs2
        $stmtUpd = $db->prepare("
            UPDATE regs2
            SET apagar = 0,
                status = 5,
                observaciones = CONCAT(COALESCE(observaciones,''), ' Voucher Grupal #', ?)
            WHERE idreg = ?
        ");
        foreach ($registros as $reg) {
            $stmtUpd->execute([$idv, $reg['idreg']]);
        }

        $db->commit();

        echo json_encode([
            'success'       => true,
            'idv'           => $idv,
            'total_voucher' => $total_voucher,
            'registros'     => count($registros),
            'idreg_list'    => array_column($registros, 'idreg')
        ], JSON_UNESCAPED_UNICODE);

    } catch (Exception $e) {
        $db->rollBack();
        http_response_code(500);
        echo json_encode(['error' => $e->getMessage()]);
    }
    exit;
}

http_response_code(400);
echo json_encode(['error' => 'Acción no reconocida: ' . $action]);
