"""
FSM Transitions for Annotation model.

This module defines declarative transitions for the Annotation entity.
Annotation transitions can update related task states via post_transition_hooks.
"""

from typing import Any, Dict, Optional

from fsm.registry import register_state_transition
from fsm.state_choices import AnnotationStateChoices
from fsm.transitions import ModelChangeTransition, StateModelType, TransitionContext


@register_state_transition('annotation', 'annotation_created', triggers_on_create=True, triggers_on_update=False)
class AnnotationCreatedTransition(ModelChangeTransition):
    """
    Transition when an annotation is created.

    This is the default transition for newly created annotations.

    Trigger: Automatically on creation only (triggers_on_create=True, triggers_on_update=False)
    """

    def get_target_state(self, context: Optional[TransitionContext] = None) -> str:
        return AnnotationStateChoices.CREATED

    def get_reason(self, context: TransitionContext) -> str:
        """Return detailed reason for annotation creation."""
        return 'Annotation created'

    def transition(self, context: TransitionContext) -> Dict[str, Any]:
        """Execute annotation submission transition."""
        annotation = context.entity

        return {
            'task_id': annotation.task_id,
            'project_id': annotation.project_id,
            'completed_by_id': annotation.completed_by_id,
            'lead_time': annotation.lead_time,
        }

    def post_transition_hook(self, context: TransitionContext, state_record: StateModelType) -> None:
        """
        Post-transition hook for annotation creation.

        Updates task state to COMPLETED when annotation is created.
        Then updates project state based on task completion status.
        Handles "cold start" scenarios where task may not have state record yet.
        """
        from fsm.project_transitions import update_project_state_after_task_change
        from fsm.state_choices import TaskStateChoices
        from fsm.state_manager import StateManager
        from fsm.utils import get_or_initialize_state

        annotation = context.entity
        task = annotation.task
        project = annotation.project

        # Get current task state (initialize if needed)
        current_task_state = StateManager.get_current_state_value(task)

        if current_task_state is None:
            # Task has no state record - initialize it
            # Since annotation was just created, task should be COMPLETED
            current_task_state = get_or_initialize_state(
                task, user=context.current_user, inferred_state=TaskStateChoices.COMPLETED
            )

        # Transition task to COMPLETED if not already
        if current_task_state != TaskStateChoices.COMPLETED:
            StateManager.execute_transition(entity=task, transition_name='task_completed', user=context.current_user)

        # Update project state based on task changes
        update_project_state_after_task_change(project, user=context.current_user)


@register_state_transition(
    'annotation', 'annotation_updated', triggers_on_create=False, triggers_on_update=True, force_state_record=True
)
class AnnotationUpdatedTransition(ModelChangeTransition):
    """
    Transition when an annotation is updated.

    Updates keep the annotation in CREATED state but create audit trail records.

    Trigger: On update (triggers_on_create=False, triggers_on_update=True, force_state_record=True)
    """

    def get_target_state(self, context: Optional[TransitionContext] = None) -> str:
        return AnnotationStateChoices.CREATED

    def get_reason(self, context: TransitionContext) -> str:
        """Return detailed reason for annotation update."""
        return 'Annotation updated'

    def transition(self, context: TransitionContext) -> Dict[str, Any]:
        """Execute annotation update transition."""
        annotation = context.entity

        return {
            'task_id': annotation.task_id,
            'project_id': annotation.project_id,
            'updated_by_id': getattr(annotation, 'updated_by_id', None),
            'changed_fields': list(self.changed_fields.keys()) if self.changed_fields else [],
        }

    def post_transition_hook(self, context: TransitionContext, state_record: StateModelType) -> None:
        """Post-transition hook for annotation updates."""
        pass
