<?php
declare(strict_types=1);

namespace App\Controllers;

require_once BASE_PATH . '/app/helpers/permissions.php';

use App\Core\Controller;
use App\Core\Database;

final class SubmissionZipController extends Controller
{
    private function buildZip(int $submissionId): string
    {
        $db = Database::getInstance();

        $st = $db->prepare("SELECT * FROM submission_files WHERE submission_id=:sid AND is_active=1 ORDER BY id ASC");
        $st->execute([':sid'=>$submissionId]);
        $files = $st->fetchAll();

        if (empty($files)) {
            throw new \RuntimeException("No files");
        }

        $zipDir = sys_get_temp_dir();
        $zipPath = $zipDir . '/submission_' . $submissionId . '_' . time() . '.zip';

        $zip = new \ZipArchive();
        if ($zip->open($zipPath, \ZipArchive::CREATE) !== true) {
            throw new \RuntimeException("ZIP open failed");
        }

        foreach ($files as $f) {
            $rel = (string)$f['file_path'];
            $abs = __DIR__ . '/../../storage/' . $rel;
            if (!is_file($abs)) continue;

            $cat = (string)($f['file_category'] ?? 'file');
            $name = (string)($f['original_name'] ?? basename($abs));
            $safeName = preg_replace('/[^\w\-.()\s]+/u', '_', $name);
            $zip->addFile($abs, $cat . '/' . $safeName);
        }

        $zip->close();
        return $zipPath;
    }

    public function download(): void
    {
        require_login();
        $db = Database::getInstance();
        $uid = (int)auth_id();
        $submissionId = (int)($_GET['submission_id'] ?? 0);

        $st = $db->prepare("SELECT id FROM submissions WHERE id=:id AND author_id=:uid LIMIT 1");
        $st->execute([':id'=>$submissionId, ':uid'=>$uid]);
        if (!$st->fetchColumn()) { http_response_code(403); exit('Forbidden'); }

        try {
            $zipPath = $this->buildZip($submissionId);
        } catch (\Throwable $e) {
            flash('danger', 'No files to download');
            redirect('author/submissions');
        }

        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename="submission_'.$submissionId.'.zip"');
        header('Content-Length: ' . filesize($zipPath));
        readfile($zipPath);
        @unlink($zipPath);
        exit;
    }

    public function adminDownload(): void
    {
        require_permission('admin.access');
        $submissionId = (int)($_GET['submission_id'] ?? 0);

        try {
            $zipPath = $this->buildZip($submissionId);
        } catch (\Throwable $e) {
            flash('danger', 'No files to download');
            redirect('admin/submissions/view?id='.$submissionId);
        }

        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename="submission_'.$submissionId.'.zip"');
        header('Content-Length: ' . filesize($zipPath));
        readfile($zipPath);
        @unlink($zipPath);
        exit;
    }
}
