<?php
/**
 * API: Certificar Factura FEL (Adaptado para SufarmaERP)
 */

header('Content-Type: application/json');
require_once '../config/fel_config.php';
require_once '../config/db_mysqli.php';

/** @var mysqli $conn */
/** @var mysqli_result $resItems */

try {
    $input = json_decode(file_get_contents('php://input'), true);
    if (!$input) throw new Exception('Datos inválidos');

    // 1. DETERMINAR SUCURSAL PARA LA FACTURACIÓN
    $idSucursalActiva = $input['sucursal_id'] ?? '';
    $venta_id = $input['venta_id'] ?? null;

    if (empty($idSucursalActiva) && !empty($venta_id)) {
        // Fallback: Si se eligió "Todas", determinar la sucursal de la venta
        $ids = explode(',', $venta_id);
        $primeraVentaId = (int)$ids[0];
        $stmtVenta = $conn->prepare("SELECT sucursal_id FROM ventas WHERE id = ?");
        $stmtVenta->bind_param("i", $primeraVentaId);
        $stmtVenta->execute();
        $resVenta = $stmtVenta->get_result()->fetch_assoc();
        if ($resVenta) {
            $idSucursalActiva = $resVenta['sucursal_id'];
        }
    }

    if (empty($idSucursalActiva)) {
        throw new Exception('No se pudo determinar la sucursal para la facturación.');
    }

    // 2. OBTENER DATOS DE LA SUCURSAL
    $stmtSuc = $conn->prepare("SELECT * FROM sucursales WHERE id = ?");
    $stmtSuc->bind_param("i", $idSucursalActiva);
    $stmtSuc->execute();
    $dbSucursal = $stmtSuc->get_result()->fetch_assoc();

    if (!$dbSucursal) {
        throw new Exception("La sucursal ID $idSucursalActiva no existe.");
    }

    $nombreComercial = !empty($dbSucursal['nombre_fel']) ? $dbSucursal['nombre_fel'] : $dbSucursal['nombre'];
    $codigoSat = !empty($dbSucursal['codigo_establecimiento']) ? $dbSucursal['codigo_establecimiento'] : 1;
    
    $direccionEmisor = $dbSucursal['direccion'];
    $municipioEmisor = !empty($dbSucursal['municipio']) ? $dbSucursal['municipio'] : 'GUATEMALA';
    $departamentoEmisor = !empty($dbSucursal['departamento']) ? $dbSucursal['departamento'] : 'GUATEMALA';

    // Datos recibidos del Frontend
    $venta_id = $input['venta_id'] ?? null;
    $buyer = $input['buyer'] ?? []; 
    $items = $input['items'] ?? []; 
    $observations = $input['observations'] ?? 'Gracias por su compra';

    // 2.5 AUTOLOAD ITEMS SI NO SE PROPORCIONAN (MODO DIRECTO)
    if (empty($items) && !empty($venta_id)) {
        $ids = explode(',', $venta_id);
        $ids = array_map('intval', $ids);
        $placeholders = implode(',', array_fill(0, count($ids), '?'));

        $sqlDetalles = "SELECT dv.cantidad, dv.precio, dv.subtotal, p.NombreComercial as producto_nombre, p.exento_iva
                        FROM detalle_ventas dv
                        JOIN productos p ON dv.producto_id = p.id
                        WHERE dv.venta_id IN ($placeholders) AND dv.facturado = 1";
        
        $stmtDetalles = $conn->prepare($sqlDetalles);
        /** @var mysqli_stmt $stmtDetalles */
        $stmtDetalles->bind_param(str_repeat('i', count($ids)), ...$ids);
        $stmtDetalles->execute();
        $resItems = $stmtDetalles->get_result();
        
        while ($d = mysqli_fetch_assoc($resItems)) {
            $items[] = [
                'producto_nombre' => $d['producto_nombre'],
                'cantidad' => $d['cantidad'],
                'precio' => $d['precio'],
                'subtotal' => $d['subtotal'],
                'exento_iva' => $d['exento_iva']
            ];
        }
    }

    if (empty($items)) {
        throw new Exception('No hay productos facturables para certificar en estas ventas.');
    }

    // 3. Obtener Token
    $token = getFELToken();
    if (!$token) throw new Exception('No se pudo obtener token de Digifact');

    // 4. Preparar Datos Generales
    date_default_timezone_set('America/Guatemala'); 
    
    if (!empty($input['fecha_emision'])) {
        $fecha_base = $input['fecha_emision']; 
        $hora_actual = date("H:i:s");
        $fecha_completa = $fecha_base . "T" . $hora_actual;
    } else {
        $fecha_completa = date("Y-m-d\TH:i:s");
    }

    $fecha_emision = $fecha_completa . "-06:00";
    $referencia = "FAC-" . time();

    // 5. Preparar Cliente (FORZAR CF SI ES MODO DIRECTO O VACÍO)
    $buyer_tax_id = strtoupper(trim($buyer['taxID'] ?? 'CF'));
    $buyer_name   = strtoupper(trim($buyer['name'] ?? 'CONSUMIDOR FINAL'));
    $buyer_address = strtoupper(trim($buyer['address'] ?? 'CIUDAD'));
    $buyer_type   = $buyer['type'] ?? 'CF'; 

    if ($buyer_type === 'CF' || $buyer_tax_id === 'CF' || $buyer_tax_id === 'C/F' || empty($buyer_tax_id)) {
        $buyer_tax_id = 'CF';
        $buyer_name = 'CONSUMIDOR FINAL'; 
        $buyer_address = 'CIUDAD';
    }

    // 6. Procesar Items
    $invoice_items = [];
    $total_iva = 0;
    $total_invoice = 0;
    $tiene_exentos = false; 

    foreach ($items as $index => $item) {
        $cantidad    = floatval($item['cantidad']);
        $precio_unit = floatval($item['precio']);
        $total_linea = $cantidad * $precio_unit;
        
        $es_exento = isset($item['exento_iva']) && $item['exento_iva'] == 1;

        if ($es_exento) {
            $base_imponible = number_format($total_linea, 6, '.', '');
            $monto_iva = "0.000000";
            $codigo_impuesto = "2"; 
            $tiene_exentos = true;
        } else {
            $base = $total_linea / 1.12;
            $iva  = $total_linea - $base;
            
            $base_imponible = number_format($base, 6, '.', '');
            $monto_iva      = number_format($iva, 6, '.', '');
            $codigo_impuesto = "1"; 
        }

        $total_iva += (float)$monto_iva;
        $total_invoice += $total_linea;

        $invoice_items[] = [
            "Number" => (string)($index + 1),
            "Type" => "Bien",
            "Description" => substr(($item['producto_nombre'] ?? ($item['nombre'] ?? 'Producto')), 0, 490),
            "Qty" => number_format($cantidad, 6, '.', ''),
            "UnitOfMeasure" => "UNI",
            "Price" => number_format($precio_unit, 6, '.', ''),
            "Taxes" => [
                "Tax" => [[
                    "Code" => $codigo_impuesto, 
                    "Description" => "IVA",
                    "TaxableAmount" => $base_imponible,
                    "Amount" => $monto_iva
                ]]
            ],
            "Totals" => [
                "TotalItem" => number_format($total_linea, 6, '.', '')
            ]
        ];
    }

    // 7. Preparar Frases
    $frases = [
        ["Name" => "TipoFrase", "Data" => "1", "Value" => "1"],
        ["Name" => "Escenario", "Data" => "1", "Value" => "1"]
    ];

    if ($tiene_exentos) {
        $frases[] = ["Name" => "TipoFrase", "Data" => "2", "Value" => "4"];
        $frases[] = ["Name" => "Escenario", "Data" => "2", "Value" => "10"];
    }

    // 8. Datos del Comprador
    $buyerNode = [
        "TaxID" => $buyer_tax_id,
        "Name" => $buyer_name,
        "AddressInfo" => [
            "Address" => $buyer_address,
            "City" => "01001",
            "District" => "GUATEMALA",
            "State" => "GUATEMALA",
            "Country" => "GT"
        ]
    ];

    if ($buyer_type === 'CUI') {
        $buyerNode["TaxIDType"] = "CUI";
    }

    // 9. Construir JSON para Digifact
    $factura = [
        "Version" => "1.00",
        "CountryCode" => "GT",
        "Header" => [
            "DocType" => "FACT",
            "IssuedDateTime" => $fecha_emision,
            "Currency" => "GTQ"
        ],
        "Seller" => [
            "TaxID" => FEL_NIT_EMISOR,
            "Name" => FEL_RAZON_SOCIAL,
            "TaxIDAdditionalInfo" => [ ["Name" => "AfiliacionIVA", "Data" => null, "Value" => "GEN"] ],
            "BranchInfo" => [
                "Code" => (string)$codigoSat, 
                "Name" => $nombreComercial,   
                "AddressInfo" => [
                    "Address" => $direccionEmisor,
                    "City" => "01001",
                    "District" => $municipioEmisor,    
                    "State" => $departamentoEmisor,
                    "Country" => "GT"
                ]
            ],
            "AdditionlInfo" => $frases
        ],
        "Buyer" => $buyerNode,
        "Items" => $invoice_items,
        "Totals" => [
            "TotalTaxes" => [
                "TotalTax" => [[
                    "Description" => "IVA",
                    "Amount" => number_format($total_iva, 6, '.', '')
                ]]
            ],
            "GrandTotal" => [
                "InvoiceTotal" => number_format($total_invoice, 6, '.', '')
            ]
        ],
        "AdditionalDocumentInfo" => [
            "AdditionalInfo" => [[
                "Code" => $referencia,
                "Type" => "ADENDA",
                "AditionalData" => [
                    "Data" => [[
                        "Name" => "INFORMACION_ADICIONAL",
                        "Info" => [[
                            "Name" => "OBSERVACIONES",
                            "Data" => null,
                            "Value" => $observations
                        ]]
                    ]]
                ],
                "AditionalInfo" => [[
                    "Name" => "VALIDAR_REFERENCIA_INTERNA",
                    "Data" => null,
                    "Value" => "NO_VALIDAR"
                ]]
            ]]
        ]
    ];

    // 10. Enviar a Digifact
    $json_nuc = json_encode($factura);
    $nit_pad = str_pad(FEL_NIT_EMISOR, 12, "0", STR_PAD_LEFT);
    
    $url = FEL_CERT_URL . "?" . http_build_query([
        "TAXID" => $nit_pad, 
        "USERNAME" => FEL_USUARIO, 
        "FORMAT" => "XML"
    ]);

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json_nuc);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Authorization: " . $token,
        "Content-Type: application/json"
    ]);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $res = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) throw new Exception('Error HTTP ' . $httpCode . ' al conectar con certificador.');

    $resultado = json_decode($res, true);

    // 11. Respuesta al Frontend
    if (isset($resultado['code']) && $resultado['code'] == 1) {
        
        if ($venta_id) {
            // Soporte para múltiples IDs (Facturación Unificada)
            $ids = explode(',', $venta_id);
            $ids = array_map('intval', $ids);
            $ids = array_filter($ids, function($id) { return $id > 0; });

            if (!empty($ids)) {
                $placeholders = implode(',', array_fill(0, count($ids), '?'));
                $stmt = $conn->prepare("UPDATE detalle_ventas SET estado_factura = 'FACTURADO', facturado = 1 WHERE venta_id IN ($placeholders)");
                $stmt->bind_param(str_repeat('i', count($ids)), ...$ids);
                $stmt->execute();
            }
        }

        echo json_encode([
            'success' => true,
            'data' => [
                'uuid' => $resultado['authNumber'],
                'serie' => $resultado['batch'],
                'numero' => $resultado['serial'],
                'xml' => $resultado['responseData1'] ?? '',
                'fecha' => $resultado['authTime'] ?? date("Y-m-d H:i:s"),
                'emisor' => [
                    'nombre' => $nombreComercial,
                    'nit' => FEL_NIT_EMISOR,
                    'direccion' => $direccionEmisor . ", " . $municipioEmisor . ", " . $departamentoEmisor
                ],
                'receptor' => $buyerNode,
                'items' => $invoice_items,
                'total' => $total_invoice
            ]
        ]);
    } else {
        $msg = $resultado['message'] ?? 'Error desconocido';
        $desc = $resultado['description'] ?? '';
        throw new Exception("Digifact Error: $msg - $desc");
    }

} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
?>
