<?php

declare(strict_types=1);

use GalpaoImperial\Api\HttpException;
use function GalpaoImperial\Api\jsonResponse;
use function GalpaoImperial\Api\requireAdmin;
use function GalpaoImperial\Api\slugify;

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

if (strtoupper($method) === 'POST') {
    requireAdmin();

    $file = $_FILES['file'] ?? null;
    if (!is_array($file) || ($file['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) {
        throw new HttpException(422, 'Envie uma imagem para upload.');
    }

    if (($file['error'] ?? UPLOAD_ERR_OK) !== UPLOAD_ERR_OK) {
        throw new HttpException(422, 'Falha ao receber a imagem.');
    }

    $tmpName = (string) ($file['tmp_name'] ?? '');
    if ($tmpName === '' || !is_uploaded_file($tmpName)) {
        throw new HttpException(422, 'Arquivo de upload inválido.');
    }

    $maxBytes = 8 * 1024 * 1024;
    if ((int) ($file['size'] ?? 0) > $maxBytes) {
        throw new HttpException(422, 'A imagem deve ter no máximo 8MB.');
    }

    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mimeType = (string) $finfo->file($tmpName);
    $extensions = [
        'image/jpeg' => 'jpg',
        'image/png' => 'png',
        'image/webp' => 'webp',
        'image/gif' => 'gif',
    ];

    if (!isset($extensions[$mimeType])) {
        throw new HttpException(422, 'Use uma imagem JPG, PNG, WEBP ou GIF.');
    }

    $uploadsDir = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'uploads';
    if (!is_dir($uploadsDir) && !mkdir($uploadsDir, 0775, true) && !is_dir($uploadsDir)) {
        throw new HttpException(500, 'Não foi possível criar a pasta de uploads.');
    }

    $originalName = pathinfo((string) ($file['name'] ?? 'imagem'), PATHINFO_FILENAME);
    $baseName = slugify($originalName);
    $fileName = sprintf('%s-%s.%s', $baseName, bin2hex(random_bytes(5)), $extensions[$mimeType]);
    $targetPath = $uploadsDir . DIRECTORY_SEPARATOR . $fileName;

    if (!move_uploaded_file($tmpName, $targetPath)) {
        throw new HttpException(500, 'Não foi possível salvar a imagem.');
    }

    jsonResponse([
        'success' => true,
        'data' => [
            'url' => '/uploads/' . $fileName,
            'mimeType' => $mimeType,
            'size' => (int) ($file['size'] ?? 0),
        ],
    ]);
}

if (strtoupper($method) !== 'GET') {
    throw new HttpException(405, 'Método não permitido.');
}

$url = trim((string) ($_GET['url'] ?? ''));
if ($url === '') {
    throw new HttpException(422, 'URL da mídia é obrigatória.');
}

if (!preg_match('#^https?://#i', $url)) {
    throw new HttpException(422, 'URL de mídia inválida.');
}

$parts = parse_url($url);
$host = strtolower((string) ($parts['host'] ?? ''));
if ($host === '' || str_contains($host, '127.0.0.1') || str_contains($host, 'localhost')) {
    throw new HttpException(422, 'Host de mídia não permitido.');
}

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_MAXREDIRS => 5,
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT => 20,
    CURLOPT_USERAGENT => 'GalpaoImperialMediaProxy/1.0',
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => 0,
    CURLOPT_HTTPHEADER => [
        'Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
        'Referer: https://imgur.com/',
    ],
]);

$body = curl_exec($ch);
$statusCode = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$curlError = $body === false ? (curl_error($ch) ?: 'Falha ao buscar mídia remota.') : '';
curl_close($ch);

if ($body === false || $statusCode >= 400) {
    $context = stream_context_create([
        'http' => [
            'method' => 'GET',
            'header' => "User-Agent: GalpaoImperialMediaProxy/1.0\r\nAccept: image/*,*/*;q=0.8\r\nReferer: https://imgur.com/\r\n",
            'timeout' => 20,
            'follow_location' => 1,
        ],
        'ssl' => [
            'verify_peer' => false,
            'verify_peer_name' => false,
        ],
    ]);
    $fallbackBody = @file_get_contents($url, false, $context);
    if ($fallbackBody === false) {
        throw new HttpException(502, $curlError !== '' ? $curlError : 'A origem da imagem respondeu com erro.');
    }
    $body = $fallbackBody;
    if ($contentType === '') {
        foreach ($http_response_header ?? [] as $headerLine) {
            if (stripos($headerLine, 'Content-Type:') === 0) {
                $contentType = trim(substr($headerLine, 13));
                break;
            }
        }
    }
}

if ($contentType === '' || !str_starts_with(strtolower($contentType), 'image/')) {
    $extension = strtolower(pathinfo((string) ($parts['path'] ?? ''), PATHINFO_EXTENSION));
    $contentTypes = [
        'png' => 'image/png',
        'webp' => 'image/webp',
        'svg' => 'image/svg+xml',
        'gif' => 'image/gif',
    ];
    $contentType = $contentTypes[$extension] ?? 'image/jpeg';
}

http_response_code(200);
header('Content-Type: ' . $contentType);
header('Cache-Control: public, max-age=86400');
header('Access-Control-Allow-Origin: *');
echo $body;
exit;
