<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class PdfMergerLib {
    
    /**
     * Check if Ghostscript is available
     */
    private function _ghostscriptAvailable()
    {
        // Check for Windows
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
            $gsPath = 'C:\\Program Files\\gs\\gs10.02.1\\bin\\gswin64c.exe';
            if (file_exists($gsPath)) {
                return $gsPath;
            }
            // Try common paths
            $paths = glob('C:\\Program Files\\gs\\*\\bin\\gswin64c.exe');
            if (!empty($paths)) {
                return $paths[0];
            }
            // Try 32-bit
            $paths = glob('C:\\Program Files (x86)\\gs\\*\\bin\\gswin32c.exe');
            if (!empty($paths)) {
                return $paths[0];
            }
            // Try PATH
            exec('where gswin64c 2>&1', $output, $returnCode);
            if ($returnCode === 0 && !empty($output[0])) {
                return trim($output[0]);
            }
            exec('where gswin32c 2>&1', $output, $returnCode);
            if ($returnCode === 0 && !empty($output[0])) {
                return trim($output[0]);
            }
        } else {
            // Linux/Mac
            exec('which gs 2>&1', $output, $returnCode);
            if ($returnCode === 0 && !empty($output[0])) {
                return trim($output[0]);
            }
        }
        return false;
    }
    
    /**
     * Merge PDFs using Ghostscript
     */
    private function _mergeWithGhostscript(array $files, string $outputPath)
    {
        $gsPath = $this->_ghostscriptAvailable();
        if (!$gsPath) {
            log_message('debug', 'Ghostscript not found');
            return false;
        }
        
        log_message('debug', 'Using Ghostscript: ' . $gsPath);
        
        // Build command
        $inputFiles = '';
        foreach ($files as $file) {
            $inputFiles .= ' "' . str_replace('/', '\\', $file) . '"';
        }
        
        $outputPath = str_replace('/', '\\', $outputPath);
        
        $cmd = '"' . $gsPath . '" -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile="' . $outputPath . '"' . $inputFiles . ' 2>&1';
        
        log_message('debug', 'Ghostscript command: ' . $cmd);
        
        exec($cmd, $output, $returnCode);
        
        if ($returnCode !== 0) {
            log_message('error', 'Ghostscript error: ' . implode("\n", $output));
            return false;
        }
        
        return file_exists($outputPath) && filesize($outputPath) > 0;
    }
    
    /**
     * Merge PDFs using PDFMerger library (fallback)
     */
    private function _mergeWithPDFMerger(array $files, string $outputPath)
    {
        try {
            $pdfMergerPath = APPPATH . 'third_party/PDFMerger/';
            set_include_path(get_include_path() . PATH_SEPARATOR . $pdfMergerPath);
            require_once $pdfMergerPath . 'PDFMerger.php';
            
            $pdfMerger = new \PDFMerger\PDFMerger();
            
            foreach ($files as $file) {
                if (file_exists($file)) {
                    $pdfMerger->addPDF($file, 'all');
                }
            }
            
            $pdfMerger->merge('file', $outputPath);
            return file_exists($outputPath) && filesize($outputPath) > 0;
        } catch (Exception $e) {
            log_message('error', 'PDFMerger error: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Merge multiple PDFs into one
     * @param array $files List of PDF file paths
     * @param string $outputPath Full path to output merged PDF
     * @return bool Success or failure
     */
    public function merge(array $files, string $outputPath)
    {
        if (empty($files)) {
            return false;
        }
        
        // Filter to only existing PDF files
        $validFiles = [];
        foreach ($files as $file) {
            if (file_exists($file) && strtolower(pathinfo($file, PATHINFO_EXTENSION)) === 'pdf') {
                $validFiles[] = $file;
            } else {
                log_message('error', 'Invalid or missing PDF file: ' . $file);
            }
        }
        
        if (empty($validFiles)) {
            log_message('error', 'No valid PDF files to merge');
            return false;
        }
        
        log_message('debug', 'Merging ' . count($validFiles) . ' PDF files');
        
        // Try Ghostscript first (more reliable)
        if ($this->_mergeWithGhostscript($validFiles, $outputPath)) {
            log_message('debug', 'PDF merge successful with Ghostscript');
            return true;
        }
        
        // Fallback to PDFMerger library
        log_message('debug', 'Trying PDFMerger library as fallback');
        if ($this->_mergeWithPDFMerger($validFiles, $outputPath)) {
            log_message('debug', 'PDF merge successful with PDFMerger');
            return true;
        }
        
        log_message('error', 'All PDF merge methods failed');
        return false;
    }
}
