<?php

namespace App\Controllers;

use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

abstract class BaseController extends Controller
{
    protected $helpers = ['url', 'form', 'text'];

    public function initController(
        RequestInterface $request,
        ResponseInterface $response,
        LoggerInterface $logger
    ): void {
        parent::initController($request, $response, $logger);
    }

    /**
     * Shared upload handler for PDF files.
     * Returns the UUID filename stored, or throws on failure.
     */
    protected function uploadPdf(string $field = 'file'): string
    {
        $file = $this->request->getFile($field);

        if (! $file || ! $file->isValid()) {
            throw new \RuntimeException('File tidak valid atau tidak ada.');
        }

        // Size: 50 MB
        if ($file->getSize() > 50 * 1024 * 1024) {
            throw new \RuntimeException('Ukuran file melebihi batas 50 MB.');
        }

        // Extension whitelist
        if (strtolower($file->getClientExtension()) !== 'pdf') {
            throw new \RuntimeException('Hanya file PDF yang diizinkan.');
        }

        // MIME from client headers
        if ($file->getClientMimeType() !== 'application/pdf') {
            throw new \RuntimeException('Tipe file tidak valid.');
        }

        // finfo magic bytes — actual file content check
        $finfo    = new \finfo(FILEINFO_MIME_TYPE);
        $realMime = $finfo->file($file->getTempName());
        if ($realMime !== 'application/pdf') {
            throw new \RuntimeException('Konten file tidak sesuai format PDF.');
        }

        // Scan first 1024 bytes for PHP code
        $head = file_get_contents($file->getTempName(), false, null, 0, 1024);
        if (preg_match('/<\?php|<\?=/i', $head)) {
            throw new \RuntimeException('File mengandung konten yang tidak diizinkan.');
        }

        $storedName = bin2hex(random_bytes(16)) . '.pdf';
        $dest       = ROOTPATH . 'storage/pdf/';

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

        $file->move($dest, $storedName);
        return $storedName;
    }

    /**
     * Shared upload handler for cover images.
     * Returns the UUID filename stored, or throws on failure.
     */
    protected function uploadCover(string $field = 'cover_img'): string
    {
        $file = $this->request->getFile($field);

        if (! $file || ! $file->isValid()) {
            throw new \RuntimeException('File cover tidak valid.');
        }

        if ($file->getSize() > 2 * 1024 * 1024) {
            throw new \RuntimeException('Ukuran cover melebihi batas 2 MB.');
        }

        $allowedExts  = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
        $allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];

        if (! in_array(strtolower($file->getClientExtension()), $allowedExts, true)) {
            throw new \RuntimeException('Format cover tidak didukung. Gunakan JPG, PNG, GIF, atau WebP.');
        }

        $finfo    = new \finfo(FILEINFO_MIME_TYPE);
        $realMime = $finfo->file($file->getTempName());
        if (! in_array($realMime, $allowedMimes, true)) {
            throw new \RuntimeException('Konten file cover tidak sesuai format gambar.');
        }

        $ext        = strtolower($file->getClientExtension());
        $storedName = bin2hex(random_bytes(16)) . '.' . $ext;
        $dest       = ROOTPATH . 'storage/covers/';

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

        $file->move($dest, $storedName);
        return $storedName;
    }

    /** Delete a stored file safely (never allow path traversal). */
    protected function deleteStoredFile(string $subdir, string $filename): void
    {
        if (empty($filename)) return;
        $path = ROOTPATH . 'storage/' . $subdir . '/' . basename($filename);
        if (is_file($path)) {
            unlink($path);
        }
    }
}
