<?php
/*
|--------------------------------------------------------------------------
| Exportar evaluacion visual-auditiva a Excel (.xlsx nativo)
|--------------------------------------------------------------------------
| Genera un .xlsx real sin librerias externas y sin ZipArchive.
| Permite alto fijo de filas y manejo correcto de acentos.
*/

session_start();

if (!isset($_SESSION['id'])) {
    header('Location: login.php');
    exit;
}

require_once('conex2.php');

/* ---- Conexion ---- */
if (!function_exists('obtener_conexion_actual')) {
    function obtener_conexion_actual() {
        static $c = null;

        if ($c instanceof mysqli) {
            return $c;
        }

        foreach (['con','conexion','conn','mysqli','link','db','bd'] as $v) {
            if (isset($GLOBALS[$v]) && $GLOBALS[$v] instanceof mysqli) {
                $c = $GLOBALS[$v];
                break;
            }
        }

        if (!$c && function_exists('conectar')) {
            $c = conectar();
        }

        if (!$c || !($c instanceof mysqli)) {
            die('Sin conexion a BD');
        }

        mysqli_set_charset($c, 'utf8');
        mysqli_query($c, "SET NAMES utf8");
        mysqli_query($c, "SET CHARACTER SET utf8");

        return $c;
    }
}

$conexion = obtener_conexion_actual();

/* ---- Parametro de busqueda ---- */
$busqueda = isset($_GET['txtBusqueda']) ? trim($_GET['txtBusqueda']) : '';
$busquedaEscapada = mysqli_real_escape_string($conexion, $busqueda);

/* ---- Consulta sin LIMIT ---- */
$query = "
    SELECT
        CONCAT(
            COALESCE(p.apellido_paterno_paciente, ''), ' ',
            COALESCE(p.apellido_materno_paciente, ''), ' ',
            COALESCE(p.nombre_paciente, '')
        ) AS nombre,
        v.mes_estudio,
        p.semanas_gestacion,
        CASE
            WHEN p.semanas_gestacion IS NULL
              OR TRIM(CAST(p.semanas_gestacion AS CHAR)) = ''
              OR p.fecha_nacimiento_paciente IS NULL
              OR p.fecha_nacimiento_paciente = '0000-00-00'
              OR p.fecha_nacimiento_paciente = '0000-00-00 00:00:00'
            THEN NULL
            WHEN CAST(p.semanas_gestacion AS UNSIGNED) >= 40
            THEN p.fecha_nacimiento_paciente
            ELSE DATE_ADD(
                p.fecha_nacimiento_paciente,
                INTERVAL (40 - CAST(p.semanas_gestacion AS UNSIGNED)) WEEK
            )
        END AS fecha_edad_corregida,
        v.fecha_estudio,
        v.totalVisual,
        v.percentilVisual,
        v.clasificacionVisual,
        v.totalAuditiva,
        v.percentilAuditiva,
        v.clasificacionAuditiva,
        v.totalEstudio,
        v.percentilEstudio,
        v.clasificacionEstudio,
        v.observaciones
    FROM visualauditiva v
    INNER JOIN paciente p
        ON v.clave_paciente = p.clave_paciente
    WHERE CONCAT(
        COALESCE(p.apellido_paterno_paciente, ''), ' ',
        COALESCE(p.apellido_materno_paciente, ''), ' ',
        COALESCE(p.nombre_paciente, '')
    ) LIKE '%{$busquedaEscapada}%'
    ORDER BY v.fecha_estudio DESC, v.id_numero_estudio DESC
";

$res = mysqli_query($conexion, $query);

if (!$res) {
    die('Error en la consulta: ' . mysqli_error($conexion));
}

/* ---- Configuracion visual ---- */
$ALTO_FILA = 28;
$ANCHO_NORMAL = 22;
$ANCHO_NOMBRE = 36;
$ANCHO_FECHA = 24;
$ANCHO_OBSERVACIONES = 60;

/* ---- Encabezados ---- */
$encabezados = array(
    'Nombre paciente',
    'Mes de evaluación',
    'Semanas de gestación',
    'Fecha edad corregida',
    'Fecha de estudio',
    'Puntaje total visual',
    'Percentil visual',
    'Clasificación visual',
    'Puntaje total auditivo',
    'Percentil auditivo',
    'Clasificación auditivo',
    'Puntaje total estudio',
    'Percentil total estudio',
    'Clasificación total estudio',
    'Observaciones',
);

