<?php
header('Content-Type: application/json; charset=utf-8');
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../includes/helpers.php';

$pdo = getConnection();
$action = $_GET['action'] ?? '';

try {
    switch ($action) {

        case 'generar_venta':
            $venta_id = intval($_GET['venta_id']??0);
            if (!$venta_id) json_error('ID de venta requerido');
            $asiento_id = generarAsientoVenta($pdo, $venta_id);
            json_success(['id'=>$asiento_id], 'Asiento de venta generado #'.$asiento_id);
            break;

        case 'generar_compra':
            $compra_id = intval($_GET['compra_id']??0);
            if (!$compra_id) json_error('ID de compra requerido');
            $asiento_id = generarAsientoCompra($pdo, $compra_id);
            json_success(['id'=>$asiento_id], 'Asiento de compra generado #'.$asiento_id);
            break;

        case 'generar_gasto':
            $gasto_id = intval($_GET['gasto_id']??0);
            if (!$gasto_id) json_error('ID de gasto requerido');
            $asiento_id = generarAsientoGasto($pdo, $gasto_id);
            json_success(['id'=>$asiento_id], 'Asiento de gasto generado #'.$asiento_id);
            break;

        case 'generar_automatico':
            $fecha_desde = $_GET['fecha_desde'] ?? date('Y-m-01');
            $fecha_hasta = $_GET['fecha_hasta'] ?? date('Y-m-d');
            $limite = max(1, min(5000, intval($_GET['limite'] ?? 1000)));
            $suc_id = intval($_GET['sucursal_id'] ?? 0);

            // First, get counts
            $v_sql = "SELECT COUNT(*) FROM ventas v
                LEFT JOIN asientos_contables a ON a.referencia_id=v.id AND a.referencia_tipo='ventas'
                WHERE a.id IS NULL AND DATE(v.fecha_y_hora) BETWEEN ? AND ?";
            $v_params = [$fecha_desde, $fecha_hasta];
            if ($suc_id > 0) {
                $v_sql .= " AND v.sucursal_id = ?";
                $v_params[] = $suc_id;
            }
            $v_pend = $pdo->prepare($v_sql);
            $v_pend->execute($v_params);

            $c_count = 0;
            if ($suc_id == 0 || $suc_id == 1) {
                $c_pend = $pdo->prepare("SELECT COUNT(*) FROM compras c
                    LEFT JOIN asientos_contables a ON a.referencia_id=c.id AND a.referencia_tipo='compras'
                    WHERE a.id IS NULL AND DATE(c.fecha_compra) BETWEEN ? AND ?");
                $c_pend->execute([$fecha_desde, $fecha_hasta]);
                $c_count = intval($c_pend->fetchColumn());
            }

            $g_sql = "SELECT COUNT(*) FROM gastos_operativos g
                LEFT JOIN asientos_contables a ON a.referencia_id=g.id AND a.referencia_tipo='gastos_operativos'
                WHERE a.id IS NULL AND g.fecha_gasto BETWEEN ? AND ?";
            $g_params = [$fecha_desde, $fecha_hasta];
            if ($suc_id > 0) {
                $g_sql .= " AND g.sucursal_id = ?";
                $g_params[] = $suc_id;
            }
            $g_pend = $pdo->prepare($g_sql);
            $g_pend->execute($g_params);

            $resultado = generarAutomatico($pdo, $fecha_desde, $fecha_hasta, $limite, $suc_id);
            $resultado['pendientes'] = [
                'ventas' => intval($v_pend->fetchColumn()),
                'compras' => $c_count,
                'gastos' => intval($g_pend->fetchColumn())
            ];
            $resultado['fecha_desde'] = $fecha_desde;
            $resultado['fecha_hasta'] = $fecha_hasta;
            json_success($resultado, 'Generacion automatica completada');
            break;

        case 'contar_pendientes':
            $fecha_desde = $_GET['fecha_desde'] ?? date('Y-m-01');
            $fecha_hasta = $_GET['fecha_hasta'] ?? date('Y-m-d');
            $suc_id = intval($_GET['sucursal_id'] ?? 0);

            $v_sql = "SELECT COUNT(*) FROM ventas v
                LEFT JOIN asientos_contables a ON a.referencia_id=v.id AND a.referencia_tipo='ventas'
                WHERE a.id IS NULL AND DATE(v.fecha_y_hora) BETWEEN ? AND ?";
            $v_params = [$fecha_desde, $fecha_hasta];
            if ($suc_id > 0) {
                $v_sql .= " AND v.sucursal_id = ?";
                $v_params[] = $suc_id;
            }
            $v_pend = $pdo->prepare($v_sql);
            $v_pend->execute($v_params);

            $c_count = 0;
            if ($suc_id == 0 || $suc_id == 1) {
                $c_pend = $pdo->prepare("SELECT COUNT(*) FROM compras c
                    LEFT JOIN asientos_contables a ON a.referencia_id=c.id AND a.referencia_tipo='compras'
                    WHERE a.id IS NULL AND DATE(c.fecha_compra) BETWEEN ? AND ?");
                $c_pend->execute([$fecha_desde, $fecha_hasta]);
                $c_count = intval($c_pend->fetchColumn());
            }

            $g_sql = "SELECT COUNT(*) FROM gastos_operativos g
                LEFT JOIN asientos_contables a ON a.referencia_id=g.id AND a.referencia_tipo='gastos_operativos'
                WHERE a.id IS NULL AND g.fecha_gasto BETWEEN ? AND ?";
            $g_params = [$fecha_desde, $fecha_hasta];
            if ($suc_id > 0) {
                $g_sql .= " AND g.sucursal_id = ?";
                $g_params[] = $suc_id;
            }
            $g_pend = $pdo->prepare($g_sql);
            $g_pend->execute($g_params);

            json_success([
                'ventas' => intval($v_pend->fetchColumn()),
                'compras' => $c_count,
                'gastos' => intval($g_pend->fetchColumn()),
                'fecha_desde' => $fecha_desde,
                'fecha_hasta' => $fecha_hasta
            ]);
            break;

        default:
            json_error('Accion no valida');
    }
} catch (Exception $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    json_error('Error: '.$e->getMessage());
}

function generarAutomatico($pdo, $fecha_desde, $fecha_hasta, $limite, $suc_id = 0) {
    $generadas = [];
    $errores = [];
    $total = 0;
    $restantes = 0;

    // Ventas pendientes (most recent first)
    $v_sql = "SELECT v.id FROM ventas v
        LEFT JOIN asientos_contables a ON a.referencia_id=v.id AND a.referencia_tipo='ventas'
        WHERE a.id IS NULL AND DATE(v.fecha_y_hora) BETWEEN ? AND ?";
    $v_params = [$fecha_desde, $fecha_hasta];
    if ($suc_id > 0) {
        $v_sql .= " AND v.sucursal_id = ?";
        $v_params[] = $suc_id;
    }
    $v_sql .= " ORDER BY v.fecha_y_hora DESC LIMIT ?";
    $v_params[] = $limite;

    $vents = $pdo->prepare($v_sql);
    $vents->execute($v_params);
    foreach ($vents as $v) {
        try {
            $id = generarAsientoVenta($pdo, $v['id']);
            $generadas[] = "Venta #{$v['id']} -> Asiento #$id";
            $total++;
        } catch (Exception $e) {
            $errores[] = "Venta #{$v['id']}: ".$e->getMessage();
        }
    }

    if ($total >= $limite) {
        // Count remaining
        $v_rem_sql = "SELECT COUNT(*) FROM ventas v
            LEFT JOIN asientos_contables a ON a.referencia_id=v.id AND a.referencia_tipo='ventas'
            WHERE a.id IS NULL AND DATE(v.fecha_y_hora) BETWEEN ? AND ?";
        $v_rem_params = [$fecha_desde, $fecha_hasta];
        if ($suc_id > 0) {
            $v_rem_sql .= " AND v.sucursal_id = ?";
            $v_rem_params[] = $suc_id;
        }
        $rem = $pdo->prepare($v_rem_sql);
        $rem->execute($v_rem_params);
        $restantes += intval($rem->fetchColumn());
        return ['total'=>$total, 'generadas'=>$generadas, 'errores'=>$errores, 'restantes'=>$restantes, 'limite_alcanzado'=>true];
    }

    // Compras pendientes (most recent first)
    if ($suc_id == 0 || $suc_id == 1) {
        $restantes_limite = $limite - $total;
        $comps = $pdo->prepare("SELECT c.id FROM compras c
            LEFT JOIN asientos_contables a ON a.referencia_id=c.id AND a.referencia_tipo='compras'
            WHERE a.id IS NULL AND DATE(c.fecha_compra) BETWEEN ? AND ?
            ORDER BY c.fecha_compra DESC LIMIT ?");
        $comps->execute([$fecha_desde, $fecha_hasta, $restantes_limite]);
        foreach ($comps as $c) {
            try {
                $id = generarAsientoCompra($pdo, $c['id']);
                $generadas[] = "Compra #{$c['id']} -> Asiento #$id";
                $total++;
            } catch (Exception $e) {
                $errores[] = "Compra #{$c['id']}: ".$e->getMessage();
            }
        }
    }

    if ($total >= $limite) {
        if ($suc_id == 0 || $suc_id == 1) {
            $rem = $pdo->prepare("SELECT COUNT(*) FROM compras c
                LEFT JOIN asientos_contables a ON a.referencia_id=c.id AND a.referencia_tipo='compras'
                WHERE a.id IS NULL AND DATE(c.fecha_compra) BETWEEN ? AND ?");
            $rem->execute([$fecha_desde, $fecha_hasta]);
            $restantes += intval($rem->fetchColumn());
        }
        $g_rem_sql = "SELECT COUNT(*) FROM gastos_operativos g
            LEFT JOIN asientos_contables a ON a.referencia_id=g.id AND a.referencia_tipo='gastos_operativos'
            WHERE a.id IS NULL AND g.fecha_gasto BETWEEN ? AND ?";
        $g_rem_params = [$fecha_desde, $fecha_hasta];
        if ($suc_id > 0) {
            $g_rem_sql .= " AND g.sucursal_id = ?";
            $g_rem_params[] = $suc_id;
        }
        $rem2 = $pdo->prepare($g_rem_sql);
        $rem2->execute($g_rem_params);
        $restantes += intval($rem2->fetchColumn());
        return ['total'=>$total, 'generadas'=>$generadas, 'errores'=>$errores, 'restantes'=>$restantes, 'limite_alcanzado'=>true];
    }

    // Gastos pendientes (most recent first)
    $restantes_limite = $limite - $total;
    $g_sql = "SELECT g.id FROM gastos_operativos g
        LEFT JOIN asientos_contables a ON a.referencia_id=g.id AND a.referencia_tipo='gastos_operativos'
        WHERE a.id IS NULL AND g.fecha_gasto BETWEEN ? AND ?";
    $g_params = [$fecha_desde, $fecha_hasta];
    if ($suc_id > 0) {
        $g_sql .= " AND g.sucursal_id = ?";
        $g_params[] = $suc_id;
    }
    $g_sql .= " ORDER BY g.fecha_gasto DESC LIMIT ?";
    $g_params[] = $restantes_limite;

    $gastos = $pdo->prepare($g_sql);
    $gastos->execute($g_params);
    foreach ($gastos as $g) {
        try {
            $id = generarAsientoGasto($pdo, $g['id']);
            $generadas[] = "Gasto #{$g['id']} -> Asiento #$id";
            $total++;
        } catch (Exception $e) {
            $errores[] = "Gasto #{$g['id']}: ".$e->getMessage();
        }
    }

    return ['total'=>$total, 'generadas'=>$generadas, 'errores'=>$errores, 'restantes'=>0, 'limite_alcanzado'=>false];
}

function generarAsientoVenta($pdo, $venta_id) {
    $chk = $pdo->prepare("SELECT id FROM asientos_contables WHERE referencia_id=? AND referencia_tipo='ventas'");
    $chk->execute([$venta_id]);
    if ($chk->fetch()) throw new Exception('Ya existe asiento para esta venta');

    $v = $pdo->prepare("SELECT v.*, tp.nombre as tipo_pago_nombre FROM ventas v
        JOIN tipopago tp ON tp.id=v.id_tipopago WHERE v.id=?");
    $v->execute([$venta_id]);
    $venta = $v->fetch();
    if (!$venta) throw new Exception('Venta no encontrada');

    $td = $pdo->prepare("SELECT COALESCE(SUM(subtotal),0) as subtotal, COALESCE(SUM(costo_promedio_al_vender*cantidad),0) as costo FROM detalle_ventas WHERE venta_id=?");
    $td->execute([$venta_id]);
    $det = $td->fetch();
    $fecha = substr($venta['fecha_y_hora'], 0, 10);
    $subtotal = floatval($det['subtotal']) ?: floatval($venta['subtotal']) ?: floatval($venta['total']);
    $total = floatval($venta['total']);
    $costo = floatval($det['costo'] ?? 0);
    $descuento = floatval($venta['descuento'] ?? 0);
    $impuestos = floatval($venta['impuestos'] ?? 0);

    $cuenta_ventas = 33;
    $cuenta_caja = 3;
    $cuenta_costo = 38;
    $cuenta_inventario = 9;
    $cuenta_iva = 19;
    $cuenta_descuento_ventas = 34;

    $pdo->beginTransaction();
    $s = $pdo->prepare("INSERT INTO asientos_contables (fecha,concepto,tipo_comprobante,referencia_id,referencia_tipo,usuario_id,sucursal_id) VALUES (?,?,'venta',?,'ventas',?,?)");
    $s->execute([$fecha, 'Venta #'.$venta_id.' ('.$venta['tipo_pago_nombre'].')', $venta_id, $venta['usuario_id']??null, $venta['sucursal_id'] ?: 1]);
    $asiento_id = intval($pdo->lastInsertId());
    $ins = $pdo->prepare("INSERT INTO asientos_detalle (asiento_id,cuenta_id,descripcion,debe,haber) VALUES (?,?,?,?,?)");

    $ins->execute([$asiento_id, $cuenta_caja, 'Venta contado #'.$venta_id, $total, 0]);
    $ins->execute([$asiento_id, $cuenta_ventas, 'Venta #'.$venta_id, 0, $subtotal]);
    if ($descuento > 0) {
        $ins->execute([$asiento_id, $cuenta_descuento_ventas, 'Descuento venta #'.$venta_id, $descuento, 0]);
    }
    if ($impuestos > 0) {
        $ins->execute([$asiento_id, $cuenta_iva, 'IVA venta #'.$venta_id, 0, $impuestos]);
    }
    if ($costo > 0) {
        $ins->execute([$asiento_id, $cuenta_costo, 'Costo venta #'.$venta_id, $costo, 0]);
        $ins->execute([$asiento_id, $cuenta_inventario, 'Inventario venta #'.$venta_id, 0, $costo]);
    }

    $pdo->commit();
    return $asiento_id;
}

function generarAsientoCompra($pdo, $compra_id) {
    $chk = $pdo->prepare("SELECT id FROM asientos_contables WHERE referencia_id=? AND referencia_tipo='compras'");
    $chk->execute([$compra_id]);
    if ($chk->fetch()) throw new Exception('Ya existe asiento para esta compra');

    $c = $pdo->prepare("SELECT c.*, l.nombre as proveedor_nombre FROM compras c LEFT JOIN lugarcompra l ON l.id=c.id_lugarCompra WHERE c.id=?");
    $c->execute([$compra_id]);
    $compra = $c->fetch();
    if (!$compra) throw new Exception('Compra no encontrada');

    $td = $pdo->prepare("SELECT COALESCE(SUM(costo_total),0) as total FROM compras_detalle WHERE compra_id=?");
    $td->execute([$compra_id]);
    $det = $td->fetch();
    $total_detalle = floatval($det['total'] ?? 0);
    $total = $total_detalle ?: floatval($compra['total']);
    $fecha = substr($compra['fecha_compra'], 0, 10);

    $cuenta_inventario = 9;
    $cuenta_proveedores = 16;
    $cuenta_caja = 3;

    $pdo->beginTransaction();
    $s = $pdo->prepare("INSERT INTO asientos_contables (fecha,concepto,tipo_comprobante,referencia_id,referencia_tipo,usuario_id,sucursal_id) VALUES (?,?,'compra',?,'compras',?,?)");
    $s->execute([$fecha, 'Compra #'.$compra_id.' - '.($compra['proveedor_nombre']??'Sin proveedor'), $compra_id, null, 1]);
    $asiento_id = intval($pdo->lastInsertId());
    $ins = $pdo->prepare("INSERT INTO asientos_detalle (asiento_id,cuenta_id,descripcion,debe,haber) VALUES (?,?,?,?,?)");

    $ins->execute([$asiento_id, $cuenta_inventario, 'Compra #'.$compra_id, $total, 0]);
    if ($compra['tipo_pago'] === 'credito' || $compra['tipo_pago'] === 'mixto') {
        $credito = floatval($compra['monto_credito'] ?? $total);
        if ($compra['tipo_pago'] === 'mixto') {
            $efectivo = floatval($compra['monto_efectivo'] ?? 0);
            if ($efectivo > 0) $ins->execute([$asiento_id, $cuenta_caja, 'Pago efectivo compra #'.$compra_id, 0, $efectivo]);
            if ($credito > 0) $ins->execute([$asiento_id, $cuenta_proveedores, 'Credito proveedor compra #'.$compra_id, 0, $credito]);
        } else {
            $ins->execute([$asiento_id, $cuenta_proveedores, 'Proveedor compra #'.$compra_id, 0, $total]);
        }
    } else {
        $ins->execute([$asiento_id, $cuenta_caja, 'Pago compra #'.$compra_id, 0, $total]);
    }

    $pdo->commit();
    return $asiento_id;
}

function generarAsientoGasto($pdo, $gasto_id) {
    $chk = $pdo->prepare("SELECT id FROM asientos_contables WHERE referencia_id=? AND referencia_tipo='gastos_operativos'");
    $chk->execute([$gasto_id]);
    if ($chk->fetch()) throw new Exception('Ya existe asiento para este gasto');

    $g = $pdo->prepare("SELECT g.*, cg.nombre as categoria_nombre FROM gastos_operativos g
        JOIN categorias_gastos cg ON cg.id=g.categoria_id WHERE g.id=?");
    $g->execute([$gasto_id]);
    $gasto = $g->fetch();
    if (!$gasto) throw new Exception('Gasto no encontrado');

    $mapa = ['sueldos'=>42,'alquiler'=>44,'servicios'=>43,'transporte'=>45,'marketing'=>46,'suministros'=>47,'mantenimiento'=>48,'impuestos'=>49,'honorarios'=>51,'bancarios'=>52];
    $cat = strtolower($gasto['categoria_nombre']);
    $cuenta_gasto_id = 43;
    foreach ($mapa as $k=>$v) { if (strpos($cat, $k) !== false) { $cuenta_gasto_id = $v; break; } }

    $monto = floatval($gasto['monto']);
    $cuenta_caja = 3;

    $pdo->beginTransaction();
    $s = $pdo->prepare("INSERT INTO asientos_contables (fecha,concepto,tipo_comprobante,referencia_id,referencia_tipo,usuario_id,sucursal_id) VALUES (?,?,'gasto',?,'gastos_operativos',?,?)");
    $s->execute([$gasto['fecha_gasto'], 'Gasto: '.$gasto['categoria_nombre'].' - '.($gasto['proveedor_nombre']??'N/A'), $gasto_id, $gasto['usuario_id']??null, $gasto['sucursal_id'] ?: 1]);
    $asiento_id = intval($pdo->lastInsertId());
    $ins = $pdo->prepare("INSERT INTO asientos_detalle (asiento_id,cuenta_id,descripcion,debe,haber) VALUES (?,?,?,?,?)");
    $ins->execute([$asiento_id, $cuenta_gasto_id, $gasto['notas']?:$gasto['categoria_nombre'], $monto, 0]);
    $ins->execute([$asiento_id, $cuenta_caja, 'Pago: '.$gasto['categoria_nombre'], 0, $monto]);

    $pdo->commit();
    return $asiento_id;
}
