<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use Dompdf\Dompdf;
use Dompdf\Options;

use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Writer\PngWriter;

use App\Models\CertificateModel;

class Certificates extends BaseController {

	protected array $data;
	
	// Untuk Sertifikat Instalasi [1]
	public function installationIndex() { // Index
		return view('certificate_installation_index');
	}
	public function getDataIndexInstallation() { // Untuk API Get Data
		// $actid = $this->request->getVar('actid'); Siapa Tahu Buat 
		
		$certificates = [
			[
				'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11914',
				'certname' => 'Jokoh Calibration Certificate',
				'productname' => 'Jokoh',
				'productnumber' => 'SN-2024-001',
				'issuedate' => '2024-01-15',
				'expirydate' => '2025-01-15',
				'vendor' => 'Summit Calibration Lab',
				'isval' => null
			],
			[
				'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
				'certname' => 'Electrical Safety Test',
				'productname' => 'GE Healthcare VIVID',
				'productnumber' => 'GE-VIV-Q992',
				'issuedate' => '2024-06-12',
				'expirydate' => '2026-03-01',
				'vendor' => 'Pramita Medika Service',
				'isval' => '2026-03-01'
			],
			[
				'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
				'certname' => 'Electrical Safety Test',
				'productname' => 'GE Healthcare VIVID',
				'productnumber' => 'GE-VIV-Q992',
				'issuedate' => '2024-06-12',
				'expirydate' => '2026-10-01',
				'vendor' => 'Pramita Medika Service',
				'isval' => '2026-09-01'
			],
			[
				'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
				'certname' => 'Electrical Safety Test',
				'productname' => 'GE Healthcare VIVID',
				'productnumber' => 'GE-VIV-Q992',
				'issuedate' => '2024-06-12',
				'expirydate' => '2026-01-01',
				'vendor' => 'Pramita Medika Service',
				'isval' => '2026-09-01'
			],
		];

		// If no actid, return all certificates
		if (empty($certificates)) {
			return $this->response->setJSON(null);
		}

		return $this->response->setJSON($certificates);
	}
	public function createinstallationPreview($certid = null) { // Untuk Preview Sertifikat
		//Melakukan search data dari database
		
		if (!$certid) {
			return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
		}

		// Get certificate data Berdasarkan certid
		$certificate = [
			'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11914',
			'certname' => 'Jokoh Calibration Certificate',
			'productname' => 'Jokoh',
			'productnumber' => 'SN-2024-001',
			'issuedate' => '2024-01-15',
			'expirydate' => '2025-01-15',
			'vendor' => 'Summit Calibration Lab',
			'isval' => null
		];

		if (empty($certificate)) { // JIka Tidak Ada
			return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
		}
		
		return $this->previewPdf($certificate, 'installation'); // Preview PDF
	}


	// Untuk Sertifikat Maintenance [2]
	public function maintenanceIndex() { // Index
		return view('certificate_maintenance_index');
	}
	public function getDataIndexMaintenance() {
		$userPosId = session()->get('userposid');
		$userId = session()->get('userid');

		$certificateModel = new CertificateModel();
		
		// 1. Mulai Query Builder
		$builder = $certificateModel->select('
										certificates.cert_id, 
										certificates.cert_number, 
										certificates.cert_name, 
										certificates.cert_type,
										certificates.actid, 
										certificates.issued_date, 
										certificates.expired_date, 
										certificates.status,
										certificates.user_validation_at, 
										certificates.spv_validation_at, 
										certificates.manager_validation_at,
										activities.subject as activity_subject, 
										CONCAT(users.firstname, " ", users.lastname) as fullname
									')
									->join('activities', 'activities.actid = certificates.actid', 'left')
									->join('users', 'users.userid = certificates.user_id', 'left');

		// 2. Filter berdasarkan Role
		if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua)
		} else if ($userPosId == 2) { // SPV: Melihat data user yang "reportto"-nya adalah ID supervisor ini
			$builder->where('users.reportto', $userId);
		} else if ($userPosId == 4) { // TSOIVD: Hanya melihat data milik sendiri
			$builder->where('certificates.user_id', $userId);
		} else {// Role lain: Tidak diberi akses
			return $this->response->setJSON([]);
		}

		// 3. Eksekusi Query
		$allData = $builder->findAll();

		if (empty($allData)) {
			return $this->response->setJSON([]); // Kembalikan array kosong agar frontend tidak error
		}

