<?php
/**
 * Automatic Price/UVP Update (Cron)
 * and Metabox with Admin Menu for Manual Price Updates.
 *
 * - Sets up scheduled price updates using WP Cron.
 * - Provides an admin interface for manual price updates.
 * - Fetches price, UVP, and Prime status from Amazon API.
 *
 * @package Boxyfy
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

/* Cron-Schedules hinzufügen */
function boxyfy_add_cron_schedules( $schedules ) {
    // Alle 6 Stunden.
    if ( ! isset( $schedules['6_hours'] ) ) {
        $schedules['6_hours'] = array(
            'interval' => 6 * 3600,
            'display'  => __( 'Alle 6 Stunden', 'boxyfy' ),
        );
    }
    // Alle 12 Stunden.
    if ( ! isset( $schedules['12_hours'] ) ) {
        $schedules['12_hours'] = array(
            'interval' => 12 * 3600,
            'display'  => __( 'Alle 12 Stunden', 'boxyfy' ),
        );
    }
    // Alle 24 Stunden.
    if ( ! isset( $schedules['24_hours'] ) ) {
        $schedules['24_hours'] = array(
            'interval' => 24 * 3600,
            'display'  => __( 'Alle 24 Stunden', 'boxyfy' ),
        );
    }
    // Alle 48 Stunden.
    if ( ! isset( $schedules['48_hours'] ) ) {
        $schedules['48_hours'] = array(
            'interval' => 48 * 3600,
            'display'  => __( 'Alle 48 Stunden', 'boxyfy' ),
        );
    }
    return $schedules;
}
add_filter( 'cron_schedules', 'boxyfy_add_cron_schedules' );

/* Cron-Job für Preisupdates einrichten */
function boxyfy_update_price_cron_schedule() {
    $hookname = 'boxyfy_cron_update_amazon_prices';
    // Option (in Stunden, Standard: 12)
    $interval = (int) get_option( 'boxyfy_autoupdate_interval', 12 );
    if ( 0 === $interval ) {
        $timestamp = wp_next_scheduled( $hookname );
        if ( $timestamp ) {
            wp_unschedule_event( $timestamp, $hookname );
        }
        return;
    }
    $schedule_string = $interval . '_hours';
    $timestamp = wp_next_scheduled( $hookname );
    if ( $timestamp ) {
        $current_schedule = wp_get_schedule( $hookname );
        if ( ! $current_schedule || $current_schedule !== $schedule_string ) {
            wp_unschedule_event( $timestamp, $hookname );
            wp_schedule_event( time() + ( $interval * 3600 ), $schedule_string, $hookname );
        }
    } else {
        wp_schedule_event( time() + ( $interval * 3600 ), $schedule_string, $hookname );
    }
}
add_action( 'init', 'boxyfy_update_price_cron_schedule' );

/* Aktualisiert Preis und UVP für alle relevanten Posts */
function boxyfy_update_amazon_prices_for_all() {
    $args = array(
        'post_type'      => 'boxyfy_tsprodukte',
        'posts_per_page' => -1,
        'meta_query'     => array(
            array(
                'key'     => 'tsprodukt_asin_price',
                'compare' => 'EXISTS',
            ),
        ),
    );
    $query = new WP_Query( $args );
    if ( $query->have_posts() ) {
        while ( $query->have_posts() ) {
            $query->the_post();
            $post_id = get_the_ID();
            $asin = get_post_meta( $post_id, 'tsprodukt_asin_price', true );
            if ( empty( $asin ) ) {
                continue;
            }
            $data = boxyfy_get_amazon_data( $asin, false );
            if ( $data ) {
                update_post_meta( $post_id, 'tsprodukt_price1', $data['price'] );
                update_post_meta( $post_id, 'tsprodukt_saving_basis', $data['savingBasis'] );
                update_post_meta( $post_id, 'tsprodukt_prime_status', $data['isPrimeEligible'] ? 'yes' : 'no' );
            } else {
                update_post_meta( $post_id, 'tsprodukt_saving_basis', 'N/A' );
            }
        }
        wp_reset_postdata();
    }
}
add_action( 'boxyfy_cron_update_amazon_prices', 'boxyfy_update_amazon_prices_for_all' );

