// Generated by Qleany v1.5.1 from feature_controller.tera

use crate::AddBlockToListDto;
use crate::CreateListDto;
use crate::CreateListResultDto;
use crate::DeleteTextDto;
use crate::DeleteTextResultDto;
use crate::InsertBlockDto;
use crate::InsertBlockResultDto;
use crate::InsertFormattedTextDto;
use crate::InsertFormattedTextResultDto;
use crate::InsertFragmentDto;
use crate::InsertFragmentResultDto;
use crate::InsertFrameDto;
use crate::InsertFrameResultDto;
use crate::InsertHtmlAtPositionDto;
use crate::InsertHtmlAtPositionResultDto;
use crate::InsertImageDto;
use crate::InsertImageResultDto;
use crate::InsertListDto;
use crate::InsertListResultDto;
use crate::InsertMarkdownAtPositionDto;
use crate::InsertMarkdownAtPositionResultDto;
use crate::InsertTableColumnDto;
use crate::InsertTableColumnResultDto;
use crate::InsertTableDto;
use crate::InsertTableResultDto;
use crate::InsertTableRowDto;
use crate::InsertTableRowResultDto;
use crate::InsertTextDto;
use crate::InsertTextResultDto;
use crate::MergeTableCellsDto;
use crate::MergeTableCellsResultDto;
use crate::RemoveBlockFromListDto;
use crate::RemoveTableColumnDto;
use crate::RemoveTableColumnResultDto;
use crate::RemoveTableDto;
use crate::RemoveTableRowDto;
use crate::RemoveTableRowResultDto;
use crate::SplitTableCellDto;
use crate::SplitTableCellResultDto;
use crate::units_of_work::add_block_to_list_uow::AddBlockToListUnitOfWorkFactory;
use crate::units_of_work::create_list_uow::CreateListUnitOfWorkFactory;
use crate::units_of_work::delete_text_uow::DeleteTextUnitOfWorkFactory;
use crate::units_of_work::insert_block_uow::InsertBlockUnitOfWorkFactory;
use crate::units_of_work::insert_formatted_text_uow::InsertFormattedTextUnitOfWorkFactory;
use crate::units_of_work::insert_fragment_uow::InsertFragmentUnitOfWorkFactory;
use crate::units_of_work::insert_frame_uow::InsertFrameUnitOfWorkFactory;
use crate::units_of_work::insert_html_at_position_uow::InsertHtmlAtPositionUnitOfWorkFactory;
use crate::units_of_work::insert_image_uow::InsertImageUnitOfWorkFactory;
use crate::units_of_work::insert_list_uow::InsertListUnitOfWorkFactory;
use crate::units_of_work::insert_markdown_at_position_uow::InsertMarkdownAtPositionUnitOfWorkFactory;
use crate::units_of_work::insert_table_column_uow::InsertTableColumnUnitOfWorkFactory;
use crate::units_of_work::insert_table_row_uow::InsertTableRowUnitOfWorkFactory;
use crate::units_of_work::insert_table_uow::InsertTableUnitOfWorkFactory;
use crate::units_of_work::insert_text_uow::InsertTextUnitOfWorkFactory;
use crate::units_of_work::merge_table_cells_uow::MergeTableCellsUnitOfWorkFactory;
use crate::units_of_work::remove_block_from_list_uow::RemoveBlockFromListUnitOfWorkFactory;
use crate::units_of_work::remove_table_column_uow::RemoveTableColumnUnitOfWorkFactory;
use crate::units_of_work::remove_table_row_uow::RemoveTableRowUnitOfWorkFactory;
use crate::units_of_work::remove_table_uow::RemoveTableUnitOfWorkFactory;
use crate::units_of_work::split_table_cell_uow::SplitTableCellUnitOfWorkFactory;
use crate::use_cases::add_block_to_list_uc::AddBlockToListUseCase;
use crate::use_cases::create_list_uc::CreateListUseCase;
use crate::use_cases::delete_text_uc::DeleteTextUseCase;
use crate::use_cases::insert_block_uc::InsertBlockUseCase;
use crate::use_cases::insert_formatted_text_uc::InsertFormattedTextUseCase;
use crate::use_cases::insert_fragment_uc::InsertFragmentUseCase;
use crate::use_cases::insert_frame_uc::InsertFrameUseCase;
use crate::use_cases::insert_html_at_position_uc::InsertHtmlAtPositionUseCase;
use crate::use_cases::insert_image_uc::InsertImageUseCase;
use crate::use_cases::insert_list_uc::InsertListUseCase;
use crate::use_cases::insert_markdown_at_position_uc::InsertMarkdownAtPositionUseCase;
use crate::use_cases::insert_table_column_uc::InsertTableColumnUseCase;
use crate::use_cases::insert_table_row_uc::InsertTableRowUseCase;
use crate::use_cases::insert_table_uc::InsertTableUseCase;
use crate::use_cases::insert_text_uc::InsertTextUseCase;
use crate::use_cases::merge_table_cells_uc::MergeTableCellsUseCase;
use crate::use_cases::remove_block_from_list_uc::RemoveBlockFromListUseCase;
use crate::use_cases::remove_table_column_uc::RemoveTableColumnUseCase;
use crate::use_cases::remove_table_row_uc::RemoveTableRowUseCase;
use crate::use_cases::remove_table_uc::RemoveTableUseCase;
use crate::use_cases::split_table_cell_uc::SplitTableCellUseCase;
use anyhow::Result;
use common::event::{Event, Origin};

