<?php
namespace App\Controllers;

use App\Controllers\BaseController;

class ReportController extends BaseController
{
    protected $db;
    protected $reportHelper;
    
    public function __construct()
    {
        $this->db = \Config\Database::connect();
        $this->reportHelper = new \App\Libraries\ReportHelper($this->db);
        helper(['url', 'text']);
    }
    
    public function generate($accessnumber, $eng = 0, $ispdf = 0)
    {
        if ($ispdf == 0) {
            $ispdf = $this->request->getVar('ispdf') ?? 0;
        }

        $engQuery = $this->request->getVar('eng');
        if ($engQuery !== null) {
            $eng = (int) $engQuery;
        } elseif ($eng == 0) {
            $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
            $row = $this->db->query($sql, [$accessnumber])->getRowArray();
            $eng = $row['REPORT_LANG'] ?? 0;
        }

        return $this->renderReport($accessnumber, $eng, $ispdf, false);
    }
    
    public function print($accessnumber, $eng = 0, $ispdf = 0)
    {
        if ($ispdf == 0) {
            $ispdf = $this->request->getVar('ispdf') ?? 0;
        }

        $engQuery = $this->request->getVar('eng');
        if ($engQuery !== null) {
            $eng = (int) $engQuery;
        } elseif ($eng == 0) {
            $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
            $row = $this->db->query($sql, [$accessnumber])->getRowArray();
            $eng = $row['REPORT_LANG'] ?? 0;
        }

        return $this->renderReport($accessnumber, $eng, $ispdf, true);
    }
    
    private function renderReport($accessnumber, $eng, $ispdf, $shouldLog)
    {
        $userroleid = session()->get('userroleid');
        if (!in_array($userroleid, [0, 1, 2, 4])) {
            return $this->response->setStatusCode(403)->setJSON(['message' => 'Unauthorized']);
        }
        
        $data = $this->reportHelper->getReportData($accessnumber, $eng);
        $data['eng'] = $eng;
        $data['accessnumber'] = $accessnumber;
        $data['ispdf'] = $ispdf;
        
        if ($shouldLog == true) {
            $this->logPrintAudit($accessnumber, $data['status']);
        }
        
        return view('report/template', $data);
    }
    
    private function logPrintAudit($accessnumber, $status)
    {
        $sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_REQUESTS(ACCESSNUMBER, STEPDATE, STEPTYPE, STEPSTATUS)
                VALUES(?, GETDATE(), 'PRINT', ?)";
        $this->db->query($sql, [$accessnumber, $status]);
    }
    
    public function preview($accessnumber)
    {
        $eng = $this->request->getVar('eng') ?? 0;
        
        // If eng not provided, read REPORT_LANG from CM_REQUESTS
        if ($eng == 0) {
            $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
            $row = $this->db->query($sql, [$accessnumber])->getRowArray();
            $eng = $row['REPORT_LANG'] ?? 0;
        }
        
        return $this->renderReport($accessnumber, $eng, 0, false);
    }
    
