from plone import api
from ploneintranet.notifications.sql import saconfig
from Products.DCWorkflow.interfaces import IAfterTransitionEvent


def todo_update_handler(context, event):
    """
    * when a todo is created the assignee gets a notification
    * when a todo is edited assignee and initiator get notifications
    * when a todo is state changed assignee and initiator get notifications

    always - the one who did the changes does not get a notification
    """
    # After creation, another event handler may update the workflow state of a
    # todo which will trigger additional messages.
    # The request is marked to show that the item has just been created.
    if getattr(context.REQUEST, "newly_created", False):
        return

    # Don't send notifications for planned todos
    wft = api.portal.get_tool("portal_workflow")
    state_id = wft.getInfoFor(context, "review_state")
    if state_id == "planned":
        return

    initiator = context.initiator
    assignee = context.assignee
    current_user = api.user.get_current()
    current_user_id = current_user.getId()

    # Determine the nature of the change
    change = "modification"
    if IAfterTransitionEvent.providedBy(event):
        # In a case, a todo is transitioned from 'planned' to 'open' when
        # the case reaches the milestone of the todo.

        # The assignee may only be first aware of the todo when it is set to
        # 'open', since they may not have permission to view it earlier. So we
        # send a notification that they have been assigned.
        if not event.transition:
            return
        old_state = event.old_state.getId()
        if state_id == "open":
            change = "assignment"
        elif old_state == "open" and state_id == "done":
            saconfig.log_event(context, "todo_closed_assignee")
            saconfig.log_event(context, "todo_closed_initiator")
            return
        else:
            return
    elif any(
        "assignee" in description.attributes for description in event.descriptions
    ):
        # The todo has been changed and one of the changes was the assignee.
        change = "assignment"

    # Special Case:
    # An assignee has been set and it is not the current user, so we
    # need to inform the assignee.
    if assignee and assignee != current_user_id:
        if change == "assignment":
            saconfig.log_event(context, "todo_assigned")
        else:
            saconfig.log_event(context, "todo_assignee_changed")

    if initiator and initiator != current_user_id and initiator != assignee:
        saconfig.log_event(context, "todo_initiator_changed")