use common::event::DocumentEditingEvent::AddBlockToList;
use common::event::DocumentEditingEvent::CreateList;
use common::event::DocumentEditingEvent::DeleteText;
use common::event::DocumentEditingEvent::InsertBlock;
use common::event::DocumentEditingEvent::InsertFormattedText;
use common::event::DocumentEditingEvent::InsertFragment;
use common::event::DocumentEditingEvent::InsertFrame;
use common::event::DocumentEditingEvent::InsertHtmlAtPosition;
use common::event::DocumentEditingEvent::InsertImage;
use common::event::DocumentEditingEvent::InsertList;
use common::event::DocumentEditingEvent::InsertMarkdownAtPosition;
use common::event::DocumentEditingEvent::InsertTable;
use common::event::DocumentEditingEvent::InsertTableColumn;
use common::event::DocumentEditingEvent::InsertTableRow;
use common::event::DocumentEditingEvent::InsertText;
use common::event::DocumentEditingEvent::MergeTableCells;
use common::event::DocumentEditingEvent::RemoveBlockFromList;
use common::event::DocumentEditingEvent::RemoveTable;
use common::event::DocumentEditingEvent::RemoveTableColumn;
use common::event::DocumentEditingEvent::RemoveTableRow;
use common::event::DocumentEditingEvent::SplitTableCell;

use common::undo_redo::UndoRedoManager;
use common::{database::db_context::DbContext, event::EventHub};
use std::sync::Arc;

