<?php
declare(strict_types=1);

// Synthetic XLSX only: no application bootstrap, HTTP or database access.
$writerFile = (string)getenv('CDX_XLSX_WRITER_FILE');
if (!is_file($writerFile) || is_link($writerFile)
    || hash_file('sha256', $writerFile)
        !== '1b2a67845fe13ba1cf4f19e32f65e3249a572c0022e34e9141a67186f0e4d759') {
    throw new RuntimeException('Unbound XLSX writer source');
}
require_once $writerFile;
$dirname = sys_get_temp_dir() . '/cdx-xlsx-synthetic-' . strtoupper(bin2hex(random_bytes(8)));
if (!mkdir($dirname, 0700)) throw new RuntimeException('Private dir unavailable');
$path = $dirname . '/synthetic.xlsx';
umask(0077);
$status = 'error';
try {
    $writer = new \app\common\service\XlsxStreamWriter($path, 'Synthetic');
    $writer->open();
    $writer->writeRow(['序号','设备名称','设备编号','消费笔数','现金消费金额',
        '补贴消费金额','赠送消费金额','退款笔数','退款金额','实付总消费金额']);
    $writer->writeRow([1,'Synthetic device','EQ001',1,'1.00','0.00','0.00',0,'0.00','1.00']);
    $writer->writeRow(['合计','','',1,'1.00','0.00','0.00',0,'0.00','1.00']);
    $writer->finish();
    if (!is_file($path) || (fileperms($path) & 0777) !== 0600
        || filesize($path) > 65536) {
        throw new RuntimeException('Synthetic file bound failed');
    }
    $zip = new ZipArchive();
    if ($zip->open($path) !== true) throw new RuntimeException('ZIP open failed');
    $xml = $zip->getFromName('xl/worksheets/sheet1.xml');
    $second = $zip->getFromName('xl/worksheets/sheet2.xml');
    $zip->close();
    if (!is_string($xml) || $second !== false) throw new RuntimeException('Sheet bound failed');
    $doc = new DOMDocument();
    if (!$doc->loadXML($xml, LIBXML_NONET)) throw new RuntimeException('XML parse failed');
    $xp = new DOMXPath($doc);
    $xp->registerNamespace('s', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
    $rows = [];
    $types = [];
    foreach ($xp->query('/s:worksheet/s:sheetData/s:row') as $node) {
        $r = (int)$node->getAttribute('r');
        $rows[$r] = [];
        $types[$r] = [];
        foreach ($xp->query('s:c', $node) as $cell) {
            $ref = (string)$cell->getAttribute('r');
            $col = preg_replace('/\d+$/', '', $ref);
            $text = (string)$cell->getAttribute('t') === 'inlineStr';
            $rows[$r][$col] = (string)$xp->evaluate(
                $text ? 'string(s:is/s:t)' : 'string(s:v)', $cell);
            $types[$r][$col] = $text ? 'text' : 'number';
        }
    }
    if (count($rows) !== 3 || count($rows[1]) !== 10
        || count($rows[2]) !== 10 || count($rows[3]) !== 8
        || $rows[1]['E'] !== '现金消费金额'
        || $rows[2]['E'] !== '1.00' || $rows[3]['E'] !== '1.00'
        || $rows[2]['C'] !== 'EQ001' || $rows[3]['A'] !== '合计'
        || $types[2]['D'] !== 'number' || $types[2]['E'] !== 'text') {
        throw new RuntimeException('Synthetic cell/type check failed');
    }
    $status = 'pass';
} finally {
    $removed = true;
    foreach ([$path, $path . '.tmp', $path . '.sheet.xml.tmp'] as $exact) {
        if (is_file($exact) && !unlink($exact)) $removed = false;
    }
    if (is_dir($dirname) && !rmdir($dirname)) $removed = false;
    echo json_encode(['synthetic_zip_dom' => $status,
        'private_files_removed' => $removed], JSON_UNESCAPED_SLASHES) . PHP_EOL;
    if (!$removed) exit(1);
}
