<?php

namespace Miruni;

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}
// @phpstan-ignore requireOnce.fileNotFound
require_once ABSPATH . 'wp-admin/includes/file.php';
// @phpstan-ignore requireOnce.fileNotFound
require_once ABSPATH . 'wp-admin/includes/media.php';
// @phpstan-ignore requireOnce.fileNotFound
require_once ABSPATH . 'wp-admin/includes/image.php';

class Miruni_Media_Manager
{

    /**
     * Get the default upload parameters.
     *
     * @return array<string, mixed>
     */
    static function get_upload_defaults(): array
    {
        return array(
            'filename' => null,
            'post_id' => 0,
            'timeout' => 300, // 5 minutes for large files
            'description' => '',
            'alt_text' => ''
        );
    }

    private static function download_file_from_url(string $url): ?string
    {
        // validate url
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            return null;
        }

        // download file
        $temp_file = download_url($url, self::get_upload_defaults()['timeout']);
        if (is_wp_error($temp_file)) {
            return null;
        }

        if (!file_exists($temp_file) || filesize($temp_file) === 0) {
            @unlink($temp_file);
            return null;
        }

        return $temp_file;
    }

    /**
     * Download a remote file and sideload it into the WP media library.
     *
     * Returns attachment ID on success or WP_Error on failure.
     *
     * @param string $url
     * @param array<string, mixed> $options
     * @return int|\WP_Error
     */
    public static function upload_from_url(string $url, array $options = [])
    {
        $opts = array_merge(self::get_upload_defaults(), $options);

        $temp_file = self::download_file_from_url($url);
        if ($temp_file === null) {
            return new \WP_Error('download_failed', 'Unable to download file from URL.');
        }

        // Determine filename
        $derived_name = basename(parse_url($url, PHP_URL_PATH) ?: 'file');
        $filename = $opts['filename'] ?: $derived_name;

        $file_array = array(
            'name' => wp_basename($filename),
            'tmp_name' => $temp_file,
        );

        // media_handle_sideload will call wp_handle_sideload() internally.
        // test_form must be false because this is not coming from a form.
        $attachment_id = media_handle_sideload($file_array, intval($opts['post_id']), $opts['description']);

        // If there's an error, clean up temp file and return the error.
        if (is_wp_error($attachment_id)) {
            @unlink($temp_file);
            return $attachment_id;
        }

        // Optionally set alt text
        if (!empty($opts['alt_text'])) {
            update_post_meta($attachment_id, '_wp_attachment_image_alt', sanitize_text_field($opts['alt_text']));
        }

        return $attachment_id;
    }

}