pub fn insert_text(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertTextDto,
) -> Result<InsertTextResultDto> {
    let uow_context = InsertTextUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertTextUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertText),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn delete_text(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &DeleteTextDto,
) -> Result<DeleteTextResultDto> {
    let uow_context = DeleteTextUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = DeleteTextUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(DeleteText),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_block(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertBlockDto,
) -> Result<InsertBlockResultDto> {
    let uow_context = InsertBlockUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertBlockUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertBlock),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_image(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertImageDto,
) -> Result<InsertImageResultDto> {
    let uow_context = InsertImageUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertImageUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertImage),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_frame(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertFrameDto,
) -> Result<InsertFrameResultDto> {
    let uow_context = InsertFrameUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertFrameUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertFrame),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_formatted_text(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertFormattedTextDto,
) -> Result<InsertFormattedTextResultDto> {
    let uow_context = InsertFormattedTextUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertFormattedTextUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertFormattedText),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn create_list(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &CreateListDto,
) -> Result<CreateListResultDto> {
    let uow_context = CreateListUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = CreateListUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(CreateList),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_list(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertListDto,
) -> Result<InsertListResultDto> {
    let uow_context = InsertListUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertListUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertList),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_fragment(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertFragmentDto,
) -> Result<InsertFragmentResultDto> {
    let uow_context = InsertFragmentUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertFragmentUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertFragment),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_html_at_position(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertHtmlAtPositionDto,
) -> Result<InsertHtmlAtPositionResultDto> {
    let uow_context = InsertHtmlAtPositionUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertHtmlAtPositionUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertHtmlAtPosition),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_markdown_at_position(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertMarkdownAtPositionDto,
) -> Result<InsertMarkdownAtPositionResultDto> {
    let uow_context = InsertMarkdownAtPositionUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertMarkdownAtPositionUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertMarkdownAtPosition),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_table(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertTableDto,
) -> Result<InsertTableResultDto> {
    let uow_context = InsertTableUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertTableUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertTable),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn remove_table(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &RemoveTableDto,
) -> Result<()> {
    let uow_context = RemoveTableUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = RemoveTableUseCase::new(Box::new(uow_context));
    uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(RemoveTable),
        ids: vec![],
        data: None,
    });
    Ok(())
}

pub fn insert_table_row(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertTableRowDto,
) -> Result<InsertTableRowResultDto> {
    let uow_context = InsertTableRowUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertTableRowUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertTableRow),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn insert_table_column(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &InsertTableColumnDto,
) -> Result<InsertTableColumnResultDto> {
    let uow_context = InsertTableColumnUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = InsertTableColumnUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(InsertTableColumn),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn remove_table_row(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &RemoveTableRowDto,
) -> Result<RemoveTableRowResultDto> {
    let uow_context = RemoveTableRowUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = RemoveTableRowUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(RemoveTableRow),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn remove_table_column(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &RemoveTableColumnDto,
) -> Result<RemoveTableColumnResultDto> {
    let uow_context = RemoveTableColumnUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = RemoveTableColumnUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(RemoveTableColumn),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn merge_table_cells(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &MergeTableCellsDto,
) -> Result<MergeTableCellsResultDto> {
    let uow_context = MergeTableCellsUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = MergeTableCellsUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(MergeTableCells),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn split_table_cell(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &SplitTableCellDto,
) -> Result<SplitTableCellResultDto> {
    let uow_context = SplitTableCellUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = SplitTableCellUseCase::new(Box::new(uow_context));
    let return_dto = uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    // Notify that the handling manifest has been loaded
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(SplitTableCell),
        ids: vec![],
        data: None,
    });
    Ok(return_dto)
}

pub fn add_block_to_list(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &AddBlockToListDto,
) -> Result<()> {
    let uow_context = AddBlockToListUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = AddBlockToListUseCase::new(Box::new(uow_context));
    uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(AddBlockToList),
        ids: vec![],
        data: None,
    });
    Ok(())
}

pub fn remove_block_from_list(
    db_context: &DbContext,
    event_hub: &Arc<EventHub>,
    undo_redo_manager: &mut UndoRedoManager,
    stack_id: Option<u64>,
    dto: &RemoveBlockFromListDto,
) -> Result<()> {
    let uow_context = RemoveBlockFromListUnitOfWorkFactory::new(db_context, event_hub);
    let mut uc = RemoveBlockFromListUseCase::new(Box::new(uow_context));
    uc.execute(dto)?;
    undo_redo_manager.add_command_to_stack(Box::new(uc), stack_id)?;
    event_hub.send_event(Event {
        origin: Origin::DocumentEditing(RemoveBlockFromList),
        ids: vec![],
        data: None,
    });
    Ok(())
}
