<?php
/**
 * Simple XLSX Parser - reads xlsx rows without external deps
 */
class SimpleXlsx {
    private $sharedStrings = [];
    private $sheets = [];

    public static function parse($file) {
        $obj = new self();
        return $obj->load($file) ? $obj : false;
    }

    private function load($file) {
        if (!file_exists($file)) return false;
        $zip = new ZipArchive();
        if ($zip->open($file) !== true) return false;

        // Shared strings
        $ss = $zip->getFromName('xl/sharedStrings.xml');
        if ($ss) {
            $xml = simplexml_load_string($ss);
            foreach ($xml->si as $si) {
                $text = '';
                if (isset($si->t)) {
                    $text = (string)$si->t;
                } else {
                    foreach ($si->r as $r) {
                        if (isset($r->t)) $text .= (string)$r->t;
                    }
                }
                $this->sharedStrings[] = $text;
            }
        }

        // Workbook rels to find sheet files
        $wbRel = $zip->getFromName('xl/_rels/workbook.xml.rels');
        $sheetFiles = [];
        if ($wbRel) {
            $xml = simplexml_load_string($wbRel);
            foreach ($xml->Relationship as $r) {
                $type = (string)$r['Type'];
                if (strpos($type, 'worksheet') !== false) {
                    $target = (string)$r['Target'];
                    if (strpos($target, 'xl/') === false) $target = 'xl/' . $target;
                    $sheetFiles[] = $target;
                }
            }
        }

        if (empty($sheetFiles)) $sheetFiles = ['xl/worksheets/sheet1.xml'];

        foreach ($sheetFiles as $sf) {
            $raw = $zip->getFromName($sf);
            if ($raw) $this->sheets[] = $this->parseSheet($raw);
        }

        $zip->close();
        return !empty($this->sheets);
    }

    private function parseSheet($xml_string) {
        $xml = simplexml_load_string($xml_string);
        $rows = [];
        $maxCol = 0;

        foreach ($xml->sheetData->row as $row) {
            $rowArr = [];
            $rowIdx = (int)$row['r'] - 1;
            foreach ($row->c as $c) {
                $ref = (string)$c['r'];
                $col = $this->colIndex($ref);
                if ($col > $maxCol) $maxCol = $col;
                $type = (string)$c['t'];
                $val  = isset($c->v) ? (string)$c->v : '';
                if ($type === 's') {
                    $val = $this->sharedStrings[(int)$val] ?? '';
                } elseif ($type === 'inlineStr') {
                    $val = isset($c->is->t) ? (string)$c->is->t : '';
                }
                $rowArr[$col] = $val;
            }
            // Fill gaps
            $full = [];
            for ($i = 0; $i <= $maxCol; $i++) {
                $full[] = $rowArr[$i] ?? '';
            }
            $rows[$rowIdx] = $full;
        }
        ksort($rows);
        return array_values($rows);
    }

    private function colIndex($ref) {
        preg_match('/([A-Z]+)/', strtoupper($ref), $m);
        $col = 0;
        foreach (str_split($m[1]) as $ch) {
            $col = $col * 26 + (ord($ch) - 64);
        }
        return $col - 1;
    }

    public function rows($sheetIndex = 0) {
        return $this->sheets[$sheetIndex] ?? [];
    }
}
