import logging
from typing import List, Optional
from uuid import UUID

from staff.budget_position.workflow_service import entities
from staff.budget_position.workflow_service.use_cases.interfaces import OebsHireService
from staff.budget_position.workflow_service.use_cases.push_workflow_to_oebs import PushWorkflowToOebs


logger = logging.getLogger(__name__)


class ConfirmWorkflows:
    def __init__(
        self,
        repository: entities.WorkflowRepositoryInterface,
        femida_service: entities.FemidaService,
        oebs_hire_service: OebsHireService,
        push_workflow_to_oebs: PushWorkflowToOebs,
    ):
        self._oebs_hire_service = oebs_hire_service
        self._repository = repository
        self._femida_service = femida_service
        self._push_workflow_to_oebs = push_workflow_to_oebs

    def confirm(self, workflow_id: UUID, responsible_id: Optional[int]) -> None:
        workflow = self._repository.get_by_id(workflow_id)
        workflow.confirm()
        logger.info('Confirmed %s workflow', workflow.id)
        self._repository.save(workflow)

        if workflow.should_push_new_department_to_femida or workflow.should_push_new_bp_to_femida:
            logger.info('Workflow %s will scheduled for pushing new department to femida', workflow.id)
            self._femida_service.schedule_department_push(workflow.id)

        if workflow.should_close_vacancy:
            self._femida_service.close_vacancy(workflow.id)

        if workflow.should_be_pushed_automatically:
            logger.info('Workflow should be pushed automatically')
            if workflow.should_be_pushed_to_oebs_hire:
                workflow.mark_pushing_to_oebs()
                self._oebs_hire_service.push_workflow(workflow)
                return

            self._push_workflow_to_oebs.push(workflow.id, responsible_id)

    def confirm_for_credit_management_application(self, application_id: int) -> None:
        workflows = self._repository.get_workflows_by_credit_management_application(application_id)
        self._mark_confirmed(workflows)

    def confirm_many(self, workflows_ids: List[UUID]) -> None:
        workflows = self._repository.get_workflow_list(workflows_ids)
        self._mark_confirmed(workflows)

    def _mark_confirmed(self, workflows: List[entities.AbstractWorkflow]) -> None:
        for workflow in workflows:
            if workflow.is_pending():
                workflow.confirm()
            logger.info('Confirmed %s workflow', workflow.id)
            self._repository.save(workflow)
