<?php

namespace App\Libraries;

use App\Models\ParticipantModel;
// --- PERUBAHAN PADA 'USE' STATEMENTS ---
use Endroid\QrCode\QrCode; // Menggantikan Builder
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\Writer\PngWriter;

/**
 * Service class untuk menangani logika terkait tiket,
 * seperti pembuatan QR code (string dan gambar).
 */
class TicketService
{
    protected ParticipantModel $participantModel;
    protected string $qrCodePath;

    public function __construct()
    {
        $this->participantModel = new ParticipantModel();
        $this->qrCodePath = WRITEPATH . 'qrcodes' . DIRECTORY_SEPARATOR;

        if (!is_dir($this->qrCodePath)) {
            mkdir($this->qrCodePath, 0775, true);
        }
    }

    /**
     * Generate dan simpan QR Code untuk semua peserta dalam sebuah transaksi.
     * (Tidak ada perubahan pada logika metode ini)
     */
    public function generateQrForTransaction(int $transactionId): bool
    {
        try {
            $participants = $this->participantModel
                ->where('transaction_id', $transactionId)
                ->findAll();

            if (empty($participants)) {
                return true; 
            }
            
            foreach ($participants as $p) {
                if (!empty($p->qr_number)) {
                    $this->deleteOldQrImage($p->qr_number);
                }
                
                $qrString = $this->createUniqueQrString($p->id);
                $qrImagePath = $this->createQrImage($qrString, $p->id);
                
                $dataToUpdate = [
                    'qr_number'     => $qrString,
                    'qr_image_path' => $qrImagePath
                ];

                // Lakukan update dan periksa hasilnya secara eksplisit
                if ($this->participantModel->update($p->id, $dataToUpdate) === false) {
                    // Jika update gagal, catat error spesifik dari model
                    $errors = $this->participantModel->errors();
                    log_message('error', "[TicketService] FAILED to update participant ID: {$p->id}. Model Errors: " . json_encode($errors));
                    $allUpdatesSucceeded = false;
                } else {
                    log_message('info', "[TicketService] Successfully updated participant ID: {$p->id} with QR data.");
                }
            }

        } catch (\Exception $e) {
            log_message('error', '[TicketService] Failed to generate QR for transaction ' . $transactionId . ': ' . $e->getMessage());
            return false;
        }
        
        return true;
    }

    /**
     * Membuat file gambar QR code fisik.
     * --- METODE INI DISESUAIKAN DENGAN LIBRARY BARU ---
     */
    private function createQrImage(string $qrString, int $participantId): string
    {
        $fileName = "{$participantId}_{$qrString}_" . time() . '.png';
        $fullPath = $this->qrCodePath . $fileName;

        // Cara baru yang lebih bersih untuk membuat QR Code
        $qrCode = QrCode::create($qrString)
            ->setEncoding(new Encoding('UTF-8'))
            ->setSize(300)
            ->setMargin(10);
        
        $writer = new PngWriter();
        $result = $writer->write($qrCode);
        
        // Simpan file ke disk
        $result->saveToFile($fullPath);

        return $fileName;
    }

    /**
     * Menghapus file gambar QR code lama jika ada.
     * (Tidak ada perubahan pada logika metode ini)
     */
    private function deleteOldQrImage(string $oldQrNumber)
    {
        $matchingFiles = glob($this->qrCodePath . "*_{$oldQrNumber}_*.png");
        
        if ($matchingFiles) {
            foreach ($matchingFiles as $file) {
                if (file_exists($file)) {
                    unlink($file);
                }
            }
        }
    }
    
    /**
     * Membuat sebuah string QR yang unik.
     * (Tidak ada perubahan pada logika metode ini)
     */
    private function createUniqueQrString(int $participantId): string
    {
        return strtoupper(
            bin2hex(random_bytes(2)) . 
            substr(str_pad($participantId, 4, '0', STR_PAD_LEFT), 0, 4) . 
            bin2hex(random_bytes(2))
        );
    }
}