import base64
import json
import os
from datetime import date

import requests
from requests.auth import HTTPBasicAuth

from configs.firebase import SANDBOX
from functions.Etsy.Orders import getCountriesFromDb
from functions.Response import API_Error
from functions.Shipments.Convert import (convertCarrier, convertRate,
                                         getShipmentPlatformCreds,
                                         saveShipment)
from functions.Storage import get_file_path, upload_blob


def getCarriers(enterpriseId: str):
    creds = getShipmentPlatformCreds(enterpriseId, "MACHSHIP")
    carriers: list[dict] = []
    if creds:
        if creds.get("enabled") == False:
            return carriers
        try:
            url = "https://live.machship.com/apiv2/companies/getAll"
            # Use token in header instead of HTTPBasicAuth
            headers = {
                "accept": "text/plain",
                "token": creds.get("apiKey")
                or "faw4y7vQj0CG6SKhX17OsgU2vwirRkXU_DIYOzFEAcAw",
            }
            res = requests.get(url, headers=headers)

            if res.status_code == 200:
                response_data = res.json()
                # Handle the new response format with 'object' array
                if "object" in response_data and isinstance(
                    response_data["object"], list
                ):
                    carrier_list = response_data["object"]
                    carriers = [
                        convertCarrier(
                            id=carrier.get("id"),
                            platformId="MACHSHIP",
                            platformName="Machship",
                            name=carrier.get("name"),
                            description=carrier.get("displayName"),
                        )
                        for carrier in carrier_list
                    ]
                else:
                    # Fallback to the old format if 'object' key is not present
                    carriers = [
                        convertCarrier(
                            id=carrier.get("id"),
                            platformId="MACHSHIP",
                            platformName="Machship",
                            name=carrier.get("name"),
                            description=carrier.get("displayName"),
                        )
                        for carrier in response_data
                    ]
            else:
                print(res.text, res.status_code)

        except Exception as e:
            print(e)

    return carriers


def getServices(enterpriseId: str, companyId: str):
    """Fetch available carrier accounts and services from MachShip API."""

    # Retrieve credentials for the shipment platform
    creds = getShipmentPlatformCreds(enterpriseId, "MACHSHIP")
    services: list[dict] = []

    if not creds:
        print("No credentials found for MACHSHIP.")
        return services

    try:
        url = f"https://live.machship.com/apiv2/companies/getAvailableCarriersAccountsAndServices?companyId={companyId}"

        # Use token in header instead of HTTPBasicAuth
        headers = {
            "accept": "text/plain",
            "token": creds.get("apiKey")
            or "faw4y7vQj0CG6SKhX17OsgU2vwirRkXU_DIYOzFEAcAw",
        }
        res = requests.get(url, headers=headers)

        if res.status_code == 200:
            services = res.json()
            print("Successfully fetched services:", services)
        else:
            print(f"Error fetching services: {res.status_code} - {res.text}")

    except requests.RequestException as e:
        print(f"Request failed: {e}")

    return services


def getRates(
    enterpriseId: str,
    fromAddress: dict,
    order: dict,
    parcel: dict,
    companyId: str,
    packageCode: str = None,
):
    """Get shipping rates for a given order from MachShip API."""

    # Retrieve credentials for the shipment platform
    creds = getShipmentPlatformCreds(enterpriseId, "MACHSHIP")
    rates = []

    if not creds:
        print("No credentials found for MACHSHIP.")
        return rates

    try:
        toCountry, toZip = order.get("shippingAddress").get("country"), order.get(
            "shippingAddress"
        ).get("zip")

        # Convert country names to country codes
        if toCountry in ["United States", "United States of America"]:
            toCountry = "US"
        elif len(toCountry) != 2:
            countries = [
                c.get("code")
                for c in getCountriesFromDb().values()
                if c.get("name") == toCountry
            ]
            if countries:
                toCountry = countries[0]

        # Define dimensions for the parcel
        dimensions = dict(
            length=parcel.get("length"),
            width=parcel.get("width"),
            height=parcel.get("height"),
            units="inches",
        )

        # Define dimensions for letter parcels
        if packageCode == "letter":
            dimensions = dict(length=4, width=6, height=0.025, units="inches")

        # Make the API request with the token header authentication
        url = f"https://live.machship.com/apiv2/quotes/getAll?companyId={companyId}"
        headers = {
            "accept": "text/plain",
            "token": creds.get("apiKey")
            or "faw4y7vQj0CG6SKhX17OsgU2vwirRkXU_DIYOzFEAcAw",
        }
        res = requests.post(
            url,
            headers=headers,
            json=dict(
                carrierCode=companyId,
                fromPostalCode=fromAddress.get("zip"),
                toCountry=toCountry,
                toPostalCode=toZip,
                dimensions=dimensions,
            ),
        )

        if res.status_code == 200:
            rates = res.json()
            print("Successfully fetched rates:", rates)
        else:
            print(f"Error fetching rates: {res.status_code} - {res.text}")

    except requests.RequestException as e:
        print(f"Request failed: {e}")

    return rates


def createShipment(
    enterpriseId: str,
    order: dict,
    fromAddress: dict,
    toAddress: dict,
    parcel: dict,
    rate: dict
):
    companyId, serviceId, rateId = rate.get("carrierId"), rate.get("serviceId"), rate.get("rateId")
    """Create a shipment for an order with MachShip API."""

    # Retrieve credentials for the shipment platform
    creds = getShipmentPlatformCreds(enterpriseId, "MACHSHIP")
    shipment = None

    if not creds:
        print("No credentials found for MACHSHIP.")
        return shipment

    try:
        # Define the shipment payload
        shipment = dict(
            carrierCode=companyId,
            serviceCode=serviceId,
            quoteId=rateId,
            consignmentReference=order.get("orderId"),
            consignmentItems=[
                dict(
                    itemDescription=parcel.get("description", "Parcel"),
                    itemQuantity=1,
                    itemWeight=parcel.get("weight"),
                    itemLength=parcel.get("length"),
                    itemWidth=parcel.get("width"),
                    itemHeight=parcel.get("height"),
                )
            ],
            consignmentAddresses=[
                dict(
                    addressType="From",
                    addressLine1=fromAddress.get("address1"),
                    addressLine2=fromAddress.get("address2"),
                    suburb=fromAddress.get("city"),
                    state=fromAddress.get("state"),
                    postcode=fromAddress.get("zip"),
                    country=fromAddress.get("country"),
                    contactName=fromAddress.get("name"),
                    contactPhone=fromAddress.get("phone"),
                ),
                dict(
                    addressType="To",
                    addressLine1=toAddress.get("address1"),
                    addressLine2=toAddress.get("address2"),
                    suburb=toAddress.get("city"),
                    state=toAddress.get("state"),
                    postcode=toAddress.get("zip"),
                    country=toAddress.get("country"),
                    contactName=toAddress.get("name"),
                    contactPhone=toAddress.get("phone"),
                ),
            ],
        )

        # Make the API request with token header authentication
        url = "https://live.machship.com/apiv2/consignments/createConsignment"
        headers = {
            "accept": "text/plain",
            "token": creds.get("apiKey")
            or "faw4y7vQj0CG6SKhX17OsgU2vwirRkXU_DIYOzFEAcAw",
        }
        res = requests.post(url, headers=headers, json=shipment)

        if res.status_code == 200:
            shipment = res.json()
            print("Successfully created shipment:", shipment)
        else:
            print(f"Error creating shipment: {res.status_code} - {res.text}")

    except requests.RequestException as e:
        print(f"Request failed: {e}")

    return shipment