/* Callback für die Metabox (Nur HTML-Ausgabe – CSS und JS werden extern geladen) */
function boxyfy_amazon_price_metabox_callback( $post ) {
    $asin_price   = get_post_meta( $post->ID, 'tsprodukt_asin_price', true );
    $price        = get_post_meta( $post->ID, 'tsprodukt_price1', true );
    $saving_basis = get_post_meta( $post->ID, 'tsprodukt_saving_basis', true );
	$sales_rank  = get_post_meta( $post->ID, 'tsprodukt_sales_rank', true );
    $image_ids    = get_post_meta( $post->ID, 'tsprodukt_amazon_images', true );
    $nonce = wp_create_nonce( 'boxyfy_amazon_image_nonce' );
    ?>
    <p><?php esc_html_e( 'Aktuellen Preis/Bilder/Sales-Rank durch den Button abrufen. (Vorher bitte das Produkt veröffentlichen!)', 'boxyfy' ); ?></p>
    <label for="tsprodukt_fetch_images">
        <input type="checkbox" id="tsprodukt_fetch_images" name="tsprodukt_fetch_images" />
        <?php esc_html_e( 'Amazon-Produktbilder (max. 500x500 Pixel) mitabrufen?', 'boxyfy' ); ?>
    </label>
    <br><br>
    <label for="tsprodukt_asin_price"><?php esc_html_e( 'Amazon-ASIN eingeben:', 'boxyfy' ); ?></label>
    <input type="text" id="tsprodukt_asin_price" name="tsprodukt_asin_price" value="<?php echo esc_attr( $asin_price ); ?>" />
    <?php if ( ! empty( $price ) ) : ?>
    	<p id="current-price" class="price-message success-message">
        	<strong><?php esc_html_e( 'Aktueller Preis:', 'boxyfy' ); ?></strong> <?php echo esc_html( $price ); ?>
        	<?php if ( ! empty( $saving_basis ) && 'N/A' !== $saving_basis ) : ?>
            	<br><strong><?php esc_html_e( 'Aktueller UVP:', 'boxyfy' ); ?></strong> <?php echo esc_html( $saving_basis ); ?>
        	<?php endif; ?>
        	<?php if ( ! empty( $sales_rank ) ) : ?>
            	<br><strong><?php esc_html_e( 'Amazon-Verkaufsrang:', 'boxyfy' ); ?></strong> <?php echo esc_html( $sales_rank ); ?>
        	<?php endif; ?>
    	</p>
	<?php else : ?>
        <p id="current-price" class="price-message success-message">
            <strong><?php esc_html_e( 'Aktueller Preis:', 'boxyfy' ); ?></strong> <?php esc_html_e( 'Nicht verfügbar', 'boxyfy' ); ?>
        </p>
    <?php endif; ?>
    <button type="button" class="button" id="fetch-amazon-data">
        <?php esc_html_e( 'Daten jetzt abrufen', 'boxyfy' ); ?>
    </button>
    <div id="price-error-message" class="error-message"></div>
    <div id="price-success-message" class="success-message"></div>
    <!-- Anzeige der abgerufenen Bilder -->
    <div id="amazon-images-gallery">
        <?php
        if ( ! empty( $image_ids ) && is_array( $image_ids ) ) :
            foreach ( $image_ids as $image_id ) :
                $image_url = wp_get_attachment_url( $image_id );
                if ( $image_url ) :
                    ?>
                    <div class="amazon-image-item" data-image-id="<?php echo esc_attr( $image_id ); ?>">
                        <img src="<?php echo esc_url( $image_url ); ?>" width="90" height="90" />
                        <button type="button" class="remove-image-button" data-image-id="<?php echo esc_attr( $image_id ); ?>">X</button>
                    </div>
                    <?php
                endif;
            endforeach;
        endif;
        ?>
    </div>

    <?php
}

/* Metabox registrieren */
function boxyfy_register_amazon_metabox() {
    add_meta_box(
        'ts_amazon_price_metabox',
        __( 'Boxyfy: Amazon-Preis, Amazon-Bilder und Amazon-Sales-Rank abrufen', 'boxyfy' ),
        'boxyfy_amazon_price_metabox_callback',
        'boxyfy_tsprodukte', // Beitragstyp anpassen
        'normal',
        'high'
    );
}
add_action( 'add_meta_boxes', 'boxyfy_register_amazon_metabox' );

