package top.yeij.cyrene.data.repository

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import top.yeij.cyrene.data.remote.ApiService
import top.yeij.cyrene.data.remote.dto.IoTControlRequest
import top.yeij.cyrene.domain.model.Device
import top.yeij.cyrene.domain.model.DeviceState
import top.yeij.cyrene.domain.model.DeviceType
import top.yeij.cyrene.domain.repository.IoTRepository

class IoTRepositoryImpl(
    private val apiService: ApiService,
    private val webSocketService: top.yeij.cyrene.service.WebSocketService,
) : IoTRepository {

    private val _devices = MutableStateFlow<List<Device>>(emptyList())
    override fun getDevices(): Flow<List<Device>> = _devices.asStateFlow()

    override suspend fun controlDevice(
        deviceId: String,
        action: String,
        value: Any?,
    ): Result<Device> {
        return try {
            val response = apiService.controlDevice(deviceId, IoTControlRequest(action, value))
            if (response.isSuccessful) {
                val updated = response.body()!!.toDomain()
                _devices.value = _devices.value.map {
                    if (it.id == deviceId) updated else it
                }
                Result.success(updated)
            } else {
                Result.failure(Exception("设备控制失败: ${response.code()}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun refreshDevices() {
        try {
            val response = apiService.getDevices()
            if (response.isSuccessful) {
                _devices.value = response.body()!!.map { it.toDomain() }
            }
        } catch (_: Exception) { }
    }

    private fun top.yeij.cyrene.data.remote.dto.DeviceDto.toDomain() = Device(
        id = id,
        name = name,
        type = try {
            DeviceType.valueOf(type.uppercase())
        } catch (_: Exception) {
            DeviceType.UNKNOWN
        },
        state = DeviceState(
            power = state.power,
            brightness = state.brightness,
            temperature = state.temperature,
            humidity = state.humidity,
            colorTemp = state.colorTemp,
            locked = state.locked,
            open = state.open,
        ),
        room = room,
    )
}
