import easypost

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.functions.Users.main import User
from V2.middlewares.auth import API_Error


def shipNowEasypost(user:User,app:Application,fromAddress:Address, order:Order, parcel:dict, carrierId=None, serviceId=None, returnAddress:Address=None) -> Shipment:
    if app:
        try:
            toAddress = Address.from_dict(order.shippingAddress)
            easypost.api_key = app.apiKey
            toAddress  = dict(
                name=toAddress.name,
                street1 = toAddress.address1,
                street2 = toAddress.address2,
                city = toAddress.city,
                state = toAddress.state,
                zip = toAddress.zip,
                country = toAddress.country,
                phone = toAddress.phone if toAddress.phone else fromAddress.phone,
                verify=False,
                verify_strict=False
            )
            fromAddress  = dict(
                name=order.shopName if order.shopName and user.enterpriseId != "60D7GFDlMFFd6IsK1e58" else fromAddress.name,
                company=order.shopName if order.shopName and user.enterpriseId != "60D7GFDlMFFd6IsK1e58" else fromAddress.company,
                street1 = fromAddress.address1,
                street2 = fromAddress.address2,
                city = fromAddress.city,
                state = fromAddress.state,
                zip = fromAddress.zip,
                country = fromAddress.country,
                phone = fromAddress.phone,
            )
            if returnAddress: returnAddress = dict(
                    name=returnAddress.name,
                    street1 = returnAddress.address1,
                    street2 = returnAddress.address2,
                    city = returnAddress.city,
                    state = returnAddress.state,
                    zip = returnAddress.zip,
                    country = returnAddress.country,
                    phone = returnAddress.phone if returnAddress.phone else "1111111111",
                )
            else: returnAddress = fromAddress
            # if order.id == "tSVO92hch4RdHv3YFroJ1695149061155_copy":
            #     fromAddress['street1'] = "6280 S VLY VIEW BLVD"
            #     fromAddress['zip'] = "89118-3891"
            #     fromAddress['city']= "LAS VEGAS"
            #     fromAddress['street2'] = "STE 340"
            #     fromAddress['state'] = "NV"
            shipment = easypost.Shipment.create(
                reference=order.id,
                to_address = toAddress,
                from_address = fromAddress,
                return_address= returnAddress,
                parcel = parcel,
                options=dict(label_size="4x6"),
                customs_info=easypost.CustomsInfo.create(
                    customs_items=[easypost.CustomsItem.create(
                    description = "Clothing",
                    quantity = "1",
                    weight= parcel.get('weight'),
                    value = order.grandTotal if order.grandTotal else 1,
                    origin_country = fromAddress.get('country'),
                    hs_tariff_number="610910"
                    )],
                eel_pfc='NOEEI 30.37(a)',
                contents_type='merchandise',
                restriction_type='none',
                restriction_comments='none',
                non_delivery_option="return",
                customs_certify='true',
                customs_signer="Adam Arizaga" if user.enterpriseId == "60D7GFDlMFFd6IsK1e58" else None,
                contents_explanation="",
                ),
            )
            rates:list[dict] = shipment.get('rates')
            if not rates: raise API_Error("No rates available", 500)
            if carrierId and serviceId:
                selectedRate = next((rate for rate in rates if rate.get('carrier') == carrierId and rate.get('service') == serviceId), None)
                if not selectedRate: raise API_Error(f"{carrierId} and {serviceId} are not available.")
            else:
                smartRates = easypost.Shipment.get_smartrates(shipment)
                smartRates = [rate for rate in smartRates if rate.get("service") == "Priority"]
                smartRates.sort(key=lambda x: float(x.get('rate')))
                selectedRate = smartRates[0]
            shipment = easypost.Shipment.buy(shipment, rate=selectedRate).to_dict()
            return Shipment(
                uid=user.uid,
                enterpriseId=user.enterpriseId,
                orderId= order.id,
                platformOrderId= order.platformOrderId,
                platformId="EASYPOST",
                platformName="EasyPost",
                image = shipment.get('postage_label', {}).get('label_url'),
                carrierName = shipment.get('selected_rate').get('carrier'),
                platformShipmentId= shipment.get('id'),
                pdf= shipment.get('postage_label', {}).get('label_pdf_url'),
                cost=shipment.get('selected_rate', {}).get('rate'), 
                trackingCode=shipment.get('tracking_code'),
                currency=shipment.get('selected_rate', {}).get('currency', 'USD'),
                carrierService= shipment.get('selected_rate', {}).get('service'),
                trackingUrl= shipment.get('tracker', {}).get('public_url'),
                userUid=user.uid,
                routedOrderIds = order.routedOrderIds if order.routedOrderIds else []
            )
        except Exception as e:
            print(e)
            raise API_Error(str(e))
    return []



