<?php
/*-----------------------------------------------*/
/*  EXTHEM.ES
/*  PREMIUM WORDRESS THEMES
/*
/*  STOP DON'T TRY EDIT
/*  IF YOU DON'T KNOW PHP 
/*
/*  As Errors In Your Themes
/*  Are Not The Responsibility
/*  Of The DEVELOPERS
/*  @EXTHEM.ES
/*  
/*  Follow Social Media Exthem.es
/*  Youtube : https://www.youtube.com/channel/UCpcZNXk6ySLtwRSBN6fVyLA
/*  Facebook : https://www.facebook.com/groups/exthem.es
/*  Twitter : https://x.com/bangreyblog
/*  Instagram : https://www.instagram.com/exthem.es/
/*  Telegram : https://t.me/exthemes_helps
/*  TikTok : https://www.tiktok.com/@exthemes
/*	More Premium Themes Visit Now On https://exthem.es/
/*-----------------------------------------------*/
if ( ! defined( 'ABSPATH' ) ) exit; 
// Silence is golden.

/**
 * Upload remote file – but return existing attachment ID if already uploaded
 *
 * @param string $file_url          Remote URL
 * @param int    $parent_post_id    Optional parent post
 * @param callable $progress_callback Optional progress function
 * @return int|WP_Error             Existing or new attachment ID
 */
function wp_upload_remote_file( $file_url, $parent_post_id = 0, $progress_callback = null ) {

    // Load WP core if needed
    if ( ! function_exists( 'download_url' ) ) {
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';
    }

    // 1. Check by remote URL stored in postmeta (fastest)
    global $wpdb;
    $existing_id = $wpdb->get_var( $wpdb->prepare(
        "SELECT post_id FROM $wpdb->postmeta 
         WHERE meta_key = '_remote_file_url' 
         AND meta_value = %s 
         LIMIT 1",
        $file_url
    ) );

    if ( $existing_id ) {
        if ( is_callable( $progress_callback ) ) {
            call_user_func( $progress_callback, 1, 1, 'already_exists' );
        }
        return (int) $existing_id; // Already uploaded → return ID immediately
    }

    // 2. If you prefer hash-based deduplication (prevents duplicates even if URL changed)
    // Uncomment the block below if you want this extra safety

    /*
    $headers = wp_remote_head( $file_url, array( 'timeout' => 30 ) );
    if ( ! is_wp_error( $headers ) ) {
        $etag = wp_remote_retrieve_header( $headers, 'etag' );
        $last_modified = wp_remote_retrieve_header( $headers, 'last-modified' );

        if ( $etag || $last_modified ) {
            $hash = md5( $etag . $last_modified . $file_url );
            $existing_id = $wpdb->get_var( $wpdb->prepare(
                "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_file_hash' AND meta_value = %s LIMIT 1",
                $hash
            ) );
            if ( $existing_id ) {
                // Optionally update the URL meta in case URL changed
                update_post_meta( $existing_id, '_remote_file_url', $file_url );
                return (int) $existing_id;
            }
        }
    }
    */

    // ——— If not found → proceed with normal download ———
    $total_size = 0;
    $headers    = wp_remote_head( $file_url, array( 'timeout' => 30 ) );
    if ( ! is_wp_error( $headers ) && ! empty( $headers['headers']['content-length'] ) ) {
        $total_size = (int) $headers['headers']['content-length'];
    }

    $tmp = download_url_with_progress( $file_url, $total_size, $progress_callback );
    if ( is_wp_error( $tmp ) ) {
        return $tmp;
    }

    // ——— Security checks (APK + IPA already allowed from previous steps) ———
    $file_array = array(
        'name'     => wp_basename( parse_url( $file_url, PHP_URL_PATH ) ),
        'type'     => wp_check_filetype( $tmp )['type'],
        'tmp_name' => $tmp,
        'error'    => 0,
        'size'     => filesize( $tmp ),
    );

    $ext = strtolower( pathinfo( $file_array['name'], PATHINFO_EXTENSION ) );
    if ( $ext === 'ipa' ) {
        $file_array['type'] = 'application/octet-stream';
    } elseif ( $ext === 'apk' ) {
        $file_array['type'] = 'application/vnd.android.package-archive';
    }

    $allowed = get_allowed_mime_types();
    if ( empty( $file_array['type'] ) || ! in_array( $file_array['type'], $allowed, true ) ) {
        @unlink( $tmp );
        return new WP_Error( 'invalid_type', 'File type not allowed.' );
    }

    // ——— Sideload → insert → metadata ———
    if ( is_callable( $progress_callback ) ) {
        call_user_func( $progress_callback, 0, 1, 'sideload' );
    }

    $overrides = array( 'test_form' => false );
    $results   = wp_handle_sideload( $file_array, $overrides );

    if ( isset( $results['error'] ) ) {
        @unlink( $tmp );
        return new WP_Error( 'sideload_failed', $results['error'] );
    }

    if ( is_callable( $progress_callback ) ) {
        call_user_func( $progress_callback, 1, 1, 'sideload' );
    }

    $filename = $results['file'];

    $attachment = array(
        'post_mime_type' => $results['type'],
        'post_title'     => preg_replace( '/\.[^.]+$/', '', wp_basename( $filename ) ),
        'post_content'   => '',
        'post_status'    => 'inherit',
        'post_parent'    => (int) $parent_post_id,
    );

    $attach_id = wp_insert_attachment( $attachment, $filename, (int) $parent_post_id );
    if ( is_wp_error( $attach_id ) ) {
        @unlink( $filename );
        return $attach_id;
    }

    // Store the original remote URL so we can detect duplicates later
    update_post_meta( $attach_id, '_remote_file_url', $file_url );

    // Optional: store hash for extra deduplication (uncomment if you enabled the block above)
    // $hash = md5( wp_remote_retrieve_header( $headers, 'etag' ) . wp_remote_retrieve_header( $headers, 'last-modified' ) . $file_url );
    // update_post_meta( $attach_id, '_file_hash', $hash );

    // Generate metadata
    if ( is_callable( $progress_callback ) ) {
        call_user_func( $progress_callback, 0, 1, 'metadata' );
    }
    $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
    wp_update_attachment_metadata( $attach_id, $attach_data );
    if ( is_callable( $progress_callback ) ) {
        call_user_func( $progress_callback, 1, 1, 'metadata' );
    }

    return $attach_id; // New attachment ID
}

