# Copyright 2021 Studio73 - Ethan Hildick <ethan@studio73.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)..

import logging

import requests

from odoo import _
from odoo.exceptions import UserError

_logger = logging.getLogger(__name__)
CORREOS_EXPRESS_LABEL_TYPE = [("1", "PDF"), ("2", "ZPL")]
CORREOS_EXPRESS_SERVICE = [
    ("61", "PAQ10"),
    ("62", "PAQ14"),
    ("63", "PAQ24"),
    ("66", "BALEARES"),
    ("67", "CANARIAS EXPRES"),
    ("68", "CANARIAS AEREO"),
    ("69", "CANARIAS MARITIMO"),
    ("90", "INTERNACIONAL ESTANDAR"),
    ("91", "INTERNACIONAL EXPRES"),
    ("92", "PAQ EMPRESA 14"),
    ("93", "EPAQ24"),
    ("27", "CAMPAÑA CEX"),
    ("53", "53 ENTREGA + MANIPULACION LOINEX"),
    ("54", "54 ENTREGA + RECOGIDA LOINEX"),
    ("55", "55 ENTREGA + RECOGIDA + MANIPULA LOINEX"),
    ("73", "CHRONO PORTUGAL OPTICA"),
    ("76", "PAQUETERIA OPTICAS"),
    ("77", "OPTICA PREPAGADO"),
]
CORREOS_EXPRESS_PORTES = [("P", "Paid"), ("D", "Due")]


TEST_PATH = "https://www.test.cexpr.es/wsps/"
PROD_PATH = "https://www.cexpr.es/wspsc/"


class CorreosExpressRequest(object):
    def __init__(self, carrier):
        self.carrier_id = carrier
        path = PROD_PATH if self.carrier_id.prod_environment else TEST_PATH
        self.urls = {
            "shipment": path + "apiRestGrabacionEnviok8s/json/grabacionEnvio",
            "label": path + "apiRestEtiquetaTransporte/json/etiquetaTransporte",
            "tracking": path + "apiRestSeguimientoEnviosk8s/json/seguimientoEnvio",
        }

    def _send_api_request(self, request_type, url, data=None, skip_auth=False):
        if data is None:
            data = {}
        result = {}
        try:
            auth = tuple()
            if not skip_auth:
                auth = tuple(
                    [
                        self.carrier_id.correos_express_username,
                        self.carrier_id.correos_express_password,
                    ]
                )
            if request_type == "GET":
                res = requests.get(url=url, auth=auth, timeout=60)
            elif request_type == "POST":
                _logger.debug(data)
                res = requests.post(url=url, auth=auth, json=data, timeout=60)
            else:
                raise UserError(
                    _("Unsupported request type, please only use 'GET' or 'POST'")
                )
            result = res.json()
            correos_express_last_request = ("URL: {}\nData: {}").format(url, data)
            self.carrier_id.log_xml(
                correos_express_last_request, "correos_express_last_request"
            )
            self.carrier_id.log_xml(result, "correos_express_last_response")
            _logger.debug(res.json())
            res.raise_for_status()
        except requests.exceptions.Timeout as e:
            raise UserError(_("Timeout: the server did not reply within 60s")) from e
        except Exception as e:
            raise UserError(f"{e}\n{result or ''}") from e
        return_code, message = self._check_for_error(result)
        if return_code != 0:
            raise UserError(_("Correos Express Error:") + f" {return_code} {message}")
        return res

    def _check_for_error(self, result):
        return_code = 999
        message = "Webservice ERROR."
        # shipment
        if type(result.get("codigoRetorno", "false")) != str:
            return_code = result.get("codigoRetorno")
            message = result.get("mensajeRetorno") or ""
        # label
        if type(result.get("codErr", "false")) != str:
            return_code = result.get("codErr")
            message = result.get("desErr") or ""
        # tracking
        if type(result.get("error", "false")) != str:
            return_code = result.get("error")
            message = result.get("mensajeError") or ""
        return return_code, message

    def create_shipment(self, vals):
        res = self._send_api_request(
            request_type="POST", url=self.urls["shipment"], data=vals
        )
        return res.json()

    def print_shipment(self, vals):
        res = self._send_api_request(
            request_type="POST", url=self.urls["label"], data=vals
        )
        return res.json().get("listaEtiquetas", [])

    def track_shipment(self, vals):
        res = self._send_api_request(
            request_type="POST", url=self.urls["tracking"], data=vals
        )
        return res.json()
