import requests
from .project import Project

import logging
logger = logging.getLogger(__name__)

def uploadOrder(project: Project, host: str, token: str) -> None:
    """
    Uploads an order to a MillConnect server.

    Parameters
    ----------
    project : Project
        The project containing the order data.
    host : str
        The URL of the MillConnect server.
    token : str
        A valid authentication token for the MillConnect server.

    Returns
    -------
    None

    See Also
    --------
    millconnect.backend.Project
    """
    orderData = {
        'projectName': project.order['projectName'],
        'deliveryType': project.order['deliveryType'],
        'comment': project.order['comment'],
        'creationMethod': 'client',
        'fastline': project.order['fastline'],
        'alternativeDeliveryAddress': project.order['alternativeDeliveryAddress'] if project.order['alternativeDeliveryAddress'] else ''
    }

    files = {}

    if project.dentalProjectPath:
        files['dentalProject'] = project.dentalProjectPath.open('rb')

    if project.constructionInfoPath:
        files['constructionInfo'] = project.constructionInfoPath.open('rb')

    if project.sceneFilePresent and project.order['isAIO']:
        files['sceneFile'] = project.sceneFilePath.open('rb')
        if project.lowerJaw:
            files['lowerJaw'] = project.lowerJaw.open('rb')
        if project.upperJaw:
            files['upperJaw'] = project.upperJaw.open('rb')

    if project.modelInfoPath:
        files['modelInfo'] = project.modelInfoPath.open('rb')

    if project.partialInfoPath:
        files['partialInfo'] = project.partialInfoPath.open('rb')

    if project.scanInfoPath:
        files['scanInfo'] = project.scanInfoPath.open('rb')

    if project.threeshapePath:
        files['threeshape'] = project.threeshapePath.open('rb')

        # add point files compressed as zip
        pointFiles = project.getPoints()
        pointFiles += project.getImplantDirectionFiles()
        if len(pointFiles) > 0:
            compressedPoints = project.compressFiles(pointFiles)
            files['threeshapePoints'] = compressedPoints

    headers = {
        'Authorization': f'Token {token}'
    }
    response = requests.post(f'{host}/orders/', data=orderData, files=files, headers=headers)
    response.raise_for_status()
    newOrder = response.json()

    for element in project.order['elements']:
        elementData = {
            'type': element['type'] if element['type'] else '',
            'material': element['material'],
            'color': element['color'],
            'height': element['height'],
            'comment': element['comment'],
        }
        files = {
            'file': project.getFile(element['file']).open('rb')
        }
        response = requests.post(f'{host}/orders/{newOrder['id']}/elements/', files=files, data=elementData, headers=headers)
        response.raise_for_status()
        newElement = response.json()

        for amenity in element['amenities']:
            amenityData = {
                'element': newElement['id'],
                'amenity': amenity
            }
            response = requests.post(f'{host}/orders/{newOrder['id']}/elements/{newElement['id']}/amenities/', data=amenityData, headers=headers)

        for tooth in element['teeth']:
            response = requests.post(f'{host}/orders/{newOrder['id']}/elements/{newElement['id']}/teeth/', json=tooth, headers=headers)
            response.raise_for_status()


    # mark the order to be ready
    data = {
        'ready': True
    }
    response = requests.patch(f'{host}/orders/{newOrder['id']}/', json=data, headers=headers)
    response.raise_for_status()