/* AJAX-Handler: Amazon-Daten abrufen */
add_action( 'wp_ajax_boxyfy_fetch_amazon_data', 'boxyfy_fetch_amazon_data' );
function boxyfy_fetch_amazon_data() {
    check_ajax_referer( 'boxyfy_amazon_image_nonce', 'nonce' );
    if ( ! isset( $_POST['asin'], $_POST['post_id'] ) ) {
        wp_send_json_error( array( 'message' => 'Fehlende ASIN oder Post-ID.' ) );
    }
    $asin         = sanitize_text_field( wp_unslash( $_POST['asin'] ) );
    $post_id      = absint( $_POST['post_id'] );
    $fetch_images = ! empty( $_POST['fetch_images'] ) && $_POST['fetch_images'] === '1';
    $data = boxyfy_get_amazon_data( $asin, $fetch_images );
    if ( $data ) {
        update_post_meta( $post_id, 'tsprodukt_asin_price', $asin );
        update_post_meta( $post_id, 'tsprodukt_price1', $data['price'] );
        update_post_meta( $post_id, 'tsprodukt_prime_status', $data['isPrimeEligible'] ? 'yes' : 'no' );
        update_post_meta( $post_id, 'tsprodukt_saving_basis', $data['savingBasis'] );
		update_post_meta( $post_id, 'tsprodukt_sales_rank', $data['salesRank'] );
        $response_data = array(
            'price'        => $data['price'],
            'savingBasis'  => $data['savingBasis'],
            'prime_status' => $data['isPrimeEligible'] ? 'Prime verfügbar' : 'Kein Prime',
        );
        if ( $fetch_images ) {
            $media_ids  = array();
            $image_urls = array();
            foreach ( $data['images'] as $image_url ) {
                $media = media_sideload_image( $image_url, $post_id, null, 'id' );
                if ( ! is_wp_error( $media ) ) {
                    $media_ids[]  = $media;
                    $image_urls[] = wp_get_attachment_url( $media );
                }
            }
            update_post_meta( $post_id, 'tsprodukt_amazon_images', $media_ids );
            $response_data['image_ids']  = $media_ids;
            $response_data['image_urls'] = $image_urls;
        }
        wp_send_json_success( $response_data );
    } else {
        update_post_meta( $post_id, 'tsprodukt_prime_status', 'no' );
        update_post_meta( $post_id, 'tsprodukt_saving_basis', 'N/A' );
        wp_send_json_error( array( 'message' => 'Keine Daten für diese ASIN gefunden.' ) );
    }
}

/* AJAX-Handler: Amazon-Bild entfernen */
add_action( 'wp_ajax_boxyfy_remove_amazon_image', 'boxyfy_remove_amazon_image' );
function boxyfy_remove_amazon_image() {
    check_ajax_referer( 'boxyfy_amazon_image_nonce', 'nonce' );
    if ( ! isset( $_POST['image_id'], $_POST['post_id'] ) ) {
        wp_send_json_error( array( 'message' => 'Unvollständige Anfrage.' ) );
    }
    $image_id = absint( $_POST['image_id'] );
    $post_id  = absint( $_POST['post_id'] );
    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        wp_send_json_error( array( 'message' => 'Sie haben keine Berechtigung, dieses Bild zu entfernen.' ) );
    }
    $images = get_post_meta( $post_id, 'tsprodukt_amazon_images', true );
    if ( ! is_array( $images ) ) {
        wp_send_json_error( array( 'message' => 'Keine Bilder gefunden.' ) );
    }
    $key = array_search( $image_id, $images );
    if ( false === $key ) {
        wp_send_json_error( array( 'message' => 'Bild nicht gefunden.' ) );
    }
    unset( $images[ $key ] );
    $images = array_values( $images );
    if ( ! update_post_meta( $post_id, 'tsprodukt_amazon_images', $images ) ) {
        wp_send_json_error( array( 'message' => 'Fehler beim Aktualisieren der Bilddaten.' ) );
    }
    // Optional: Bild aus der Mediathek löschen.
    wp_delete_attachment( $image_id, true );
    wp_send_json_success( array( 'message' => 'Bild erfolgreich entfernt.' ) );
}

