<?php

use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\api\DefaultApi;
use Amazon\ProductAdvertisingAPI\v1\ApiException;
use Amazon\ProductAdvertisingAPI\v1\Configuration;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsRequest;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsResource;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\PartnerType;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ProductAdvertisingAPIClientException;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetVariationsRequest;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetVariationsResource;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsRequest;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsResource;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetBrowseNodesRequest;
use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetBrowseNodesResource;

require_once dirname( __FILE__ ) . '/paapi5-php-sdk/vendor/autoload.php';

function paapi5_getItem( $sAsin ) {
	global $__amazilonApiCalls;
	global $wpdb;
	global $__amazilonNoAutoVariant;

	if ( ( $config = get_option( 'bowsxWpApn' ) ) === false || empty( $config['publicKey'] ) || empty( $config['privateKey'] ) || empty( $config['associateTag'] ) ) {
		return false;
	}

	$return = $returnFail = array(
		'state'        => date( 'Y-m-d H:i:s' ),
		'asin'         => $sAsin,
		'aBrowseNodes' => array(),
		'title'        => __( 'Productinformation not retrievable', 'amazilon' ),
		'aFeatures'    => array()
	);

	$apiConfig = new Configuration();
	$apiConfig->setAccessKey( trim( $config['publicKey'] ) );
	$apiConfig->setSecretKey( trim( $config['privateKey'] ) );
	$partnerTag = trim( $config['associateTag'] );
	$apiConfig->setHost( 'webservices.amazon.de' );
	$apiConfig->setRegion( 'eu-west-1' );

	$apiInstance = new DefaultApi( new GuzzleHttp\Client(), $apiConfig );
	$itemIds     = array( $sAsin );
	$resources   = array(
		GetItemsResource::ITEM_INFOTITLE,
		GetItemsResource::OFFERSLISTINGSPRICE,
		GetItemsResource::OFFERSSUMMARIESLOWEST_PRICE,
		GetItemsResource::OFFERSLISTINGSSAVING_BASIS,
		GetItemsResource::OFFERSLISTINGSDELIVERY_INFOIS_PRIME_ELIGIBLE,
		GetItemsResource::IMAGESPRIMARYSMALL,
		GetItemsResource::IMAGESPRIMARYMEDIUM,
		GetItemsResource::IMAGESPRIMARYLARGE,
		GetItemsResource::IMAGESVARIANTSSMALL,
		GetItemsResource::IMAGESVARIANTSMEDIUM,
		GetItemsResource::IMAGESVARIANTSLARGE,
		GetItemsResource::BROWSE_NODE_INFOBROWSE_NODES,
		GetItemsResource::OFFERSSUMMARIESOFFER_COUNT,
		GetItemsResource::ITEM_INFOFEATURES,
		GetItemsResource::PARENT_ASIN,
	);

	$getItemsRequest = new GetItemsRequest();
	$getItemsRequest->setItemIds( $itemIds );
	$getItemsRequest->setPartnerTag( $partnerTag );
	$getItemsRequest->setPartnerType( PartnerType::ASSOCIATES );
	$getItemsRequest->setResources( $resources );
	$getItemsRequest->setCondition( 'New' );

	$invalidPropertyList = $getItemsRequest->listInvalidProperties();
	$length              = count( $invalidPropertyList );
	if ( $length > 0 ) {
		return false;
	}

	try {
		$getItemsResponse = $apiInstance->getItems( $getItemsRequest );
		if ( $getItemsResponse == null ) {
			return $returnFail;
		}
		if ( $getItemsResponse->getItemsResult() != null ) {
			if ( $getItemsResponse->getItemsResult()->getItems() != null ) {
				$responseList = $getItemsResponse->getItemsResult()->getItems();
				if ( count( $responseList ) < 1 ) {
					return $returnFail;
				}
				$oItem = $getItemsResponse->getItemsResult()->getItems()[0];
				if ( $oItem->getOffers() == null || $oItem->getOffers()->getListings() == null || count( $oItem->getOffers()->getListings() ) < 1 ) {
					if ( $__amazilonNoAutoVariant !== true ) {
						$sCheckAsin = $oItem->getParentASIN() !== null ? $oItem->getParentASIN() : $sAsin;
						$sNextAsin  = paapi5_getAvailableVariation( $sCheckAsin );
						if ( $sNextAsin != $sAsin ) {
							return paapi5_getItem( $sNextAsin, $cc );
						}
					}
				}
				$return = paapi5_prepareItem( $oItem );
			}
		}

		return $return;
	} catch ( ApiException $e ) {
		if ( ! is_admin() ) {
			return false;
		}
		$sError = 'PA-API5 Error: ';
		if ( $e->getResponseObject() instanceof ProductAdvertisingAPIClientException ) {
			$errors = $e->getResponseObject()->getErrors();
			foreach ( $errors as $error ) {
				$sError .= $error->getCode() . ' / ' . $error->getMessage() . "\n";
			}
		} else {
			$sError .= $e->getCode() . ' / ' . $e->getMessage();
			$sError .= "\n" . $e->getResponseBody();
		}
		update_option( 'bowsxWpApnError', trim( $sError ) );
	} catch ( Exception $e ) {
		if ( ! is_admin() ) {
			return false;
		}
		update_option( 'bowsxWpApnError', 'PA-API5 Error: ' . trim( $e->getMessage() ) );
	}

	return false;
}