/* ---- Funciones de texto ---- */
function textoUtf8Valido($texto) {
    return preg_match('//u', $texto) === 1;
}

function normalizarTextoExcel($valor) {
    if ($valor === null) {
        return '';
    }

    $texto = (string)$valor;

    $texto = str_replace(["\r\n", "\r", "\n"], ' ', $texto);
    $texto = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $texto);

    if ($texto !== '' && !textoUtf8Valido($texto)) {
        if (function_exists('iconv')) {
            $convertido = @iconv('Windows-1252', 'UTF-8//IGNORE', $texto);

            if ($convertido !== false) {
                $texto = $convertido;
            }
        }
    }

    if (preg_match('/(Ã|Â|â€|â€™|â€œ|â€�|â€“|â€”)/u', $texto)) {
        if (function_exists('iconv')) {
            $corregido = @iconv('UTF-8', 'Windows-1252//IGNORE', $texto);

            if ($corregido !== false && textoUtf8Valido($corregido)) {
                $texto = $corregido;
            }
        }

        $reemplazos = array(
            'Ã¡' => 'á',
            'Ã©' => 'é',
            'Ã­' => 'í',
            'Ã³' => 'ó',
            'Ãº' => 'ú',
            'ÃÁ' => 'Á',
            'Ã‰' => 'É',
            'ÃÍ' => 'Í',
            'Ã“' => 'Ó',
            'Ãš' => 'Ú',
            'Ã±' => 'ñ',
            'Ã‘' => 'Ñ',
            'Â¿' => '¿',
            'Â¡' => '¡',
            'Â°' => '°',
            'Â´' => '´',
            'Â¨' => '¨',
            'â€™' => "'",
            'â€œ' => '"',
            'â€�' => '"',
            'â€“' => '-',
            'â€”' => '-',
            'Â'   => '',
        );

        $texto = strtr($texto, $reemplazos);
    }

    return trim($texto);
}

