import operator
import warnings

_ = lambda x: x

from ocyan.core.fender import config

target_name = operator.itemgetter("name")

PIPELINE_STATUS_NEW = config.get("oscar", "initial_order_status", _("new"))
PIPELINE_STATUS_PENDING_PAYMENT = config.get(
    "oscar", "waiting_for_payment_order_status", _("pending-payment")
)
PIPELINE_STATUS_DELAYED_PAYMENT = config.get(
    "oscar", "delayed_payment_status", _("delayed-payment")
)
PIPELINE_STATUS_PAID = config.get("oscar", "paid_order_status", _("paid"))
PIPELINE_STATUS_REFUND = config.get("oscar", "refund_order_status", _("refund"))
PIPELINE_STATUS_COMPLETE = config.get("oscar", "complete_order_status", _("complete"))
PIPELINE_STATUS_CANCELLED = config.get(
    "oscar", "cancelled_order_status", _("cancelled")
)
PIPELINE_STATUS_RESTOCKED = config.get(
    "oscar", "restocked_order_status", _("restocked")
)


def format_pipeline(pipeline):
    """
    >>> order_pipeline = [
    ...     {
    ...         "target": [
    ...             {
    ...                 "name": "pending-payment"
    ...             }
    ...         ],
    ...         "source": "new"
    ...     },
    ...     {
    ...         "target": [
    ...             {
    ...                 "name": "complete"
    ...             },
    ...             {
    ...                 "name": "new"
    ...             },
    ...         ],
    ...         "source": "pending-payment"
    ...     },
    ...     {
    ...         "target": [],
    ...         "source": "complete"
    ...     },
    ... ]
    >>> format_pipeline(order_pipeline)
    {'new': ('pending-payment',), 'pending-payment': ('complete', 'new'), 'complete': ()}
    """
    pipeline = {
        item["source"]: tuple(map(target_name, item["target"])) for item in pipeline
    }
    if pipeline:
        warnings.warn(
            "It seems you have overriden pipeline in your ocyan json, are you "
            "sure that is necessary?"
        )
        return pipeline

    # We can not deal with empty pipelines and since complex defaults are
    # currently broken, lets have some sane default order pipeline.

    order_pipeline = {
        PIPELINE_STATUS_NEW: (
            PIPELINE_STATUS_PENDING_PAYMENT,
            PIPELINE_STATUS_PAID,
            PIPELINE_STATUS_CANCELLED,
        ),
        PIPELINE_STATUS_PENDING_PAYMENT: (
            PIPELINE_STATUS_PAID,
            PIPELINE_STATUS_CANCELLED,
            PIPELINE_STATUS_DELAYED_PAYMENT,
        ),
        PIPELINE_STATUS_DELAYED_PAYMENT: (
            PIPELINE_STATUS_PAID,
            PIPELINE_STATUS_CANCELLED,
        ),
        PIPELINE_STATUS_PAID: (PIPELINE_STATUS_COMPLETE, PIPELINE_STATUS_REFUND),
        PIPELINE_STATUS_REFUND: (PIPELINE_STATUS_CANCELLED,),
        PIPELINE_STATUS_COMPLETE: (PIPELINE_STATUS_REFUND,),
        PIPELINE_STATUS_CANCELLED: (
            PIPELINE_STATUS_PENDING_PAYMENT,
            PIPELINE_STATUS_PAID,
        ),
    }
    orderline_pipeline = dict(
        order_pipeline,
        **{
            PIPELINE_STATUS_CANCELLED: (
                PIPELINE_STATUS_PENDING_PAYMENT,
                PIPELINE_STATUS_PAID,
                PIPELINE_STATUS_RESTOCKED,
            )
        },
    )
    return order_pipeline, orderline_pipeline
