
import base64
import json
import os
from datetime import date

import requests
from requests.auth import HTTPBasicAuth

from configs.firebase import db
from functions.Etsy.Orders import getCountriesFromDb
from functions.Storage import get_file_path, upload_blob
from V2.functions.Address.main import Address
from V2.functions.Applications.main import Application
from V2.functions.Orders.main import Order
from V2.functions.Shipments.main import Shipment
from V2.middlewares.auth import API_Error


def shipNowShipstation(uid:str,order:Order, app:Application, fromAddress:Address, carrierId:str, serviceId:str, parcel:dict, packageId = "package"):
    toAddress = Address.from_dict(order.shippingAddress)
    toCountry = toAddress.country
    if toCountry in ["United States", "US", "United States of America"]: toAddress.country = "US"
    else: 
        toAddress.country = [c.get("code") for c in getCountriesFromDb().values() if c.get('name') == toCountry]
        if toAddress.country: toAddress.country = toAddress.country[0]
        else: toAddress.country = "US"
    if carrierId == "ups": carrierId = "ups_walleted"
    fromName = order.shopName if order.shopName else fromAddress.name
    if " " not in fromName: fromName = "Shipping Department"
    fromAddress  = dict(
                name=fromName,
                street1 = fromAddress.address1,
                street2 = fromAddress.address2,
                city = fromAddress.city,
                state = fromAddress.state,
                postalCode = fromAddress.zip,
                country = fromAddress.countryCode if fromAddress.countryCode else fromAddress.country,
                phone = fromAddress.phone,
                company= order.shopName if order.shopName else fromAddress.company,
            )
    toAddress  = dict(
                name=toAddress.name,
                street1 = toAddress.address1,
                street2 = toAddress.address2,
                city = toAddress.city,
                state = toAddress.state,
                postalCode = toAddress.zip,
                country = toAddress.country,
                phone = toAddress.phone,
                company= toAddress.name if toAddress.name else toAddress.company,
            )
    # print(fromAddress, toAddress)
    dimensions = dict(
            length=parcel.get('length'),
            width=parcel.get('width'),
            height=parcel.get('height'),
            units="inches"
        )
    if packageId == "letter":
        dimensions = dict(
            length=4,
            width=6,
            height=0.025,
            units="inches"
        )
    res = requests.post(
        'https://ssapi.shipstation.com/shipments/createlabel', 
        auth = HTTPBasicAuth(app.apiKey, app.apiSecret),
        headers={"Content-Type": "application/json"},
        data=json.dumps(dict(
        carrierCode=carrierId,
        weight=dict(
            value=parcel.get('weight'),
            units="grams" if app.enterpriseId == "3vRxw0HKksLTyVzsN83d" else "ounces" 
        ),
        dimensions=dimensions,
        serviceCode = serviceId,
        packageCode=packageId,
        shipDate=date.today().isoformat(),
        shipFrom=fromAddress,
        shipTo=toAddress,
        internationalOptions = dict(
            nonDelivery="treat_as_abandoned",
            contents = "merchandise",
            customsItems= [
                dict(
                    description = "unisex printed t shirts",
                    quantity=1,
                    value=10,
                    harmonizedTariffCode=640411,
                    countryOfOrigin="US"
                )
        ]
        ) if identify_address(toAddress) else None
    )))
    if res.status_code == 200:
        shipment = res.json()
        labelData = shipment.get('labelData')
        file_path = get_file_path(f"{shipment.get('shipmentId')}.pdf")
        with open(file_path, "wb") as file:
            file.write(base64.b64decode(str(labelData)))
        label = upload_blob(
            file_path, f"users/{uid}/shipments/{shipment.get('shipmentId')}.pdf")
        os.remove(file_path)
        shipment = Shipment(
            uid=uid,
            enterpriseId=app.enterpriseId,
            platformId="SHIPSTATION",
            platformName= "ShipStation",
            orderId=order.id,
            platformOrderId=order.platformOrderId,
            image=None,
            platformShipmentId=shipment.get('shipmentId'),
            carrierName= shipment.get('carrierCode'),
            carrierService= shipment.get('serviceCode'),
            cost=shipment.get('shipmentCost'),
            pdf=label,
            trackingCode= shipment.get('trackingNumber'),
            userUid= order.uid,
            routedOrderIds = order.routedOrderIds,
            trackingUrl=shipment.get('trackingURL', None),
        )
        return shipment
    raise API_Error(res.text, res.status_code)


def identify_address(address):
    us_identifiers = ['United States', 'USA', 'US']
    military_states = ['Armed Forces Pacific', 'AP', 'Armed Forces Europe', 'AE', 'Armed Forces Americas', 'AA']
    if address.get('country', '').strip() not in us_identifiers: return True
    if address.get('state', '').strip() in military_states: return True
    if 'APO' in address.get('address1', '') or 'FPO' in address.get('address2', '') or 'DPO' in address.get('addresss', ''): return True
    return False