function paapi5_getAvailableVariation( $sAsin, $cc = 'de' ) {
	global $__amazilonApiCalls;
	global $wpdb;
	global $__amazilonNoAutoVariant;

	$append = $cc != 'de' ? '-' . $cc : '';
	if ( ( $config = get_option( 'bowsxWpApn' ) ) === false || empty( $config[ 'publicKey' . $append ] ) || empty( $config[ 'privateKey' . $append ] ) || empty( $config[ 'associateTag' . $append ] ) ) {
		return false;
	}

	$apiConfig = new Configuration();
	$apiConfig->setAccessKey( trim( $config['publicKey'] ) );
	$apiConfig->setSecretKey( trim( $config['privateKey'] ) );
	$partnerTag = trim( $config['associateTag'] );
	switch ( $cc ) {
		case 'com':
			$apiConfig->setHost( 'webservices.amazon.com' );
			$apiConfig->setRegion( 'us-east-1' );
			break;
		case 'es':
			$apiConfig->setHost( 'webservices.amazon.es' );
			$apiConfig->setRegion( 'eu-west-1' );
			break;
		case 'co.uk':
			$apiConfig->setHost( 'webservices.amazon.co.uk' );
			$apiConfig->setRegion( 'eu-west-1' );
			break;
		default:
			$apiConfig->setHost( 'webservices.amazon.de' );
			$apiConfig->setRegion( 'eu-west-1' );
	}

	$apiInstance = new DefaultApi( new GuzzleHttp\Client(), $apiConfig );
	$resources   = array(
		GetItemsResource::OFFERSLISTINGSPRICE,
	);

	$getVariationsRequest = new GetVariationsRequest();
	$getVariationsRequest->setASIN( $sAsin );
	$getVariationsRequest->setPartnerTag( $partnerTag );
	$getVariationsRequest->setPartnerType( PartnerType::ASSOCIATES );
	$getVariationsRequest->setResources( $resources );
	$getVariationsRequest->setCondition( 'New' );

	$invalidPropertyList = $getVariationsRequest->listInvalidProperties();
	$length              = count( $invalidPropertyList );
	if ( $length > 0 ) {
		return false;
	}

	try {
		$getVariationsResponse = $apiInstance->getVariations( $getVariationsRequest );
		if ( $getVariationsResponse == null ) {
			return $returnFail;
		}
		if ( $getVariationsResponse->getVariationsResult() != null ) {
			if ( $getVariationsResponse->getVariationsResult()->getItems() != null ) {
				$responseList = $getVariationsResponse->getVariationsResult()->getItems();
				if ( count( $responseList ) < 1 ) {
					return $returnFail;
				}
				for ( $i = 0; $i < count( $getVariationsResponse->getVariationsResult()->getItems() ); $i ++ ) {
					$oItem = $getVariationsResponse->getVariationsResult()->getItems()[ $i ];
					if ( $oItem->getOffers() != null && $oItem->getOffers()->getListings() != null && count( $oItem->getOffers()->getListings() ) > 0 ) {
						return $oItem->getAsin();
					}
				}
			}
		}

		return $sAsin;
	} catch ( ApiException $e ) {
		if ( ! is_admin() ) {
			return false;
		}
		$sError = 'PA-API5 Error: ';
		if ( $e->getResponseObject() instanceof ProductAdvertisingAPIClientException ) {
			$errors = $e->getResponseObject()->getErrors();
			foreach ( $errors as $error ) {
				$sError .= $error->getCode() . ' / ' . $error->getMessage() . "\n";
			}
		} else {
			$sError .= $e->getCode() . ' / ' . $e->getMessage();
			$sError .= "\n" . $e->getResponseBody();
		}
		update_option( 'bowsxWpApnError', trim( $sError ) );
	} catch ( Exception $e ) {
		if ( ! is_admin() ) {
			return false;
		}
		update_option( 'bowsxWpApnError', 'PA-API5 Error: ' . trim( $e->getMessage() ) );
	}

	return $sAsin;
}

