<?php
include_once('nomina_legal_master.php');
if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
if (!function_exists('nr_h')) {
    function nr_h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
}
if (!function_exists('nr_money')) {
    function nr_money($n){ return number_format((float)$n, 2, ',', '.'); }
}
if (!function_exists('nr_meta')) {
    function nr_meta($meta) {
        if (is_array($meta)) return $meta;
        if ($meta === null || $meta === '') return [];
        $arr = json_decode((string)$meta, true);
        return is_array($arr) ? $arr : [];
    }
}
if (!function_exists('nr_has_column')) {
    function nr_has_column($conexion, $table, $column) {
        $table = preg_replace('/[^a-zA-Z0-9_]/', '', (string)$table);
        $column = preg_replace('/[^a-zA-Z0-9_]/', '', (string)$column);
        if ($table === '' || $column === '') return false;
        $res = mysqli_query($conexion, "SHOW COLUMNS FROM `{$table}` LIKE '{$column}'");
        return $res && mysqli_num_rows($res) > 0;
    }
}
if (!function_exists('nr_float')) {
    function nr_float($value){ return ($value === null || $value === '') ? 0.0 : (float)$value; }
}
if (!function_exists('nr_corrida_info')) {
    function nr_corrida_info($conexion, $corridaId) {
        $corridaId = (int)$corridaId;
        $sql = "SELECT nc.*, p.codigo AS periodo_codigo, p.fecha_desde, p.fecha_hasta, p.es_ultima_quincena
                FROM nomina_corridas nc
                INNER JOIN periodos_nomina p ON p.id = nc.periodo_id
                WHERE nc.id = {$corridaId}
                LIMIT 1";
        $res = mysqli_query($conexion, $sql);
        return ($res && mysqli_num_rows($res)) ? mysqli_fetch_assoc($res) : null;
    }
}
if (!function_exists('nr_latest_corridas')) {
    function nr_latest_corridas($conexion, $limit = 30) {
        if (function_exists('nlm_ensure_master_schema')) { nlm_ensure_master_schema($conexion); }
        $limit = max(1, (int)$limit);
        $rows = [];
        $sql = "SELECT nc.*, p.codigo AS periodo_codigo, p.fecha_desde, p.fecha_hasta,
                       COUNT(d.persona_id) AS total_trabajadores,
                       COALESCE(SUM(d.total_asignaciones),0) AS total_asignaciones,
                       COALESCE(SUM(d.total_deducciones),0) AS total_deducciones,
                       COALESCE(SUM(d.neto_pagar),0) AS total_neto,
                       COALESCE(SUM(CASE WHEN 1=1 THEN IFNULL(d.total_patronal,0) ELSE 0 END),0) AS total_patronal
                FROM nomina_corridas nc
                INNER JOIN periodos_nomina p ON p.id = nc.periodo_id
                LEFT JOIN nomina_detalle d ON d.corrida_id = nc.id
                GROUP BY nc.id
                ORDER BY nc.id DESC
                LIMIT {$limit}";
        $res = mysqli_query($conexion, $sql);
        if ($res) while($row = mysqli_fetch_assoc($res)) $rows[] = $row;
        return $rows;
    }
}
if (!function_exists('nr_workers_for_corrida')) {
    function nr_workers_for_corrida($conexion, $corridaId) {
        if (function_exists('nlm_ensure_master_schema')) { nlm_ensure_master_schema($conexion); }
        $corridaId = (int)$corridaId;
        $rows = [];
        $hasMasterDetalle = nr_has_column($conexion, 'nomina_detalle', 'total_patronal');
        $extraDetalle = $hasMasterDetalle ? ", d.base_salario_normal, d.base_salario_integral, d.total_patronal" : ", 0 AS base_salario_normal, 0 AS base_salario_integral, 0 AS total_patronal";
        $sql = "SELECT d.persona_id, d.total_asignaciones, d.total_deducciones, d.neto_pagar" . $extraDetalle . ",
                       COALESCE(ts.nombre, p.nombre) AS nombre,
                       COALESCE(ts.apellido, p.apellido) AS apellido,
                       COALESCE(ts.cedula, p.cedula) AS cedula,
                       COALESCE(ts.id_cargo, p.id_cargo) AS id_cargo,
                       COALESCE(ts.fecha_ingreso, p.fecha_ingreso) AS fecha_ingreso,
                       COALESCE(ts.estatus_laboral, p.estatus_laboral) AS estatus_laboral,
                       COALESCE(ts.cargo, c.cargo) AS cargo,
                       COALESCE(ts.salario_monto_original, p.salario_base) AS salario_base,
                       COALESCE(ts.salario_moneda, p.moneda_salario) AS moneda_salario,
                       COALESCE(ts.salario_monto_original, c.salario) AS salario_cargo,
                       COALESCE(ts.salario_moneda, c.moneda_salario) AS moneda_cargo,
                       COALESCE(ts.bono_extra_usd_mensual, c.bono_extra_usd_mensual, 0) AS bono_extra_usd_mensual,
                       ts.salario_origen AS snapshot_salario_origen,
                       ts.salario_moneda AS snapshot_salario_moneda,
                       ts.salario_monto_original AS snapshot_salario_monto_original,
                       ts.salario_mensual_bs AS snapshot_salario_mensual_bs,
                       ts.salario_diario_bs AS snapshot_salario_diario_bs,
                       ts.salario_hora_bs AS snapshot_salario_hora_bs,
                       ts.tasa_bcv_usada AS snapshot_tasa_bcv_usada
                FROM nomina_detalle d
                INNER JOIN personas p ON p.id = d.persona_id
                LEFT JOIN cargos c ON c.id_cargo = p.id_cargo
                LEFT JOIN nomina_corrida_trabajador_snapshot ts ON ts.corrida_id = d.corrida_id AND ts.persona_id = d.persona_id
                WHERE d.corrida_id = {$corridaId}
                ORDER BY COALESCE(ts.apellido, p.apellido), COALESCE(ts.nombre, p.nombre)";
        $res = mysqli_query($conexion, $sql);
        if ($res) while($row = mysqli_fetch_assoc($res)) $rows[(int)$row['persona_id']] = $row;
        return $rows;
    }
}
if (!function_exists('nr_movements_for_corrida')) {
    function nr_movements_for_corrida($conexion, $corridaId) {
        if (function_exists('nlm_ensure_master_schema')) { nlm_ensure_master_schema($conexion); }
        $corridaId = (int)$corridaId;
        $rows = [];
        $sql = "SELECT m.persona_id, m.concepto_id, m.cantidad, m.base, m.tasa, m.monto, m.meta,
                       COALESCE(cs.codigo, c.codigo) AS codigo,
                       COALESCE(cs.nombre, c.nombre) AS nombre,
                       COALESCE(cs.tipo, c.tipo) AS tipo,
                       cs.incide_salario_normal AS snapshot_incide_salario_normal,
                       cs.incide_base_cotizacion AS snapshot_incide_base_cotizacion
                FROM nomina_movimientos m
                INNER JOIN conceptos_nomina c ON c.id = m.concepto_id
                LEFT JOIN nomina_corrida_conceptos_snapshot cs ON cs.corrida_id = m.corrida_id AND cs.concepto_id = m.concepto_id
                WHERE m.corrida_id = {$corridaId}
                ORDER BY m.persona_id, COALESCE(cs.tipo, c.tipo), COALESCE(cs.codigo, c.codigo)";
        $res = mysqli_query($conexion, $sql);
        if ($res) {
            while($row = mysqli_fetch_assoc($res)) {
                $pid = (int)$row['persona_id'];
                if (!isset($rows[$pid])) $rows[$pid] = [];
                $rows[$pid][] = $row;
            }
        }
        return $rows;
    }
}
if (!function_exists('nr_salary_context')) {
    function nr_salary_context(array $persona, array $corrida) {
        if (isset($persona['snapshot_salario_mensual_bs']) && $persona['snapshot_salario_mensual_bs'] !== null && $persona['snapshot_salario_mensual_bs'] !== '') {
            $source = strtoupper((string)($persona['snapshot_salario_origen'] ?? 'SNAPSHOT'));
            $moneda = strtoupper((string)($persona['snapshot_salario_moneda'] ?? 'VES'));
            $monto = nr_float($persona['snapshot_salario_monto_original'] ?? 0);
            return [
                'source' => $source,
                'monto' => $monto,
                'moneda' => $moneda,
                'monto_bs' => nr_float($persona['snapshot_salario_mensual_bs'] ?? 0),
                'label' => $source === 'FICHA' ? 'Definido en ficha (congelado)' : ($source === 'CARGO' ? 'Heredado del cargo (congelado)' : 'Snapshot histórico'),
            ];
        }
        $tasa = nr_float($corrida['tasa_bcv_usd'] ?? 0);
        $salPropio = ($persona['salario_base'] !== null && $persona['salario_base'] !== '');
        $salCargo = (!$salPropio && $persona['salario_cargo'] !== null && $persona['salario_cargo'] !== '');
        if ($salPropio) {
            $source = 'FICHA';
            $monto = nr_float($persona['salario_base']);
            $moneda = strtoupper((string)($persona['moneda_salario'] ?? 'VES'));
        } elseif ($salCargo) {
            $source = 'CARGO';
            $monto = nr_float($persona['salario_cargo']);
            $moneda = strtoupper((string)($persona['moneda_cargo'] ?? 'VES'));
        } else {
            $source = 'INCOMPLETO';
            $monto = 0.0;
            $moneda = 'VES';
        }
        $montoBs = ($moneda === 'USD') ? ($monto * $tasa) : $monto;
        return [
            'source' => $source,
            'monto' => $monto,
            'moneda' => $moneda,
            'monto_bs' => $montoBs,
            'label' => $source === 'FICHA' ? 'Definido en ficha' : ($source === 'CARGO' ? 'Heredado del cargo' : 'Sin salario'),
        ];
    }
}
if (!function_exists('nr_reference_text')) {
    function nr_reference_text(array $mov) {
        $meta = nr_meta($mov['meta'] ?? null);
        $parts = [];
        if ($mov['base'] !== null && $mov['base'] !== '') {
            $parts[] = 'Base Bs ' . nr_money($mov['base']);
        }
        $origenMeta = (string)($meta['origen'] ?? '');
        if ($mov['tasa'] !== null && $mov['tasa'] !== '' && !in_array($origenMeta, ['concepto_fijo_global','concepto_manual_extra'], true)) {
            $parts[] = 'Tasa ' . number_format(((float)$mov['tasa']) * 100, 2, ',', '.') . '%';
        }
        if (!empty($meta['sal_dia'])) {
            $parts[] = 'Día Bs ' . nr_money($meta['sal_dia']);
        }
        if (!empty($meta['sal_hora'])) {
            $parts[] = 'Hora Bs ' . nr_money($meta['sal_hora']);
        }
        if (isset($meta['bono_usd_mes']) && nr_float($meta['bono_usd_mes']) > 0) {
            $parts[] = nr_money($meta['bono_usd_mes']) . ' USD';
        }
        if (isset($meta['cesta_usd_mes']) && nr_float($meta['cesta_usd_mes']) > 0) {
            $parts[] = 'Cesta ' . nr_money($meta['cesta_usd_mes']) . ' USD';
        }
        if (isset($meta['dias_elegibles'])) {
            $parts[] = 'Días elegibles ' . nr_h($meta['dias_elegibles']);
        }
        if (isset($meta['tasa_bcv']) && nr_float($meta['tasa_bcv']) > 0) {
            $parts[] = 'BCV ' . number_format((float)$meta['tasa_bcv'], 4, '.', '');
        }
        if (($meta['origen'] ?? '') === 'concepto_fijo_global') {
            $base = nr_float($meta['monto_base'] ?? 0);
            $moneda = strtoupper((string)($meta['moneda_base'] ?? 'VES'));
            $parts[] = 'Fijo global ' . $moneda . ' ' . nr_money($base);
        }
        if (!empty($meta['manual_extra'])) {
            $moneda = strtoupper((string)($meta['moneda_base'] ?? 'VES'));
            $valor = nr_float($meta['valor_entrada'] ?? 0);
            if ($valor > 0) {
                $parts[] = 'Manual ' . $moneda . ' ' . nr_money($valor);
            }
        }
        if (($meta['origen'] ?? '') === 'novedades_periodo') {
            $parts[] = 'Novedad manual';
        }
        return $parts ? implode(' · ', $parts) : '—';
    }
}
if (!function_exists('nr_receipt_group')) {
    function nr_receipt_group(array $rows) {
        $asig = [];
        $ded = [];
        $pat = [];
        foreach ($rows as $row) {
            if (($row['tipo'] ?? '') === 'ASIG') $asig[] = $row;
            elseif (($row['tipo'] ?? '') === 'DED') $ded[] = $row;
            elseif (($row['tipo'] ?? '') === 'PATR') $pat[] = $row;
        }
        return [$asig, $ded, $pat];
    }
}
if (!function_exists('nr_worker_flags')) {
    function nr_worker_flags(array $movs) {
        $flags = ['con_novedades' => false, 'con_deducciones' => false, 'con_patronales' => false];
        foreach ($movs as $m) {
            $codigo = strtoupper((string)($m['codigo'] ?? ''));
            $meta = nr_meta($m['meta'] ?? null);
            if (($m['tipo'] ?? '') === 'DED' && nr_float($m['monto']) > 0) $flags['con_deducciones'] = true;
            if (($m['tipo'] ?? '') === 'PATR' && nr_float($m['monto']) > 0) $flags['con_patronales'] = true;
            if (in_array($codigo, ['A-010','B-004','B-005','B-006','B-007'], true)) $flags['con_novedades'] = true;
            if ($codigo === 'A-009' && nr_float($meta['manual_bs'] ?? 0) > 0) $flags['con_novedades'] = true;
        }
        return $flags;
    }
}
?>