function xmlEscapar($valor) {
    $texto = normalizarTextoExcel($valor);

    return htmlspecialchars($texto, ENT_XML1 | ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function formatearFechaExcel($fecha) {
    $fecha = trim((string)$fecha);

    if ($fecha === '' || $fecha === '0000-00-00' || $fecha === '0000-00-00 00:00:00') {
        return '';
    }

    $timestamp = strtotime($fecha);

    if ($timestamp === false) {
        return $fecha;
    }

    return date('Y-m-d', $timestamp);
}

/* ---- Funciones para Excel ---- */
function nombreColumnaExcel($numero) {
    $letras = '';

    while ($numero > 0) {
        $modulo = ($numero - 1) % 26;
        $letras = chr(65 + $modulo) . $letras;
        $numero = intval(($numero - $modulo) / 26);
    }

    return $letras;
}

function celdaInlineStr($valor, $columna, $fila, $estilo) {
    $ref = nombreColumnaExcel($columna) . $fila;

    return '<c r="' . $ref . '" t="inlineStr" s="' . $estilo . '"><is><t>' . xmlEscapar($valor) . '</t></is></c>';
}

/* ---- Obtener datos ---- */
$filas = array();

while ($fila = mysqli_fetch_assoc($res)) {
    $filas[] = array(
        isset($fila['nombre'])                ? $fila['nombre'] : '',
        isset($fila['mes_estudio'])           ? $fila['mes_estudio'] : '',
        isset($fila['semanas_gestacion'])     ? $fila['semanas_gestacion'] : '',
        isset($fila['fecha_edad_corregida'])  ? formatearFechaExcel($fila['fecha_edad_corregida']) : '',
        isset($fila['fecha_estudio'])         ? formatearFechaExcel($fila['fecha_estudio']) : '',
        isset($fila['totalVisual'])           ? $fila['totalVisual'] : '',
        isset($fila['percentilVisual'])       ? $fila['percentilVisual'] : '',
        isset($fila['clasificacionVisual'])   ? $fila['clasificacionVisual'] : '',
        isset($fila['totalAuditiva'])         ? $fila['totalAuditiva'] : '',
        isset($fila['percentilAuditiva'])     ? $fila['percentilAuditiva'] : '',
        isset($fila['clasificacionAuditiva']) ? $fila['clasificacionAuditiva'] : '',
        isset($fila['totalEstudio'])          ? $fila['totalEstudio'] : '',
        isset($fila['percentilEstudio'])      ? $fila['percentilEstudio'] : '',
        isset($fila['clasificacionEstudio'])  ? $fila['clasificacionEstudio'] : '',
        isset($fila['observaciones'])         ? $fila['observaciones'] : '',
    );
}

/* ====================================================================
   Archivos internos del .xlsx
   ==================================================================== */

$totalFilas = count($filas) + 1;
$totalColumnas = count($encabezados);
$dimension = 'A1:' . nombreColumnaExcel($totalColumnas) . $totalFilas;

/* ---- [Content_Types].xml ---- */
$contentTypes = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
    <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
    <Default Extension="xml" ContentType="application/xml"/>
    <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
    <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
    <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
</Types>';

/* ---- _rels/.rels ---- */
$rels = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
    <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
</Relationships>';

/* ---- xl/_rels/workbook.xml.rels ---- */
$wbRels = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
    <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
    <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
</Relationships>';

/* ---- xl/workbook.xml ---- */
$workbook = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
          xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
    <sheets>
        <sheet name="Visual Auditiva" sheetId="1" r:id="rId1"/>
    </sheets>
</workbook>';

/* ---- xl/styles.xml ---- */
$styles = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <fonts count="2">
        <font>
            <sz val="11"/>
            <name val="Calibri"/>
        </font>
        <font>
            <b/>
            <sz val="11"/>
            <name val="Calibri"/>
            <color rgb="FFFFFFFF"/>
        </font>
    </fonts>

    <fills count="3">
        <fill>
            <patternFill patternType="none"/>
        </fill>
        <fill>
            <patternFill patternType="gray125"/>
        </fill>
        <fill>
            <patternFill patternType="solid">
                <fgColor rgb="FF1F4E79"/>
                <bgColor indexed="64"/>
            </patternFill>
        </fill>
    </fills>

    <borders count="2">
        <border>
            <left/>
            <right/>
            <top/>
            <bottom/>
            <diagonal/>
        </border>
        <border>
            <left style="thin">
                <color rgb="FFB8B8B8"/>
            </left>
            <right style="thin">
                <color rgb="FFB8B8B8"/>
            </right>
            <top style="thin">
                <color rgb="FFB8B8B8"/>
            </top>
            <bottom style="thin">
                <color rgb="FFB8B8B8"/>
            </bottom>
            <diagonal/>
        </border>
    </borders>

    <cellStyleXfs count="1">
        <xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
    </cellStyleXfs>

    <cellXfs count="3">
        <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>
        <xf numFmtId="0" fontId="0" fillId="0" borderId="1" xfId="0" applyBorder="1" applyAlignment="1">
            <alignment vertical="center" wrapText="0"/>
        </xf>
        <xf numFmtId="0" fontId="1" fillId="2" borderId="1" xfId="0" applyFont="1" applyFill="1" applyBorder="1" applyAlignment="1">
            <alignment horizontal="center" vertical="center" wrapText="1"/>
        </xf>
    </cellXfs>

    <cellStyles count="1">
        <cellStyle name="Normal" xfId="0" builtinId="0"/>
    </cellStyles>

    <dxfs count="0"/>
    <tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleLight16"/>
</styleSheet>';

/* ---- Columnas ---- */
$cols = '<cols>';

for ($i = 1; $i <= $totalColumnas; $i++) {
    $ancho = $ANCHO_NORMAL;

    if ($i == 1) {
        $ancho = $ANCHO_NOMBRE;
    } elseif ($i == 4 || $i == 5) {
        $ancho = $ANCHO_FECHA;
    } elseif ($i == 15) {
        $ancho = $ANCHO_OBSERVACIONES;
    }

    $cols .= '<col min="' . $i . '" max="' . $i . '" width="' . $ancho . '" customWidth="1"/>';
}

$cols .= '</cols>';

/* ---- Fila de encabezados ---- */
$sheetData = '<sheetData>';

$sheetData .= '<row r="1" ht="' . $ALTO_FILA . '" customHeight="1">';

foreach ($encabezados as $index => $encabezado) {
    $sheetData .= celdaInlineStr($encabezado, $index + 1, 1, 2);
}

$sheetData .= '</row>';

/* ---- Filas de datos ---- */
$rowNum = 2;

foreach ($filas as $fila) {
    $sheetData .= '<row r="' . $rowNum . '" ht="' . $ALTO_FILA . '" customHeight="1">';

    foreach ($fila as $index => $valor) {
        $sheetData .= celdaInlineStr($valor, $index + 1, $rowNum, 1);
    }

    $sheetData .= '</row>';
    $rowNum++;
}

$sheetData .= '</sheetData>';

/* ---- xl/worksheets/sheet1.xml ---- */
$sheet = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
           xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
    <dimension ref="' . $dimension . '"/>

    <sheetViews>
        <sheetView workbookViewId="0">
            <pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
            <selection pane="bottomLeft"/>
        </sheetView>
    </sheetViews>

    <sheetFormatPr defaultRowHeight="' . $ALTO_FILA . '"/>

    ' . $cols . '

    ' . $sheetData . '

    <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
</worksheet>';

/* ====================================================================
   Crear ZIP manual SIN ZipArchive
   ==================================================================== */

function zipDosFechaHora() {
    $t = getdate();
    $year = $t['year'];

    if ($year < 1980) {
        $year = 1980;
        $month = 1;
        $day = 1;
        $hour = 0;
        $minute = 0;
        $second = 0;
    } else {
        $month = $t['mon'];
        $day = $t['mday'];
        $hour = $t['hours'];
        $minute = $t['minutes'];
        $second = $t['seconds'];
    }

    $dosTime = ($hour << 11) | ($minute << 5) | floor($second / 2);
    $dosDate = (($year - 1980) << 9) | ($month << 5) | $day;

    return array($dosTime, $dosDate);
}

function crearZipManual($archivos) {
    $localData = '';
    $centralData = '';
    $offset = 0;
    $count = 0;

    list($dosTime, $dosDate) = zipDosFechaHora();

    foreach ($archivos as $nombre => $contenido) {
        $nombre = str_replace('\\', '/', $nombre);
        $contenido = (string)$contenido;

        $crc = crc32($contenido);
        $size = strlen($contenido);
        $nameLen = strlen($nombre);

        $localHeader =
            pack(
                'VvvvvvVVVvv',
                0x04034b50,
                20,
                0,
                0,
                $dosTime,
                $dosDate,
                $crc,
                $size,
                $size,
                $nameLen,
                0
            ) . $nombre;

        $localData .= $localHeader . $contenido;

        $centralHeader =
            pack(
                'VvvvvvvVVVvvvvvVV',
                0x02014b50,
                20,
                20,
                0,
                0,
                $dosTime,
                $dosDate,
                $crc,
                $size,
                $size,
                $nameLen,
                0,
                0,
                0,
                0,
                0,
                $offset
            ) . $nombre;

        $centralData .= $centralHeader;

        $offset += strlen($localHeader) + $size;
        $count++;
    }

    $centralOffset = strlen($localData);
    $centralSize = strlen($centralData);

    $end =
        pack(
            'VvvvvVVv',
            0x06054b50,
            0,
            0,
            $count,
            $count,
            $centralSize,
            $centralOffset,
            0
        );

    return $localData . $centralData . $end;
}

/* ---- Crear .xlsx real ---- */
$xlsx = crearZipManual(array(
    '[Content_Types].xml'        => $contentTypes,
    '_rels/.rels'                => $rels,
    'xl/_rels/workbook.xml.rels' => $wbRels,
    'xl/workbook.xml'            => $workbook,
    'xl/styles.xml'              => $styles,
    'xl/worksheets/sheet1.xml'   => $sheet,
));

/* ---- Limpiar buffers para no corromper el archivo--- */
while (ob_get_level()) {
    ob_end_clean();
}

/* ---- Descargar ---- */
$nombreArchivo = 'evaluacion_visual_auditiva_' . date('Ymd_His') . '.xlsx';

header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="' . $nombreArchivo . '"');
header('Content-Length: ' . strlen($xlsx));
header('Cache-Control: max-age=0');
header('Pragma: public');

echo $xlsx;
exit;