    public function generatePdf($accessnumber)
    {
        // Bypass auth for localhost/127.0.0.1
        $ip = $this->request->getIPAddress();
        $isLocalhost = in_array($ip, ['127.0.0.1', '::1']);
        
        if (!$isLocalhost) {
            $userroleid = session()->get('userroleid');
            if (!in_array($userroleid, [0, 1, 2, 4])) {
                return $this->response->setStatusCode(403)->setJSON(['success' => false, 'error' => 'Unauthorized']);
            }
        }
        
        // Get language: URL parameter > REPORT_LANG > default (0)
        $engParam = $this->request->getVar('eng') ?? null;
        if ($engParam !== null) {
            $eng = (int) $engParam;
        } else {
            // Read REPORT_LANG from CM_REQUESTS
            $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
            $row = $this->db->query($sql, [$accessnumber])->getRowArray();
            $eng = (int) ($row['REPORT_LANG'] ?? 0);
        }
        
        $data = $this->reportHelper->getReportData($accessnumber, $eng);
        $data['eng'] = $eng;
        $data['accessnumber'] = $accessnumber;
        $data['ispdf'] = 1;
        
        $html = view('report/template', $data);
        $filename = $accessnumber . ($eng == 1 ? '_eng' : '') . '.pdf';
        $collectionDate = $data['collectionDate'] ?? '';
        $hostnumber = $data['hostnumber'] ?? '';
        
try {
            $jobId = $this->postToSpooler($html, $filename, $collectionDate, $accessnumber, $hostnumber);
            
            $sqlCheck = "SELECT COUNT(*) as cnt FROM GDC_CMOD.dbo.AUDIT_REQUESTS 
                         WHERE ACCESSNUMBER = ? AND STEPTYPE IN ('GEN_PDF', 'REGEN_PDF')";
            $result = $this->db->query($sqlCheck, [$accessnumber])->getRowArray();
            
            $stepType = ($result['cnt'] > 0) ? 'REGEN_PDF' : 'GEN_PDF';
            $stepStatus = $eng == 1 ? 'English' : 'Indonesian';
            
            $sqlLog = "INSERT INTO GDC_CMOD.dbo.AUDIT_REQUESTS(ACCESSNUMBER, STEPDATE, STEPTYPE, STEPSTATUS)
                       VALUES (?, GETDATE(), ?, ?)";
            $this->db->query($sqlLog, [$accessnumber, $stepType, $stepStatus]);

            try {
                $oruDir = 'c:\inetpub\wwwroot\spooler_db\process_oru';
                if (!is_dir($oruDir)) {
                    mkdir($oruDir, 0777, true);
                }

                $oruFile = "$oruDir/$accessnumber.oru";
                $date = date('Y-m-d H:i');
                $status = $data['status'] ?? 'PENDING';
                $file = fopen($oruFile, 'w+');
                fwrite($file, "$accessnumber\r\n$hostnumber\r\n$date\r\n$status\r\n-");
                fclose($file);

                $sqlOruLog = "INSERT INTO GDC_CMOD.dbo.AUDIT_REQUESTS(ACCESSNUMBER, STEPDATE, STEPTYPE, STEPSTATUS)
                              VALUES (?, GETDATE(), 'ORU_FILE', 'Created')";
                $this->db->query($sqlOruLog, [$accessnumber]);
            } catch (\Throwable $e) {
                log_message('error', "ORU file creation failed for $accessnumber: " . $e->getMessage());
            }

            return $this->response->setJSON([
                'success' => true,
                'jobId' => $jobId,
                'message' => 'PDF queued for generation',
                'status' => 'queued',
                'lang' => $eng == 1 ? 'English' : 'Indonesian',
                'isRegen' => ($stepType === 'REGEN_PDF')
            ]);
        } catch (\Exception $e) {
            log_message('error', "PDF generation failed: " . $e->getMessage());
            return $this->response->setStatusCode(500)->setJSON([
                'success' => false,
                'error' => 'Failed to queue PDF generation'
            ]);
        }
    }
    
