import sys
sys.path.append('../')

"""
Explanation: Simulation API
A merchant wants to offer products and maximize profits. Just like on a real online marketplace, he can look at all existing offers, add some own, restock or reprice. First, it has to order products from the producer, which comes with costs. All Pricewars entities are implemented as services, and their interfaces (REST) are described in detail here.
This notebook will present how to use the Pricewars APIs to do all these tasks easily. From registration to buying products, offering them and repricing them. Using this, it is possible to build a powerful merchant.
Note: The code is type-hinted, so using an IDE (e.g. PyCharm/IntelliJ or an IPython/Jupyter notebook) provides you with auto-completion.
If you want to try the following examples, make sure that the Pricewars plattform is running.
Either by deploying them individually or by using the docker setup.
The following step is specific for this notebook.
It is not necessary if your merchant is in the repository root.
End of explanation
"""


from api import Marketplace
marketplace = Marketplace()

"""
Explanation: Initialize Marketplace API
End of explanation
"""


registration = marketplace.register(
    'http://nobody:55000/',
    merchant_name='notebook_merchant',
    algorithm_name='human')

registration

"""
Explanation: If the marketplace doesn't run on the default URL, you can change it with the host argument
Register as merchant
In order to act on the marketplace, we need to be a registered merchant. Usually you use the Management UI to register a merchant and remember/keep the merchant_token. However, you can also use an API call.
You will also have to provie an API endpoint for your merchant, which will be called upon sales of products. We will simply use an invalid one, since this is only an example.
End of explanation
"""


offers = marketplace.get_offers()
offers

"""
Explanation: It was not possible to connect to the marketplace if you got the following error:
ConnectionError: HTTPConnectionPool(host='marketplace', port=8080)
In that case, make sure that the marketplace is running and host and port are correct.
If host or port are wrong, you can change it by creating a marketplace object with the host argument:
marketplace = Marketplace(host=www.another_host.com:1234)
Check offers on the market
End of explanation
"""


type(offers[0])

"""
Explanation: The result is a list of Offer objects.
End of explanation
"""


from api import Producer
producer = Producer(token=registration.merchant_token)

"""
Explanation: If you want a state-less merchant, you can set the argument include_empty_offers to True. This will add your own, but out-of-stock offers to be added to the response.
Initialize Producer API
To be able to call authenticated functions (like ordering products), we must provide our merchant token.
End of explanation
"""


order = producer.order(amount=10)
order

"""
Explanation: Order products
Order any amount of units of a product:
End of explanation
"""


type(order)

"""
Explanation: The order contains 10 units of a product.
The billing_amount is the total cost that the merchant must pay for this order.
End of explanation
"""


from models import Offer

price = 35
shipping_time = {'standard': 5, 'prime': 2}

offer = Offer.from_product(order.product, price, shipping_time)
offer

"""
Explanation: Add product to marketplace
To create a new offer, you need a product, a selling price for that offer and guaranteed shipping times.
Let's use a price of 35€ and any shipping times.
End of explanation
"""


offer = marketplace.add_offer(offer)
offer

"""
Explanation: Send the offer to the marketplace. The accepted offer with its new offer ID is returned.
End of explanation
"""


[market_offer for market_offer in marketplace.get_offers() if market_offer.offer_id == offer.offer_id][0]

"""
Explanation: Let's see, if we can find the new offer on the marketplace:
End of explanation
"""


offer.price = 28
marketplace.update_offer(offer)

[market_offer for market_offer in marketplace.get_offers() if market_offer.offer_id == offer.offer_id][0]

"""
Explanation: Update product on marketplace
Updating an offer, e.g. changing its price, is a limited API request. According to your simulation/marketplace settings, we can only call it N times per second.
End of explanation
"""


marketplace.unregister()

"""
Explanation: Unregister the merchant
You should keep your merchant and the token as long as possible, because it is the reference to all market data (sales, profit, marketshare), offers and products.
However, if you just try things out, like in this sample and don't want to pollute the database with lots of merchants, unregister it. This also removes all offers and products.
End of explanation
"""


from api.ApiError import ApiError

offer.price = 35
try:
    marketplace.update_offer(offer)
except ApiError as e:
    print("I can't do that")
    print(e)

"""
Explanation: Now, it shouldn't be possible to do authenticated actions.
End of explanation
"""


