package com.optix.android.data.repository

import com.optix.android.domain.model.ToolCategory
import com.optix.android.domain.model.ToolEvent
import com.optix.android.domain.model.ToolMetadata
import com.optix.android.domain.repository.ToolRepository
import com.optix.android.tools.engine.ToolExecutionEngine
import com.optix.android.tools.registry.ToolRegistry
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ToolRepositoryImpl @Inject constructor(
    private val registry: ToolRegistry,
    private val engine: ToolExecutionEngine,
) : ToolRepository {

    override fun getAllTools(): List<ToolMetadata> = registry.getAllMetadata()

    override fun getToolsByCategory(category: ToolCategory): List<ToolMetadata> =
        registry.getMetadataByCategory(category)

    override fun getToolMetadata(name: String): ToolMetadata? =
        registry.get(name)?.metadata

    override fun runTool(name: String, params: Map<String, Any>): Flow<ToolEvent> {
        val tool = registry.get(name)
            ?: return kotlinx.coroutines.flow.flow {
                emit(ToolEvent.Error("Tool '$name' not found"))
                emit(ToolEvent.Done)
            }
        return engine.run(tool, params)
    }

    // Cancellation is handled by the coroutine scope in the ViewModel.
    // This method exists for interface symmetry — callers should cancel the
    // collecting coroutine scope directly (e.g. viewModelScope Job cancellation).
    override fun cancelTool(name: String) = Unit
}
