import requests
from apps.shipping.abstract_shipping import AbstractShipping
from oscar.apps.shipping.methods import Free
from django.utils import timezone
from apps.shipping import settings as ship_settings
import simplejson as json
import logging
from hookcoffee.pdf_settings import *
import io
from apps.shipping.exceptions import ShippingApiError
from django.utils.text import mark_safe

logger = logging.getLogger('shipping')


class Janio(Free, AbstractShipping):
    name = 'Janio'
    code = 'janio'
    description = 'Express delivery with tracking'

    # Janio API Stuff
    endpoint = settings.JANIO_ENDPOINT
    secret_key = settings.JANIO_API_KEY

    def _create_waybill_number(self, order):
        return 'hook{}{}'.format(str(order.number).replace('-', ''), timezone.localdate().strftime('%Y%m%d'))

    def _create_ship_line_items(self, order):
        ret = []
        for line in order.lines.all():
            ret.append({
                'item_desc': line.product.get_title(),
                'item_category': "Others",
                'item_product_id': line.product.pk,
                'item_quantity': line.quantity,
                'item_price_value': line.line_price_excl_tax,
                'item_price_currency': line.stockrecord.price_currency
            })
        return ret

    def _prep_json(self, order):
        return {
            "secret_key": self.secret_key,
            "orders": [
                {
                    "service_id": 26,
                    "tracking_no": self._create_waybill_number(order),
                    "shipper_order_id": order.number,
                    "consignee_name": order.user.get_full_name(),
                    "consignee_address": order.shipping_address.line1 + " " + order.shipping_address.line2,
                    "consignee_postal": order.shipping_address.postcode,
                    "consignee_email": order.user.email,
                    "consignee_country": order.shipping_address.country.printable_name,
                    "consignee_state": order.shipping_address.state,
                    "consignee_number": str(order.shipping_address.phone_number),
                    "order_length": 15,
                    "order_width": 15,
                    "order_height": 5,
                    "order_weight": float(order.get_total_weight()) / 1000,
                    "pickup_country": ship_settings.SENDER_COUNTRY_NAME,
                    "pickup_address": "{}, {} {}, {}".format(
                        ship_settings.SENDER_COMPANY_NAME,
                        ship_settings.SENDER_UNIT_NUMBER,
                        ship_settings.SENDER_STREET_1,
                        ship_settings.SENDER_COUNTRY_NAME
                    ),
                    "pickup_postal": ship_settings.SENDER_POSTAL_CODE,
                    "payment_type": "prepaid",
                    "items": self._create_ship_line_items(order)
                }
            ]
        }

    def get_waybill_pdf(self, waybill, order=None):
        data = {'secret_key': self.secret_key, 'shipper_order_id': order.number, "service_id": 26}
        res = requests.get(self.endpoint.format('order/order'), data)
        if res.status_code == 200:
            details = res.json()
            try:
                print_urls = details['results'][0]['print_urls']
                if len(print_urls):
                    pdf_content = requests.get(print_urls[0]).content
                    return io.BytesIO(pdf_content).getvalue()
                else:
                    return None
            except Exception as e:
                return None

    def process_shipment(self, order):
        res = requests.post(
            self.endpoint.format('order/orders/'),
            data=json.dumps(self._prep_json(order)),
            headers={'Content-Type': 'application/json'}
        )

        logger.debug('Janio response status code : {}'.format(res.status_code))
        if res.status_code in [200, 201]:
            shipment_details = res.json()
            tracking_id = shipment_details['tracking_nos'][0]
            return tracking_id
        else:
            logger.error('Janio returned an error : {} '.format(res.text))
            raise ShippingApiError(res.text)

    def tracking_url(self):
        url = '<a href="https://tracker.janio.asia/" target="_blank">Track your order</a>'
        return mark_safe(url)

    def tracking_available(self):
        return True


__shipping_method_class__ = Janio