function paapi5_prepareItem( &$oItem ) {
	global $wpdb;
	$config = get_option( 'bowsxWpApn' );
	$return = array(
		'state'          => date( 'Y-m-d H:i:s' ),
		'asin'           => $oItem->getASIN(),
		'aBrowseNodes'   => array(),
		'title'          => __( 'Productinformation not retrievable', 'amazilon' ),
		'aFeatures'      => array(),
		'preis'          => array(
			'preis'    => false,
			'waehrung' => 'N/A',
			'discount' => false,
		),
		'streichpreis'   => array(
			'preis'    => false,
			'waehrung' => 'N/A',
		),
		'isPrime'        => false,
		'sReviewsIframe' => '',
		'fReviewsStars'  => false,
		'iReviewsCount'  => 0,
	);

	if ( isset( $config['bStatisticsAutoclear'] ) && $config['bStatisticsAutoclear'] == '1' ) {
		$wpdb->delete( $wpdb->prefix . 'wpapn_errors', array( 'asin' => $oItem->getASIN() ), array( '%s' ) );
	}

	if ( $oItem->getItemInfo() != null && $oItem->getItemInfo()->getTitle() != null && $oItem->getItemInfo()->getTitle()->getDisplayValue() != null ) {
		$return['title'] = $oItem->getItemInfo()->getTitle()->getDisplayValue();
	}
	if ( $oItem->getOffers() != null && $oItem->getOffers()->getListings() != null && count( $oItem->getOffers()->getListings() ) > 0 && $oItem->getOffers()->getListings()[0]->getPrice() != null ) {
		$oListing = $oItem->getOffers()->getListings()[0];
		if ( $oListing->getPrice()->getAmount() != null ) {
			$return['preis']['preis'] = (int) ( round( $oListing->getPrice()->getAmount(), 2 ) * 100 );
		}
		if ( $oListing->getPrice()->getCurrency() != null ) {
			$return['preis']['waehrung'] = $oListing->getPrice()->getCurrency();
		}
		if ( $oListing->getPrice()->getSavings() != null ) {
			$oSavings = $oListing->getPrice()->getSavings();
			if ( $oSavings->getAmount() != null ) {
				$return['preis']['discount'] = (int) ( round( $oSavings->getAmount(), 2 ) * 100 );
			}
			if ( $oListing->getSavingBasis() != null ) {
				$oSavingBasis = $oListing->getSavingBasis();
				if ( $oSavingBasis->getAmount() != null ) {
					$return['streichpreis']['preis'] = (int) ( round( $oSavingBasis->getAmount(), 2 ) * 100 );
				}
				if ( $oSavingBasis->getCurrency() != null ) {
					$return['streichpreis']['waehrung'] = $oSavingBasis->getCurrency();
				}
			}
		}
		if ( $oListing->getDeliveryInfo() != null && $oListing->getDeliveryInfo()->getIsPrimeEligible() != null ) {
			$return['isPrime'] = (int) $oListing->getDeliveryInfo()->getIsPrimeEligible();
		}
	} else {
		amazilonLogAdd( $oItem->getASIN(), $return['title'], __( 'Item not available', 'amazilon' ) );
	}

	if ( $oItem->getImages() != null ) {
		if ( $oItem->getImages()->getPrimary() != null && $oItem->getImages()->getPrimary()->getSmall() != null && $oItem->getImages()->getPrimary()->getMedium() != null && $oItem->getImages()->getPrimary()->getLarge() != null ) {
			$oPrimary            = $oItem->getImages()->getPrimary();
			$return['images'][0] = array(
				'small'  => $oPrimary->getSmall()->getURL() ? $oPrimary->getSmall()->getURL() : '',
				'medium' => $oPrimary->getMedium()->getURL() ? $oPrimary->getMedium()->getURL() : '',
				'large'  => $oPrimary->getLarge()->getURL() ? $oPrimary->getLarge()->getURL() : '',
			);
		}
		if ( $oItem->getImages()->getVariants() != null ) {
			$aVariants = $oItem->getImages()->getVariants();
			for ( $iVariant = 0; $iVariant < count( $aVariants ); $iVariant ++ ) {
				$oVariant = &$aVariants[ $iVariant ];
				array_push( $return['images'], array(
					'small'  => $oVariant->getSmall()->getURL() ? $oVariant->getSmall()->getURL() : '',
					'medium' => $oVariant->getMedium()->getURL() ? $oVariant->getMedium()->getURL() : '',
					'large'  => $oVariant->getLarge()->getURL() ? $oVariant->getLarge()->getURL() : '',
				) );
			}
		}
	}
	$return['sLink'] = $oItem->getDetailPageURL();
	if ( $oItem->getBrowseNodeInfo() != null && $oItem->getBrowseNodeInfo()->getBrowseNodes() != null ) {
		$aBrowseNodes = $oItem->getBrowseNodeInfo()->getBrowseNodes();
		for ( $iNode = 0; $iNode < count( $aBrowseNodes ); $iNode ++ ) {
			$oBrowseNode = &$aBrowseNodes[ $iNode ];
			array_push( $return['aBrowseNodes'], array(
				'name' => $oBrowseNode->getContextFreeName(),
				'id'   => $oBrowseNode->getId(),
			) );
		}
	}

	if ( $oItem->getItemInfo() != null && $oItem->getItemInfo()->getFeatures() != null && $oItem->getItemInfo()->getFeatures()->getDisplayValues() != null ) {
		$return['aFeatures'] = $oItem->getItemInfo()->getFeatures()->getDisplayValues();
	}

	/**
	 *  Reviews ggf. über https://www.amazon.de/product-reviews/ASIN/ abrufbar
	 */
	return $return;
}

