import base64
import requests
from datetime import datetime, timedelta
import pytz
from flask import current_app

ZAGREB_TZ = pytz.timezone('Europe/Zagreb')
DHL_API_BASE = 'https://express.api.mydhlapi.com'


def _pickup_datetime() -> str:
    """Calculate next DHL pickup slot in Zagreb time (14:00 cutoff)."""
    now = datetime.now(ZAGREB_TZ)
    cutoff = now.replace(hour=14, minute=0, second=0, microsecond=0)
    if now < cutoff:
        pickup = cutoff
    else:
        pickup = (now + timedelta(days=1)).replace(hour=14, minute=0, second=0, microsecond=0)
        while pickup.weekday() >= 5:  # skip Saturday (5) and Sunday (6)
            pickup += timedelta(days=1)
    return pickup.strftime('%Y-%m-%dT%H:%M:%S GMT+01:00')


def create_shipment(order_number: str, recipient: dict, items: list,
                    invoice_number: str = None, total_amount=None,
                    currency: str = 'EUR', weight_kg: float = 0.5,
                    is_eu: bool = True):
    """Create a DHL Express shipment.

    Args:
        order_number: e-računi order number
        recipient: dict with keys name, street, postal_code, city, country,
                   and optionally email, phone
        items: list of item dicts (productName, price, quantity)
        invoice_number: invoice number for customs (non-EU only)
        total_amount: total shipment value
        currency: currency code
        weight_kg: total package weight in kg
        is_eu: True if destination is within EU (no export declaration needed)

    Returns:
        (tracking_number: str, zpl_bytes: bytes)
    """
    cfg = current_app.config
    is_international = not is_eu and recipient.get('country', 'HR') != 'HR'

    payload = {
        "plannedShippingDateAndTime": _pickup_datetime(),
        "pickup": {"isRequested": False},
        "productCode": "P",
        "accounts": [{"typeCode": "shipper", "number": cfg['DHL_ACCOUNT_NUMBER']}],
        "outputImageProperties": {
            "printerDPI": 203,
            "encodingFormat": "ZPL2",
            "imageOptions": [
                {
                    "typeCode": "label",
                    "templateName": "ECOM26_84_001",
                    "isRequested": True,
                }
            ],
        },
        "customerDetails": {
            "shipperDetails": {
                "postalAddress": {
                    "addressLine1": cfg['DHL_SHIPPER_STREET'],
                    "cityName": cfg['DHL_SHIPPER_CITY'],
                    "postalCode": cfg['DHL_SHIPPER_POSTAL'],
                    "countryCode": cfg['DHL_SHIPPER_COUNTRY'],
                },
                "contactInformation": {
                    "fullName": cfg['DHL_SHIPPER_NAME'],
                    "email": cfg['DHL_SHIPPER_EMAIL'],
                    "phone": cfg['DHL_SHIPPER_PHONE'],
                },
            },
            "receiverDetails": {
                "postalAddress": {
                    "addressLine1": recipient['street'],
                    "cityName": recipient['city'],
                    "postalCode": recipient['postal_code'],
                    "countryCode": recipient['country'],
                },
                "contactInformation": {
                    "fullName": recipient['name'],
                    "email": recipient.get('email', ''),
                    "phone": recipient.get('phone', ''),
                },
            },
        },
        "content": {
            "packages": [
                {
                    "weight": weight_kg,
                    "dimensions": {"length": 10, "width": 10, "height": 10},
                }
            ],
            "isCustomsDeclarable": is_international,
            "description": f"Order {order_number}",
            "incoterm": "EXW" if is_eu else "DAP",
            "unitOfMeasurement": "metric",
        },
    }

    if is_international and invoice_number:
        payload['content']['exportDeclaration'] = {
            "lineItems": [
                {
                    "number": i + 1,
                    "description": item.get('description') or item.get('productName') or 'Electronics',
                    "price": float(item.get('price', 0)),
                    "quantity": {
                        "value": int(item.get('quantity', 1)),
                        "unitOfMeasurement": "PCS",
                    },
                    "commodityCodes": [
                        {"typeCode": "outbound", "value": "85340090"}
                    ],
                    "exportReasonType": "permanent",
                    "manufacturerCountry": "HR",
                    "weight": {"netValue": 0.05, "grossValue": 0.1},
                }
                for i, item in enumerate(items)
            ],
            "invoice": {
                "number": invoice_number,
                "date": datetime.now().strftime('%Y-%m-%d'),
            },
            "exportReason": "permanent",
        }

    # DHL uses Basic auth with API key + empty password
    auth_bytes = f"{cfg['DHL_API_KEY']}:".encode()
    auth_header = f"Basic {base64.b64encode(auth_bytes).decode()}"
    headers = {
        "Authorization": auth_header,
        "Content-Type": "application/json",
    }

    resp = requests.post(
        f"{DHL_API_BASE}/shipments",
        json=payload,
        headers=headers,
        timeout=30,
    )
    resp.raise_for_status()
    data = resp.json()

    tracking = data['shipmentTrackingNumber']
    # Label comes as base64-encoded content in the documents array
    zpl_b64 = data['documents'][0]['content']
    zpl_bytes = base64.b64decode(zpl_b64)
    return tracking, zpl_bytes
