<?php
namespace App\Controllers;

use App\Core\R2;
use App\Models\FileModel;
use App\Models\FolderModel;

class PublicController
{
    public function show(array $params): void
    {
        $token = $params['token'] ?? '';

        // Try file first, then folder
        $file = FileModel::findByToken($token);
        $folder = null;
        $folderFiles = [];

        if (!$file) {
            $folder = FolderModel::findByToken($token);
            if ($folder) {
                $folderFiles = FolderModel::allFilesRecursive($folder['id']);
            }
        }

        // Not found → show error page
        if (!$file && !$folder) {
            $appName = CONFIG['APP_NAME'];
            $appUrl = CONFIG['APP_URL'] . CONFIG['BASE_PATH'];
            $faviconUrl = $appUrl . '/favicon.svg';
            $errorType = 'not_found';
            http_response_code(404);
            require ROOT_PATH . '/app/Views/public_error.php';
            return;
        }

        $r2 = new R2();
        $previewUrl = null;
        $mime = '';
        $appName = CONFIG['APP_NAME'];
        $appUrl = CONFIG['APP_URL'] . CONFIG['BASE_PATH'];
        $faviconUrl = $appUrl . '/favicon.svg';
        $pageUrl = $appUrl . '/s/' . $token;
        $downloadBase = $appUrl . '/s/' . $token . '/download';

        // Pass token to view
        $viewToken = $token;

        if ($file) {
            $mime = $file['mime_type'];
            if (str_starts_with($mime, 'image/') || $mime === 'application/pdf') {
                $disposition = 'inline; filename="' . addcslashes($file['display_name'], '"\\') . '"';
                $previewUrl = $r2->presignUrl('GET', $file['object_key'], 600, [
                    'response-content-disposition' => $disposition,
                    'response-content-type' => $mime,
                ]);
            }

            $ogImageUrl = $appUrl . '/og-image.php?' . http_build_query([
                'name' => $file['display_name'],
                'size' => self::humanSize((int)$file['size_bytes']),
                'type' => explode('/', $mime)[0] === 'image' ? 'image' :
                         ($mime === 'application/pdf' ? 'pdf' :
                         (explode('/', $mime)[0] ?? 'file')),
            ]);

            $isFolder = false;
            $token = $viewToken;
            require ROOT_PATH . '/app/Views/public_share.php';
        } else {
            $ogImageUrl = $appUrl . '/og-image.php?' . http_build_query([
                'name' => $folder['name'],
                'size' => count($folderFiles) . ' file',
                'type' => 'folder',
            ]);

            $isFolder = true;
            $token = $viewToken;
            require ROOT_PATH . '/app/Views/public_share.php';
        }
    }

    public function download(array $params): void
    {
        $token = $params['token'] ?? '';
        $file = FileModel::findByToken($token);

        if (!$file) {
            $appName = CONFIG['APP_NAME'];
            $appUrl = CONFIG['APP_URL'] . CONFIG['BASE_PATH'];
            $faviconUrl = $appUrl . '/favicon.svg';
            $errorType = 'not_found';
            http_response_code(404);
            require ROOT_PATH . '/app/Views/public_error.php';
            return;
        }

        $r2 = new R2();
        $disposition = 'attachment; filename="' . addcslashes($file['display_name'], '"\\') . '"';
        $url = $r2->presignUrl('GET', $file['object_key'], 300, [
            'response-content-disposition' => $disposition,
        ]);

        header('Location: ' . $url, true, 302);
        exit;
    }

    /**
     * Download individual file from a shared folder
     */
    public function downloadFolderFile(array $params): void
    {
        $token = $params['token'] ?? '';
        $fileId = (int)($params['fileId'] ?? 0);

        // Must be a shared folder
        $folder = FolderModel::findByToken($token);
        if (!$folder) {
            $appName = CONFIG['APP_NAME'];
            $appUrl = CONFIG['APP_URL'] . CONFIG['BASE_PATH'];
            $faviconUrl = $appUrl . '/favicon.svg';
            $errorType = 'not_found';
            http_response_code(404);
            require ROOT_PATH . '/app/Views/public_error.php';
            return;
        }

        // Check the file is inside this shared folder
        $folderFiles = FolderModel::allFilesRecursive($folder['id']);
        $targetFile = null;
        foreach ($folderFiles as $ff) {
            if ((int)$ff['id'] === $fileId) {
                $targetFile = $ff;
                break;
            }
        }

        if (!$targetFile) {
            $appName = CONFIG['APP_NAME'];
            $appUrl = CONFIG['APP_URL'] . CONFIG['BASE_PATH'];
            $faviconUrl = $appUrl . '/favicon.svg';
            $errorType = 'file_not_in_folder';
            http_response_code(404);
            require ROOT_PATH . '/app/Views/public_error.php';
            return;
        }

        $r2 = new R2();
        $disposition = 'attachment; filename="' . addcslashes($targetFile['display_name'], '"\\') . '"';
        $url = $r2->presignUrl('GET', $targetFile['object_key'], 300, [
            'response-content-disposition' => $disposition,
        ]);

        header('Location: ' . $url, true, 302);
        exit;
    }

    private static function humanSize(int $bytes): string
    {
        if ($bytes === 0) return '0 B';
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        $i = 0; $val = (float)$bytes;
        while ($val >= 1024 && $i < count($units) - 1) { $val /= 1024; $i++; }
        return round($val, 1) . ' ' . $units[$i];
    }
}