def getSelectedRate(user:User,app:Application,fromAddress:Address, order:Order, parcel:dict, carrierId=None, serviceId=None, returnAddress:Address=None) -> Shipment:
    if app:
            toAddress = Address.from_dict(order.shippingAddress)
            easypost.api_key = app.apiKey
            toAddress  = dict(
                name=toAddress.name,
                street1 = toAddress.address1,
                street2 = toAddress.address2,
                city = toAddress.city,
                state = toAddress.state,
                zip = toAddress.zip,
                country = toAddress.country,
                phone = toAddress.phone if toAddress.phone else fromAddress.phone,
            )
            fromAddress  = dict(
                name=order.shopName if order.shopName and user.enterpriseId != "60D7GFDlMFFd6IsK1e58" else fromAddress.name,
                company=order.shopName if order.shopName and user.enterpriseId != "60D7GFDlMFFd6IsK1e58" else fromAddress.company,
                street1 = fromAddress.address1,
                street2 = fromAddress.address2,
                city = fromAddress.city,
                state = fromAddress.state,
                zip = fromAddress.zip,
                country = fromAddress.country,
                phone = fromAddress.phone,
            )
            if returnAddress: returnAddress = dict(
                    name=returnAddress.name,
                    street1 = returnAddress.address1,
                    street2 = returnAddress.address2,
                    city = returnAddress.city,
                    state = returnAddress.state,
                    zip = returnAddress.zip,
                    country = returnAddress.country,
                    phone = returnAddress.phone if returnAddress.phone else "1111111111",
                )
            else: returnAddress = fromAddress
            # if order.id == "tSVO92hch4RdHv3YFroJ1695149061155_copy":
            #     fromAddress['street1'] = "6280 S VLY VIEW BLVD"
            #     fromAddress['zip'] = "89118-3891"
            #     fromAddress['city']= "LAS VEGAS"
            #     fromAddress['street2'] = "STE 340"
            #     fromAddress['state'] = "NV"
            shipment = easypost.Shipment.create(
                reference=order.id,
                to_address = toAddress,
                from_address = fromAddress,
                return_address= returnAddress,
                parcel = parcel,
                options=dict(label_size="4x6"),
                customs_info=easypost.CustomsInfo.create(
                    customs_items=[easypost.CustomsItem.create(
                    description = "Clothing",
                    quantity = "1",
                    weight= parcel.get('weight'),
                    value = order.grandTotal if order.grandTotal else 1,
                    origin_country = fromAddress.get('country'),
                    hs_tariff_number="610910"
                    )],
                eel_pfc='NOEEI 30.37(a)',
                contents_type='merchandise',
                restriction_type='none',
                restriction_comments='none',
                non_delivery_option="return",
                customs_certify='true',
                customs_signer="Adam Arizaga" if user.enterpriseId == "60D7GFDlMFFd6IsK1e58" else None,
                contents_explanation="",
                ),
            )
            rates:list[dict] = shipment.get('rates')
            if not rates: raise API_Error("No rates available", 500)
            selectedRate = next((rate for rate in rates if rate.get('carrier') == carrierId and rate.get('service') == serviceId), None)
            if not selectedRate: raise API_Error(f"{carrierId} and {serviceId} are not available.")
            return selectedRate