// Progress bar real-time pakai transient + AJAX
add_action('wp_ajax_upload_remote_with_progress', 'ajax_upload_remote_with_progress');
add_action('wp_ajax_nopriv_upload_remote_with_progress', 'ajax_upload_remote_with_progress');
add_action('wp_ajax_get_progress', 'ajax_get_progress');
add_action('wp_ajax_nopriv_get_progress', 'ajax_get_progress');

function ajax_upload_remote_with_progress() {
    check_ajax_referer('upload_remote_nonce');

    $url = sanitize_url($_POST['file_url']);
    if (!$url) wp_send_json_error('URL kosong');

    // Reset progress
    delete_transient('upload_progress_' . get_current_user_id());

    $attach_id = wp_upload_remote_file($url, 0, function($done, $total, $stage) {
        $pct = $total > 0 ? round(($done / $total) * 100, 1) : 0;

        // Bobot tiap tahap biar progress bar smooth
        $weights = ['download' => 80, 'sideload' => 10, 'metadata' => 10];
        $overall = 0;
        foreach ($weights as $s => $w) {
            if ($stage === $s) $overall += $w * ($done >= $total ? 1 : $done/$total);
            elseif ($stage > $s) $overall += $w;
        }

        set_transient('upload_progress_' . get_current_user_id(), [
            'percent' => round($overall),
            'message' => ucfirst($stage) . '... ' . $pct . '%',
            'done'    => false
        ], 300);
    });

    // Selesai
    set_transient('upload_progress_' . get_current_user_id(), [
        'percent' => 100,
        'message' => 'Selesai!',
        'done'    => true,
        'attach_id' => is_wp_error($attach_id) ? 0 : $attach_id,
        'url'     => is_wp_error($attach_id) ? '' : wp_get_attachment_url($attach_id)
    ], 300);

    if (is_wp_error($attach_id)) {
        wp_send_json_error($attach_id->get_error_message());
    } else {
        wp_send_json_success([
            'id'  => $attach_id,
            'url' => wp_get_attachment_url($attach_id)
        ]);
    }
}

function ajax_get_progress() {
    check_ajax_referer('upload_remote_nonce');
    $progress = get_transient('upload_progress_' . get_current_user_id()) ?: [
        'percent' => 0,
        'message' => 'Menunggu...',
        'done'    => false
    ];
    wp_send_json($progress);
}
