import datetime
import time
import typing

from conio_sdk.generated_protobuf import v1_pb2
from test.integration.v1.base_integration_test import BaseV1IntegrationTest


class TestPrice(BaseV1IntegrationTest):
    def test_current_price(self):
        signup_response = self.signin_with_new_user()
        authentication_headers = signup_response.authentication_headers
        before = int(time.time() * 1000)
        price_point = self.get_current_price(authentication_headers)
        after = int(time.time() * 1000)
        self.assertGreaterEqual(price_point.timestamp, before)
        self.assertGreaterEqual(after, price_point.timestamp)
        self.assertGreater(price_point.buy_price, price_point.sell_price)
        price_point_2 = self.get_current_price(authentication_headers)
        self.assertAlmostEqual(
            price_point.buy_price, price_point_2.buy_price,
            delta=0.1
        )
        self.assertAlmostEqual(
            price_point.sell_price, price_point_2.sell_price,
            delta=0.1
        )

    def test_history_prices(self):
        signup_response = self.signin_with_new_user()
        authentication_headers = signup_response.authentication_headers
        self._check_history_prices(
            self.get_historical_prices(
                authentication_headers,
                int((datetime.datetime.now() - datetime.timedelta(days=1)).timestamp() * 1000),
                int(datetime.datetime.now().timestamp() * 1000),
                interval=3600000
            ),
            24,
            expected_interval=3600000)

    # Condex does not support this use case
    # def test_history_prices_no_interval(self):
    #     signup_response = self.signin_with_new_user()
    #     authentication_headers = signup_response.authentication_headers
    #     self._check_history_prices(
    #         self.get_historical_prices(
    #             authentication_headers,
    #             int((datetime.datetime.now() - datetime.timedelta(days=10)).timestamp() * 1000),
    #             int(datetime.datetime.now().timestamp() * 1000)
    #         ),
    #         10,
    #         expected_interval=24 * 3600 * 1000
    #     )

    def _check_history_prices(
            self, historical_prices: v1_pb2.MsgHistoryPricesResponse,
            expected_len: int,
            expected_interval: typing.Optional[int] = None):

        self.assertEqual(expected_len, len(historical_prices.price_points))
        last_price = None
        found_a_buy_point_greater_than_0 = found_a_sell_point_greater_than_0 = False
        for cur_price in historical_prices.price_points:
            print(str(cur_price))
            if last_price and expected_interval:
                self.assertEqual(expected_interval, cur_price.timestamp - last_price.timestamp)
            last_price = cur_price
            found_a_buy_point_greater_than_0 |= cur_price.buy_price > 0
            found_a_sell_point_greater_than_0 |= cur_price.sell_price > 0
            found_a_sell_point_greater_than_0 and self.assertGreater(cur_price.sell_price, 0)
            found_a_buy_point_greater_than_0 and self.assertGreater(cur_price.buy_price, 0)
            found_a_buy_point_greater_than_0 and found_a_sell_point_greater_than_0 and self.assertGreater(cur_price.buy_price, cur_price.sell_price)
        self.assertEqual(
            historical_prices.price_analytics.delta_fiat * 100,
            int(historical_prices.price_analytics.delta_fiat * 100)
        )
        self.assertEqual(
            historical_prices.price_analytics.delta_percentage * 100,
            int(historical_prices.price_analytics.delta_percentage * 100)
        )