    public function checkPdfStatus($jobId)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "http://glenlis:3000/api/pdf/status/$jobId");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode !== 200) {
            log_message('error', "Spooler status check returned HTTP $httpCode");
            return $this->response->setStatusCode(500)->setJSON([
                'success' => false,
                'error' => 'Failed to check job status'
            ]);
        }
        
        return $this->response->setJSON($response);
    }
    
    private function postToSpooler($html, $filename, $collectionDate = '', $accessnumber = '', $hostnumber = '')
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'http://glenlis:3000/api/pdf/generate');
        curl_setopt($ch, CURLOPT_POST, 1);
        
        $payload = [
            'html' => $html,
            'filename' => $filename
        ];
        
        if ($collectionDate) {
            $payload['collectionDate'] = $collectionDate;
        }
        
        if ($accessnumber) {
            $payload['accessnumber'] = $accessnumber;
        }
        
        if ($hostnumber) {
            $payload['hostnumber'] = $hostnumber;
        }
        
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode !== 200) {
            log_message('error', "Spooler API returned HTTP $httpCode");
            throw new \Exception('Failed to queue PDF generation');
        }
        
        $data = json_decode($response, true);
        return $data['jobId'];
    }
    
    /**
     * Generate PDF without authentication check
     * Used by batch processing script (internal use only)
     */
    public function generatePdfNoAuth($accessnumber)
    {
        // Get language: URL parameter > REPORT_LANG > default (0)
        $engParam = $this->request->getVar('eng') ?? null;
        if ($engParam !== null) {
            $eng = (int) $engParam;
        } else {
            // Read REPORT_LANG from CM_REQUESTS
            $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
            $row = $this->db->query($sql, [$accessnumber])->getRowArray();
            $eng = (int) ($row['REPORT_LANG'] ?? 0);
        }
        
        $data = $this->reportHelper->getReportData($accessnumber, $eng);
        $data['eng'] = $eng;
        $data['accessnumber'] = $accessnumber;
        $data['ispdf'] = 1;
        
        $html = view('report/template', $data);
        $filename = $accessnumber . ($eng == 1 ? '_eng' : '') . '.pdf';
        $collectionDate = $data['collectionDate'] ?? '';
        $hostnumber = $data['hostnumber'] ?? '';
        
        try {
            $jobId = $this->postToSpooler($html, $filename, $collectionDate, $accessnumber, $hostnumber);
            
            $sqlCheck = "SELECT COUNT(*) as cnt FROM GDC_CMOD.dbo.AUDIT_REQUESTS 
                         WHERE ACCESSNUMBER = ? AND STEPTYPE IN ('GEN_PDF', 'REGEN_PDF')";
            $result = $this->db->query($sqlCheck, [$accessnumber])->getRowArray();
            
            $stepType = ($result['cnt'] > 0) ? 'REGEN_PDF' : 'GEN_PDF';
            $stepStatus = $eng == 1 ? 'English' : 'Indonesian';
            
            $sqlLog = "INSERT INTO GDC_CMOD.dbo.AUDIT_REQUESTS(ACCESSNUMBER, STEPDATE, STEPTYPE, STEPSTATUS)
                       VALUES (?, GETDATE(), ?, ?)";
            $this->db->query($sqlLog, [$accessnumber, $stepType, $stepStatus]);

            try {
                $oruDir = 'c:\inetpub\wwwroot\spooler_db\process_oru';
                if (!is_dir($oruDir)) {
                    mkdir($oruDir, 0777, true);
                }

                $oruFile = "$oruDir/$accessnumber.oru";
                $date = date('Y-m-d H:i');
                $status = $data['status'] ?? 'PENDING';
                $file = fopen($oruFile, 'w+');
                fwrite($file, "$accessnumber\r\n$hostnumber\r\n$date\r\n$status\r\n-");
                fclose($file);

                $sqlOruLog = "INSERT INTO GDC_CMOD.dbo.AUDIT_REQUESTS(ACCESSNUMBER, STEPDATE, STEPTYPE, STEPSTATUS)
                              VALUES (?, GETDATE(), 'ORU_FILE', 'Created')";
                $this->db->query($sqlOruLog, [$accessnumber]);
            } catch (\Throwable $e) {
                log_message('error', "ORU file creation failed for $accessnumber: " . $e->getMessage());
            }

            return $this->response->setJSON([
                'success' => true,
                'jobId' => $jobId,
                'message' => 'PDF queued for generation',
                'status' => 'queued',
                'lang' => $eng == 1 ? 'English' : 'Indonesian',
                'isRegen' => ($stepType === 'REGEN_PDF')
            ]);
        } catch (\Exception $e) {
            log_message('error', "PDF generation failed: " . $e->getMessage());
            return $this->response->setStatusCode(500)->setJSON([
                'success' => false,
                'error' => 'Failed to queue PDF generation'
            ]);
        }
    }
}
