package com.optix.android.data.repository

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.optix.android.data.local.WorkflowDao
import com.optix.android.data.local.entities.WorkflowEntity
import com.optix.android.domain.model.Workflow
import com.optix.android.domain.model.WorkflowStep
import com.optix.android.domain.repository.WorkflowRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class WorkflowRepositoryImpl @Inject constructor(
    private val dao: WorkflowDao,
    private val gson: Gson,
) : WorkflowRepository {

    override suspend fun saveWorkflow(workflow: Workflow): Long =
        dao.insert(workflow.toEntity())

    override suspend fun getWorkflow(id: Long): Workflow? =
        dao.getById(id)?.toDomain()

    override fun getAllWorkflows(): Flow<List<Workflow>> =
        dao.observeAll().map { list -> list.map { it.toDomain() } }

    override suspend fun deleteWorkflow(id: Long) = dao.deleteById(id)

    // ------------------------------------------------------------------
    // Mapping helpers
    // ------------------------------------------------------------------

    private val stepsType = object : TypeToken<List<WorkflowStep>>() {}.type

    private fun Workflow.toEntity() = WorkflowEntity(
        id = id,
        name = name,
        stepsJson = gson.toJson(steps),
        createdAt = createdAt,
    )

    private fun WorkflowEntity.toDomain() = Workflow(
        id = id,
        name = name,
        steps = gson.fromJson(stepsJson, stepsType) ?: emptyList(),
        createdAt = createdAt,
    )
}