function paapi5_searchItems( $sKeyword, $sIndex = 'All', $iLimit = 10 ) {
	global $__amazilonApiCalls;
	global $wpdb;

	if ( ( $config = get_option( 'bowsxWpApn' ) ) === false || empty( $config['publicKey'] ) || empty( $config['privateKey'] ) || empty( $config['associateTag'] ) ) {
		return false;
	}

	$apiConfig = new Configuration();
	$apiConfig->setAccessKey( trim( $config['publicKey'] ) );
	$apiConfig->setSecretKey( trim( $config['privateKey'] ) );
	$partnerTag = trim( $config['associateTag'] );
	$apiConfig->setHost( 'webservices.amazon.de' );
	$apiConfig->setRegion( 'eu-west-1' );

	$apiInstance = new DefaultApi(
		new GuzzleHttp\Client(), $apiConfig
	);
	$searchIndex = $sIndex;
	$resources   = array(
		SearchItemsResource::ITEM_INFOTITLE,
		SearchItemsResource::OFFERSLISTINGSPRICE,
		SearchItemsResource::OFFERSSUMMARIESLOWEST_PRICE,
		SearchItemsResource::OFFERSLISTINGSSAVING_BASIS,
		SearchItemsResource::OFFERSLISTINGSDELIVERY_INFOIS_PRIME_ELIGIBLE,
		SearchItemsResource::IMAGESPRIMARYSMALL,
		SearchItemsResource::IMAGESPRIMARYMEDIUM,
		SearchItemsResource::IMAGESPRIMARYLARGE,
		SearchItemsResource::IMAGESVARIANTSSMALL,
		SearchItemsResource::IMAGESVARIANTSMEDIUM,
		SearchItemsResource::IMAGESVARIANTSLARGE,
		SearchItemsResource::BROWSE_NODE_INFOBROWSE_NODES,
		SearchItemsResource::OFFERSSUMMARIESOFFER_COUNT,
		SearchItemsResource::ITEM_INFOFEATURES,
	);

	# Forming the request
	$searchItemsRequest = new SearchItemsRequest();
	$searchItemsRequest->setSearchIndex( $searchIndex );
	$searchItemsRequest->setKeywords( $sKeyword );
	$searchItemsRequest->setItemCount( 10 ); # PA-API5 Bug: Must be set to 10 (instead of something between 1 and 10)
	$searchItemsRequest->setPartnerTag( $partnerTag );
	$searchItemsRequest->setPartnerType( PartnerType::ASSOCIATES );
	$searchItemsRequest->setResources( $resources );
	$searchItemsRequest->setMinReviewsRating( 4 );

	# Validating request
	$invalidPropertyList = $searchItemsRequest->listInvalidProperties();
	$length              = count( $invalidPropertyList );
	if ( $length > 0 ) {
		return false;
	}

	$return = array();
	try {
		$searchItemsResponse = $apiInstance->searchItems( $searchItemsRequest );
		if ( $searchItemsResponse->getSearchResult() != null && $searchItemsResponse->getSearchResult()->getItems() != null ) {
			$aItems = $searchItemsResponse->getSearchResult()->getItems();
			for ( $iItem = 0; $iItem < count( $aItems ) && $iItem < $iLimit; $iItem ++ ) {
				array_push( $return, paapi5_prepareItem( $aItems[ $iItem ] ) );
			}

			return $return;
		}
	} catch ( ApiException $e ) {
		if ( ! is_admin() ) {
			return false;
		}
		$sError = 'PA-API5 Error: ' . $e->getCode() . ' / ' . $e->getMessage();
		if ( $e->getResponseObject() instanceof ProductAdvertisingAPIClientException ) {
			$errors = $e->getResponseObject()->getErrors();
			foreach ( $errors as $error ) {
				$sError .= "\n" . $error->getCode() . ' / ' . $error->getMessage();
			}
		} else {
			$sError .= "\n" . $e->getResponseBody();
		}
		update_option( 'bowsxWpApnError', $sError );
	} catch ( Exception $e ) {
		if ( ! is_admin() ) {
			return false;
		}
		update_option( 'bowsxWpApnError', 'PA-API5 Error: ' . $e->getMessage() );
	}

	return false;
}