/* Amazon-Daten abrufen */
function boxyfy_get_amazon_data( $asin, $fetch_images = false ) {
    $options = get_option(
        'boxyfy_amazon_settings',
        array(
            'access_key'  => '',
            'secret_key'  => '',
            'partner_tag' => '',
            'host'        => 'webservices.amazon.de',
            'region'      => 'eu-west-1',
        )
    );
    if ( empty( $options['access_key'] ) || empty( $options['secret_key'] ) || empty( $options['partner_tag'] ) ) {
        return null;
    }

    $host       = $options['host'];
    $region     = $options['region'];
    $accessKey  = $options['access_key'];
    $secretKey  = $options['secret_key'];
    $partnerTag = $options['partner_tag'];

    $resources = array(
        "Offers.Listings.Price",
        "Offers.Listings.SavingBasis",
        "Offers.Listings.DeliveryInfo.IsPrimeEligible",
		"BrowseNodeInfo.BrowseNodes.SalesRank",
    );
    if ( $fetch_images ) {
        $resources[] = "Images.Primary.Large";
        $resources[] = "Images.Variants.Large";
    }

    // Request-Payload zusammenbauen
    $payload = json_encode(
        array(
            "ItemIds"     => array( $asin ),
            "Resources"   => $resources,
            "PartnerTag"  => $partnerTag,
            "PartnerType" => "Associates",
            "Marketplace" => "www.amazon.de",
        )
    );

    $uriPath = "/paapi5/getitems";

    if ( ! class_exists( 'AwsV4' ) ) {
		require_once plugin_dir_path( BOXYFY_PLUGIN_FILE ) . 'assets/vendor/amazon/boxyfy-class-aws-v4.php';
	}

    // AwsV4 vorbereiten
    $awsv4 = new AwsV4( $accessKey, $secretKey );
    $awsv4->setRegionName( $region );
    $awsv4->setServiceName( "ProductAdvertisingAPI" );
    $awsv4->setPath( $uriPath );
    $awsv4->setPayload( $payload );
    $awsv4->setRequestMethod( "POST" );
    $awsv4->addHeader( 'content-encoding', 'amz-1.0' );
    $awsv4->addHeader( 'content-type', 'application/json; charset=utf-8' );
    $awsv4->addHeader( 'host', $host );
    $awsv4->addHeader( 'x-amz-target', 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.GetItems' );

    // Signierte Header erzeugen
    $headers = $awsv4->getHeaders();

    // HEADERS von "Key: Value" in ein Array konvertieren
    $headerString = implode(
        "\r\n",
        array_map(
            function ( $k, $v ) {
                return "$k: $v";
            },
            array_keys( $headers ),
            $headers
        )
    );

    $headerLines = explode("\r\n", $headerString);
    $headersArr  = array();
    foreach ( $headerLines as $line ) {
        $parts = explode(':', $line, 2);
        if ( 2 === count($parts) ) {
            $headerName = trim($parts[0]);
            $headerVal  = trim($parts[1]);
            $headersArr[$headerName] = $headerVal;
        }
    }

    // WP Remote POST
    $args = array(
        'method'  => 'POST',
        'headers' => $headersArr,
        'body'    => $payload,
        'timeout' => 20,
    );
    $response = wp_remote_post( 'https://' . $host . $uriPath, $args );

    // Fehler?
    if ( is_wp_error( $response ) ) {
        return null;
    }

    // Body extrahieren und JSON decodieren
    $body         = wp_remote_retrieve_body( $response );
    $responseData = json_decode( $body, true );
    if ( ! is_array( $responseData ) ) {
        return null;
    }

    // Prüfen, ob Item vorhanden
    if ( isset( $responseData['ItemsResult']['Items'][0] ) ) {
        $item = $responseData['ItemsResult']['Items'][0];

        // Price & Saving
        $price = $item['Offers']['Listings'][0]['Price']['DisplayAmount']       ?? 'N/A';
		
        // Überprüfung, ob UVP gültig ist
		$savingBasis = $item['Offers']['Listings'][0]['SavingBasis']['DisplayAmount'] ?? '';
		if ( empty( $savingBasis ) || $savingBasis === 'N/A' ) {
    		$savingBasis = 0; // Setze UVP auf 0, wenn nicht verfügbar
		}
		
		$salesRank = $item['BrowseNodeInfo']['BrowseNodes'][0]['SalesRank'] ?? null;
        $isPrimeEligible = $item['Offers']['Listings'][0]['DeliveryInfo']['IsPrimeEligible'] ?? false;

        // Images sammeln, falls fetch_images
        $images = array();
        if ( $fetch_images ) {
            if ( ! empty( $item['Images']['Primary']['Large']['URL'] ) ) {
                $images[] = $item['Images']['Primary']['Large']['URL'];
            }
            if ( ! empty( $item['Images']['Variants'] ) ) {
                foreach ( $item['Images']['Variants'] as $variant ) {
                    if ( ! empty( $variant['Large']['URL'] ) ) {
                        $images[] = $variant['Large']['URL'];
                    }
                }
            }
        }

        return array(
            'price'           => $price,
            'savingBasis'     => $savingBasis,
            'isPrimeEligible' => $isPrimeEligible,
			'salesRank'       => $salesRank,
            'images'          => $images,
        );
    }

    // Falls kein ItemsResult->Items
    return null;
}