		return $this->response->setJSON($allData);
	}
	public function showDataMaintenance() { // Untuk API Get Data
		$certid = $this->request->getPost('certid');
		if (!$certid) {
			return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID Not Found']);
		}
		$certificateModel = new CertificateModel();
		$data = $certificateModel->select('
							certificates.cert_id, 
							certificates.cert_number, 
							certificates.cert_name, 
							certificates.status,
							activities.actid, 
							activities.subject,
							productcatalog.productname,
							sites.sitename,
							products.productnumber,
							CASE 
											WHEN certificates.cert_type = "MC" THEN "Maintenance"
											WHEN certificates.cert_type = "IC" THEN "Installation"
											WHEN certificates.cert_type = "UTC" THEN "User Training"
											WHEN certificates.cert_type = "BAI" THEN "Before After Inspection"
											WHEN certificates.cert_type = "BAP" THEN "Berita Acara Pengerjaan"
											ELSE certificates.cert_type 
							END AS certtype,
							CONCAT(us.firstname, " ", us.lastname) AS username,
							certificates.user_validation_at,
							CONCAT(spv.firstname, " ", spv.lastname) AS spvname,
							certificates.spv_validation_at,
							CONCAT(mgr.firstname, " ", mgr.lastname) AS managername,
							certificates.manager_validation_at,
							certificates.issued_date, 
							certificates.expired_date
						', false)
						->join('activities', 'activities.actid = certificates.actid', 'inner')
						->join('products', 'products.productid = activities.productid', 'inner')
						->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'inner')
						->join('sites', 'sites.siteid = activities.siteid', 'left')
						->join('users as us', 'us.userid = certificates.user_id', 'left')
						->join('users as spv', 'spv.userid = certificates.spv_id', 'left')
						->join('users as mgr', 'mgr.userid = certificates.manager_id', 'left')
						->join('userposition', 'userposition.userposid = us.userposid', 'left')
						->where('certificates.cert_id', $certid)
						->first();

		$data['issued_date'] = $data['issued_date'] ? date('d M Y', strtotime($data['issued_date'])) : null;
		$data['user_validation_at'] = $data['user_validation_at'] ? date('d M Y H:i', strtotime($data['user_validation_at'])) : null;
		$data['spv_validation_at'] = $data['spv_validation_at'] ? date('d M Y H:i', strtotime($data['spv_validation_at'])) : null;
		$data['manager_validation_at'] = $data['manager_validation_at'] ? date('d M Y H:i', strtotime($data['manager_validation_at'])) : null;

		if (empty($data)) { // Jika Tidak Ada
			return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
		}
		return $this->response->setJSON($data);
	}
	public function createMaintenancePreview($certid = null) { // Untuk Preview Sertifikat
	
		if (!$certid) {
			return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID Not Found']);
		}
		$certificateModel = new CertificateModel();
		$data = $certificateModel->select('
										certificates.cert_name,
										certificates.issued_date,
										certificates.expired_date,
										certificates.file_url,
										productcatalog.productname as productname,
										sites.sitename as sitename,
										products.productnumber,
										CASE 
											WHEN certificates.cert_type = "MC" THEN "Maintenance"
											WHEN certificates.cert_type = "IC" THEN "Installation"
											WHEN certificates.cert_type = "UTC" THEN "User Training"
											WHEN certificates.cert_type = "BAI" THEN "Before After Inspection"
											WHEN certificates.cert_type = "BAP" THEN "Berita Acara Pengerjaan"
											ELSE certificates.cert_type 
										END AS cert_type,
										CONCAT(users.firstname, " ", users.lastname) AS fullname,
										userposition.texts AS user_position,
										certificates.issued_date, 
										certificates.expired_date,
										certificates.cert_number -- Penting agar callback UUID tetap jalan
									', false)
									->join('users', 'users.userid = certificates.user_id', 'left')
									->join('userposition', 'userposition.userposid = users.userposid', 'left')
									->join('activities', 'activities.actid = certificates.actid', 'left')
									->join('sites', 'sites.siteid = activities.siteid', 'left')
									->join('products', 'products.productid = activities.productid', 'left')
									->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left')
									->where('certificates.cert_id', $certid) 
									->first();		
		$certificate = [
			'certname' => $data['cert_name'],
			'sitename' => $data['sitename'],
			'certtype' => $data['cert_type'], 
			'fullname' => $data['fullname'],
			'userposition' => $data['user_position'],
			'productname' => $data['productname'],
			'productnumber' => $data['productnumber'],
			'issueddate' => $data['issued_date'],
			'expireddate' => $data['expired_date']
		];

		$builder = new Builder(
			writer: new PngWriter(),
			data: $data['file_url'],
			size: 120,
			margin: 0
		);
		$result = $builder->build();
		$certificate['qrcode'] = $result->getDataUri();

		if (empty($certificate)) { // Jika Tidak Ada
			return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
		}
		
		return $this->previewPdf($certificate, 'maintenance'); // Preview PDF
	}
	

	// Untuk Sertifikat Training [3]
	public function trainingIndex() {
		return view('certificate_training_index');
	}
	public function getDataIndexTraining() {
		// $actid = $this->request->getVar('actid');
		
		// Sample data - replace with actual database query
		$certificates = [
			[
				'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
				'certname' => 'Jokoh Calibration Certificate',
				'productname' => 'Jokoh',
				'productnumber' => 'SN-2024-001',
				'issuedate' => '2024-01-15',
				'expirydate' => '2025-01-15',
				'vendor' => 'Summit Calibration Lab',
				'isval' => null
			],
			[
				'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
				'certname' => 'Electrical Safety Test',
				'productname' => 'GE Healthcare VIVID',
				'productnumber' => 'GE-VIV-Q992',
				'issuedate' => '2024-06-12',
				'expirydate' => '2026-10-01',
				'vendor' => 'Pramita Medika Service',
				'isval' => '2026-03-01'
			]
		];

		// If no actid, return all certificates
		if (empty($certificates)) {
			return $this->response->setJSON(null);
		}

		return $this->response->setJSON($certificates);
	}
	public function createTrainingPreview($certid = null) { // Untuk Preview Sertifikat
		//Melakukan search data dari database
		
		if (!$certid) {
			return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
		}

		// Get certificate data Berdasarkan certid
		$certificate = [
			'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
			'certname' => 'Jokoh Calibration Certificate',
			'productname' => 'Jokoh',
			'productnumber' => 'SN-2024-001',
			'issuedate' => '2024-01-15',
			'expirydate' => '2025-01-15',
			'vendor' => 'Summit Calibration Lab',
			'isval' => null
		];

		if (empty($certificate)) { // JIka Tidak Ada
			return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
		}
		
		return $this->previewPdf($certificate, 'training'); // Preview PDF
	}


	// Untuk Sertifikat Calibrate [4]
	public function calibrateIndex() {
		return view('certificate_calibrate_index');
	}
	public function getDataIndexCalibrate() {
		// $actid = $this->request->getVar('actid');
		
		// Sample data - replace with actual database query
		$certificates = [
			[
				'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
				'certname' => 'Jokoh Calibration Certificate',
				'productname' => 'Jokoh',
				'productnumber' => 'SN-2024-001',
				'issuedate' => '2024-01-15',
				'expirydate' => '2025-01-15',
				'vendor' => 'Summit Calibration Lab',
				'isval' => null
			],
			[
				'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
				'certname' => 'Electrical Safety Test',
				'productname' => 'GE Healthcare VIVID',
				'productnumber' => 'GE-VIV-Q992',
				'issuedate' => '2024-06-12',
				'expirydate' => '2026-10-01',
				'vendor' => 'Pramita Medika Service',
				'isval' => '2026-03-01'
			]
		];

		// If no actid, return all certificates
		if (empty($certificates)) {
			return $this->response->setJSON(null);
		}

		return $this->response->setJSON($certificates);
	}
	public function createCalibratePreview($certid = null) { // Untuk Preview Sertifikat
		//Melakukan search data dari database
		
		if (!$certid) {
			return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
		}

		// Get certificate data Berdasarkan certid
		$certificate = [
			'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
			'certname' => 'Jokoh Calibration Certificate',
			'productname' => 'Jokoh',
			'productnumber' => 'SN-2024-001',
			'issuedate' => '2024-01-15',
			'expirydate' => '2025-01-15',
			'vendor' => 'Summit Calibration Lab',
			'isval' => null
		];

		if (empty($certificate)) { // JIka Tidak Ada
			return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
		}
		
		return $this->previewPdf($certificate, 'calibrate', 'tms24i'); // Preview PDF
	}


	// Helper Function Preview dan Validate
	private function previewPdf($certificate, $type) { // Untuk Show/Preview PDF
		// Generate PDF
		$options = new Options();
		$options->set('isRemoteEnabled', true);
		$options->set('isHtml5ParserEnabled', true);
		// $options->set('defaultFont', 'Playfair Display');

		$dompdf = new Dompdf($options);

		// Format dates
		$certificate['issueddate'] = date('d-M-Y', strtotime($certificate['issueddate']));
		$certificate['expireddate'] = date('d-M-Y', strtotime($certificate['expireddate']));

		// Select template and orientation based on type
		$template = '';
		$orientation = 'portrait';

		switch($type) {
			case 'training':
				$template = 'certificates/certificate_training';
				$orientation = 'landscape';
				break;
			case 'calibration':
				if ($productType == 'tms50i') {
					$template = 'certificates/callibrations_template/certificate_tms50i_calibration';
				} else if ($productType == 'tms24i') {
					$template = 'certificates/callibrations_template/certificate_tms24i_calibration';
				} else if ($productType == 'tms30i') {
					$template = 'certificates/callibrations_template/certificate_tms30i_calibration';
				} else if ($productType == 'bs430') {
					$template = 'certificates/callibrations_template/certificate_bs430_calibration';
				} else if ($productType == 'cl900i') {
					$template = 'certificates/callibrations_template/certificate_cl900i_calibration';
				} else if ($productType == 'jokoh') {
					$template = 'certificates/callibrations_template/certificate_jokoh_calibration';
				} else if ($productType == 'bc760r') {
					$template = 'certificates/callibrations_template/certificate_bc760r_calibration';
				} else if ($productType == 'bc5140') {
					$template = 'certificates/callibrations_template/certificate_bc5140_calibration';
				} else {
					return $this->response->setStatusCode(404)->setJSON(['error' => 'Not Found']);
				}
				$orientation = 'portrait';
				break;
			case 'maintenance':
				$template = 'certificates/certificate_maintenance';
				$orientation = 'landscape';
				break;
			case 'installation':
				$template = 'certificates/certificate_installation';
				$orientation = 'landscape';
				break;
		}

		$html = view($template, [ 'certificate' => $certificate]);

		$dompdf->loadHtml($html);
		$dompdf->set_option('isRemoteEnabled', true);
		$dompdf->setPaper('A4', $orientation);
		$dompdf->render();

		// Output PDF
		$filename = $certificate['certname']. '.pdf';
		$dompdf->stream($filename, ['Attachment' => false]);
	}
	public function validateCertificate() {
		$certid = $this->request->getPost('certid');
		$certificateType = $this->request->getPost('certificateType'); 

		if (!$certid || !$certificateType) {
			return $this->response->setJSON(['success' => false, 'message' => 'Parameter tidak lengkap.']);
		}

		$userId = session()->get('userid');
		$userPosId = session()->get('userposid');
		$certificateModel = new CertificateModel();

		// 1. Ambil data dasar saja dulu untuk pengecekan awal
		$currentCert = $certificateModel->find($certid);

		if (!$currentCert) {
			return $this->response->setJSON(['success' => false, 'message' => 'Data tidak ditemukan.']);
		}

		$updateData = [];
		$currentTime = date('Y-m-d H:i:s');

		// 2. Filter Role & Cek Duplikasi
		switch ($userPosId) {
			case 1: // Manager
				if (!empty($currentCert['manager_validation_at'])) 
					return $this->response->setJSON(['success' => false, 'message' => 'Anda sudah Melakukan Validasi.']);
				$updateData = ['manager_id' => $userId, 'manager_validation_at' => $currentTime];
				break;
			case 2: // SPV
				if (!empty($currentCert['spv_validation_at'])) 
					return $this->response->setJSON(['success' => false, 'message' => 'Anda sudah Melakukan Validasi.']);
				$updateData = ['spv_id' => $userId, 'spv_validation_at' => $currentTime];
				break;
			case 4: // TSOIVD
				if ($currentCert['user_id'] != $userId) 
					return $this->response->setJSON(['success' => false, 'message' => 'Bukan pemilik sertifikat.']);
				if (!empty($currentCert['user_validation_at'])) 
					return $this->response->setJSON(['success' => false, 'message' => 'Anda sudah Melakukan Validasi.']);
				$updateData = ['user_validation_at' => $currentTime];
				break;
			default:
				return $this->response->setJSON(['success' => false, 'message' => 'Akses ditolak.'], 403);
		}

		// 3. Eksekusi Update Validasi Role
		if ($certificateModel->update($certid, $updateData)) {
			
			// 4. Cek apakah ini validasi terakhir? 
			// Ambil ulang data terbaru (cukup kolom validation saja untuk efisiensi)
			$checkFinal = $certificateModel->select('user_validation_at, spv_validation_at, manager_validation_at')
										->find($certid);

			if (!empty($checkFinal['user_validation_at']) && 
				(!empty($checkFinal['spv_validation_at']) || 
				!empty($checkFinal['manager_validation_at']))) {
				
				// Check
				$checkStatus = $certificateModel->select('status')->find($certid);
				if ($checkStatus['status'] == 'validated') {
					return $this->response->setJSON([
						'success' => true,
						'message' => 'Semua validasi telah dilakukan'
					]);
				}

				// Update Status Utama
				$certificateModel->update($certid, ['status' => 'validated']);

				// Baru jalankan query berat JOIN di sini untuk keperluan PDF/Notifikasi
				$latestData = $certificateModel->select('
													certificates.cert_name,
													certificates.issued_date,
													certificates.expired_date,
													certificates.status,
													productcatalog.productname as productname,
													sites.sitename as sitename,
													products.productnumber,
													CASE 
														WHEN certificates.cert_type = "MC" THEN "Maintenance"
														WHEN certificates.cert_type = "IC" THEN "Installation"
														WHEN certificates.cert_type = "UTC" THEN "Training"
														WHEN certificates.cert_type = "BAI" THEN "Before After Inspection"
														WHEN certificates.cert_type = "BAP" THEN "Berita Acara Pengerjaan"
														ELSE certificates.cert_type 
													END AS cert_type,
													CONCAT(users.firstname, " ", users.lastname) AS fullname,
													userposition.texts AS user_position,
													certificates.issued_date, 
													certificates.expired_date,
													certificates.cert_number -- Penting agar callback UUID tetap jalan
												', false)
												->join('users', 'users.userid = certificates.user_id', 'left')
												->join('userposition', 'userposition.userposid = users.userposid', 'left')
												->join('activities', 'activities.actid = certificates.actid', 'left')
												->join('sites', 'sites.siteid = activities.siteid', 'left')
												->join('products', 'products.productid = activities.productid', 'left')
												->join('productcatalog', 'productcatalog.catalogid = products.catalogid', 'left')
												->where('certificates.cert_id', $certid) 
												->first();
				
				$certificate = [
					'status' => $latestData['status'],
					'certname' => $latestData['cert_name'],
					'sitename' => $latestData['sitename'],
					'certtype' => $latestData['cert_type'], 
					'fullname' => $latestData['fullname'],
					'userposition' => $latestData['user_position'],
					'productname' => $latestData['productname'],
					'productnumber' => $latestData['productnumber'],
					'issueddate' => date('d-M-Y', strtotime($latestData['issued_date'])),
					'expireddate' => date('d-M-Y', strtotime($latestData['expired_date'])),
					'exportToPDF' => true
				];
				
				try {
					
					$pdfAfterValidation = $this->savePdf($certificate, $latestData['cert_type'], $latestData['cert_number']); // Simpan ke PDF
					
					$certificateModel->update($certid, [ // Update ke tabel certificates
						'file_location' => $pdfAfterValidation['file_relative'],
						'metadata_title' => $pdfAfterValidation['metadata_title'],
						'metadata_keywords' => $pdfAfterValidation['metadata_keywords'].";".base_url('certificates/number/'.$latestData['cert_number']),
						// 'file_url' => base_url('certificates/number/'.$latestData['cert_number'])
					]);

					return $this->response->setJSON([
						'success' => true,
						'message' => 'Semua validasi telah dilakukan, PDF sudah di generate'
					]);

				} catch (\Throwable $e) {

					return $this->response->setStatusCode(500)->setJSON([
						'success' => false,
						'message' => $e->getMessage()
					]);
				}

			}
			return $this->response->setJSON([
				'success' => true,
				'message' => "Sertifikat {$certificateType} berhasil divalidasi."
			]);
		}

		return $this->response->setJSON(['success' => false, 'message' => 'Gagal memperbarui data.']);
	}
	public function savePdf($certificate, $certificateType, $cert_number, $productType = null) {
		$certificateType = strtolower($certificateType);

		switch ($certificateType) {
			case 'training':
				$template = 'certificates/certificate_training';
				$orientation = 'landscape';
				$subDir = 'training';
				break;

			case 'calibration':
				$orientation = 'portrait';
				$subDir = 'calibration';

				switch ($productType) {
					case 'tms50i':
						$template = 'certificates/callibrations_template/certificate_tms50i_calibration';
						break;
					case 'tms24i':
						$template = 'certificates/callibrations_template/certificate_tms24i_calibration';
						break;
					case 'tms30i':
						$template = 'certificates/callibrations_template/certificate_tms30i_calibration';
						break;
					case 'bs430':
						$template = 'certificates/callibrations_template/certificate_bs430_calibration';
						break;
					case 'cl900i':
						$template = 'certificates/callibrations_template/certificate_cl900i_calibration';
						break;
					case 'jokoh':
						$template = 'certificates/callibrations_template/certificate_jokoh_calibration';
						break;
					case 'bc760r':
						$template = 'certificates/callibrations_template/certificate_bc760r_calibration';
						break;
					case 'bc5140':
						$template = 'certificates/callibrations_template/certificate_bc5140_calibration';
						break;
					default:
						throw new \Exception('Product type calibration tidak valid');
				}
				break;

			case 'maintenance':
				$template = 'certificates/certificate_maintenance';
				$orientation = 'landscape';
				$subDir = 'maintenance';
				break;

			case 'installation':
				$template = 'certificates/certificate_installation';
				$orientation = 'landscape';
				$subDir = 'installation';
				break;

			default:
				throw new \Exception('Certificate type tidak valid');
		}

		if (empty($template)) {
			throw new \Exception('Template tidak ditemukan');
		}

		// Dompdf
		$options = new Options();
		$options->set('isRemoteEnabled', true);
		$options->set('isHtml5ParserEnabled', true);

		$dompdf = new Dompdf($options);
		$html = view($template, ['certificate' => $certificate]);

		$dompdf->loadHtml($html);
		$dompdf->setPaper('A4', $orientation);
		$dompdf->render();

		// Metadata
		$dompdf->addInfo('Title', $certificate['certname']);
		$dompdf->addInfo('Keywords', $certificate['certtype'] . ' Certificate;'.base_url('certificates/number/'.$cert_number));

		// Folder
		$uploadDir = FCPATH . 'upload/documents/' . $subDir;

		if (!is_dir($uploadDir)) {
			mkdir($uploadDir, 0755, true);
		}

		// Safe filename
		$cleanName = preg_replace('/[^A-Za-z0-9_\-]/', '_', $certificate['certname']);
		$timestamp = date('YmdHis');
		$filename = $cleanName . '_' . $timestamp . '.pdf';

		$filePath = $uploadDir . DIRECTORY_SEPARATOR . $filename;

		if (!file_put_contents($filePath, $dompdf->output())) {
			throw new \Exception('Gagal menyimpan file PDF');
		}

		return [
			'file_name' => $filename,
			'file_path' => $filePath,
			'file_relative' => 'upload/documents/' . $subDir . '/' . $filename,
			'metadata_title' => $certificate['certname'],
			'metadata_keywords' => $certificate['certtype'] . ' Certificate'
		];
	}
	public function view($uuid) {
		try {
			$certificateModel = new CertificateModel();

			// Ambil dari model (UUID → binary otomatis)
			$certificate = $certificateModel->getByUuid($uuid);

			if (!$certificate) {
				throw new \Exception('Certificate tidak ditemukan');
			}

			if (empty($certificate['file_location'])) {
				throw new \Exception('File PDF belum tersedia');
			}

			$filePath = FCPATH . $certificate['file_location'];

			if (!file_exists($filePath)) {
				throw new \Exception('File tidak ditemukan di server');
			}

			return $this->response
				->setHeader('Content-Type', 'application/pdf')
				->setHeader(
					'Content-Disposition',
					'inline; filename="' . basename($filePath) . '"'
				)
				->setBody(file_get_contents($filePath));

		} catch (\Throwable $e) {
			return $this->response->setStatusCode(404)->setJSON([
				// 'success' => false,
				'message' => "404 Not Found"
			]);
		}
	}
}