<?php

if (!defined('ABSPATH')) {
    exit;
}

class AIEO_DMM_Sample {

    
    public static function create_csv($slug, array $headers, array $rows) {
        $dir = AIEO_DMM::get_upload_path('samples');
        $filename = sanitize_file_name($slug . '-sample.csv');
        $path = trailingslashit($dir['path']) . $filename;
        $url  = trailingslashit($dir['url']) . $filename;

        $h = fopen($path, 'w');
        if (!$h) {
            return array('path' => '', 'url' => '', 'filename' => $filename);
        }
        
        fwrite($h, "\xEF\xBB\xBF");
        fputcsv($h, $headers);
        foreach ($rows as $row) {
            fputcsv($h, $row);
        }
        fclose($h);

        return array('path' => $path, 'url' => $url, 'filename' => $filename);
    }

    
    public static function write_csv_bom($handle) {
        if (is_resource($handle)) {
            fwrite($handle, "\xEF\xBB\xBF");
        }
    }

    
    public static function create_xlsx($slug, array $headers, array $rows) {
        $dir = AIEO_DMM::get_upload_path('samples');
        $filename = sanitize_file_name($slug . '-sample.xlsx');
        $path = trailingslashit($dir['path']) . $filename;
        $url  = trailingslashit($dir['url']) . $filename;

        if (!class_exists('ZipArchive')) {
            return array('path' => '', 'url' => '', 'filename' => $filename);
        }
        $zip = new ZipArchive();
        if (@$zip->open($path, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
            return array('path' => '', 'url' => '', 'filename' => $filename);
        }

        
        $zip->addFromString('[Content_Types].xml',
            '<?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"/>' .
            '</Types>'
        );

        
        $zip->addFromString('_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>'
        );

        
        $zip->addFromString('xl/workbook.xml',
            '<?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="Sample" sheetId="1" r:id="rId1"/></sheets>' .
            '</workbook>'
        );

        
        $zip->addFromString('xl/_rels/workbook.xml.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/worksheet" Target="worksheets/sheet1.xml"/>' .
            '</Relationships>'
        );

        
        $all_rows = array_merge(array($headers), $rows);
        $xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
             . '<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">'
             . '<sheetData>';
        foreach ($all_rows as $ri => $row) {
            $r_num = $ri + 1;
            $xml  .= '<row r="' . $r_num . '">';
            foreach (array_values($row) as $ci => $cell) {
                $col_ref = self::column_ref($ci) . $r_num;
                $val = self::xml_escape((string) $cell);
                
                if (is_numeric($cell)) {
                    $xml .= '<c r="' . $col_ref . '"><v>' . $val . '</v></c>';
                } else {
                    $xml .= '<c r="' . $col_ref . '" t="inlineStr"><is><t>' . $val . '</t></is></c>';
                }
            }
            $xml .= '</row>';
        }
        $xml .= '</sheetData></worksheet>';
        $zip->addFromString('xl/worksheets/sheet1.xml', $xml);

        $zip->close();

        return array('path' => $path, 'url' => $url, 'filename' => $filename);
    }

    
    public static function csv_to_xlsx($csv_path, $xlsx_path) {
        if (!class_exists('ZipArchive') || !file_exists($csv_path)) {
            return false;
        }

        $tmp_sheet = wp_tempnam('aieo-dmm-sheet');
        if (!$tmp_sheet) {
            return false;
        }

        $sheet_handle = fopen($tmp_sheet, 'w');
        $csv_handle   = fopen($csv_path, 'r');
        if (!$sheet_handle || !$csv_handle) {
            if ($sheet_handle) { fclose($sheet_handle); }
            if ($csv_handle) { fclose($csv_handle); }
            @unlink($tmp_sheet);
            return false;
        }

        fwrite($sheet_handle,
            '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' .
            '<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">' .
            '<sheetData>'
        );

        
        $peek = fread($csv_handle, 3);
        if ($peek !== "\xEF\xBB\xBF") {
            rewind($csv_handle);
        }

        $row_num = 0;
        while (($row = fgetcsv($csv_handle)) !== false) {
            if ($row === null || (count($row) === 1 && $row[0] === null)) {
                continue;
            }
            $row_num++;
            fwrite($sheet_handle, '<row r="' . $row_num . '">');
            foreach (array_values($row) as $ci => $cell) {
                $col_ref = self::column_ref($ci) . $row_num;
                $escaped = self::xml_escape((string) $cell);
                if ($cell !== '' && is_numeric($cell)) {
                    fwrite($sheet_handle, '<c r="' . $col_ref . '"><v>' . $escaped . '</v></c>');
                } else {
                    fwrite($sheet_handle, '<c r="' . $col_ref . '" t="inlineStr"><is><t>' . $escaped . '</t></is></c>');
                }
            }
            fwrite($sheet_handle, '</row>');
        }
        fclose($csv_handle);
        fwrite($sheet_handle, '</sheetData></worksheet>');
        fclose($sheet_handle);

        $zip = new ZipArchive();
        if (@$zip->open($xlsx_path, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
            @unlink($tmp_sheet);
            return false;
        }

        $zip->addFromString('[Content_Types].xml',
            '<?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"/>' .
            '</Types>'
        );
        $zip->addFromString('_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>'
        );
        $zip->addFromString('xl/workbook.xml',
            '<?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="Export" sheetId="1" r:id="rId1"/></sheets>' .
            '</workbook>'
        );
        $zip->addFromString('xl/_rels/workbook.xml.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/worksheet" Target="worksheets/sheet1.xml"/>' .
            '</Relationships>'
        );
        
        $zip->addFile($tmp_sheet, 'xl/worksheets/sheet1.xml');
        $zip->close();

        @unlink($tmp_sheet);
        return true;
    }

    
    private static function column_ref($index) {
        $index = (int) $index;
        if ($index < 26) {
            return chr(65 + $index);
        }
        
        $first  = intdiv($index, 26) - 1;
        $second = $index % 26;
        return chr(65 + $first) . chr(65 + $second);
    }

    private static function xml_escape($s) {
        return htmlspecialchars($s, ENT_QUOTES | ENT_XML1, 'UTF-8');
    }
}
