package io.nexilis.service.data.repositories

import android.util.Log
import androidx.lifecycle.LiveData
import io.nexilis.service.Service
import io.nexilis.service.core.Data
import io.nexilis.service.core.Network
import io.nexilis.service.core.toMD5
import io.nexilis.service.data.daos.BuddyDao
import io.nexilis.service.data.entities.Buddy
import io.nexilis.service.data.entities.MainEntity
import io.nexilis.service.tag
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import javax.inject.Inject

class BuddyRepository @Inject constructor(private val dao: BuddyDao) : Repository {

    val all: LiveData<List<Buddy>> = dao.getAll()

    val me: LiveData<Buddy> = dao.getMe()

    fun getBuddy(pin: String): LiveData<Buddy> {
        return dao.getBuddy(pin)
    }

    override suspend fun insert(entity: MainEntity) {
        dao.insert(entity as Buddy)
    }

    suspend fun signUp(
        username: String,
        password: String,
        completion: (Boolean, String) -> Unit
    ) {
        Service.sendAsync(
            Data(
                code = "A003",
                status = System.nanoTime().toString(),
                bodies = mutableMapOf(
                    "A02" to username,
                    "A03" to "",
                    "Bm" to password.toMD5(),
                    "Bm0" to ""
                )
            )
        ) { data ->
            Log.d(tag, "insert >>>> $data")
            val pin = data.bodies["A00real"] ?: ""
            if (data.isOk() && pin.isNotEmpty()) {
                dao.insert(Buddy(f_pin = pin, first_name = username, image_id = "", type = "1"))
            }
            withContext(Dispatchers.Main) {
                completion(data.isOk(), pin)
            }
        }
    }

    suspend fun signIn(
        api: String,
        username: String,
        password: String,
        completion: (Boolean, String) -> Unit
    ) {
        Service.sendSync(
            Data(
                code = "SSI01",
                status = System.nanoTime().toString(),
                bodies = mutableMapOf(
                    "A92" to username,
                    "Bm" to password,
                    "Api" to api
                )
            )
        )?.let { data ->
            Log.d(tag, "insert >>>> $data")
            val pin = data.bodies["A00real"] ?: ""
            if (data.isOk() && pin.isNotEmpty()) {
                Service.sendAsync(
                    Data(
                        code = "A050",
                        status = System.nanoTime().toString(),
                        f_pin = pin
                    )
                )
            }
            withContext(Dispatchers.Main) {
                completion(data.isOk(), pin)
            }
        }
    }

    fun addFriend(pin: String) {
        Service.sendAsync(
            Data(
                code = "A100",
                status = System.nanoTime().toString(),
                bodies = mutableMapOf(
                    "ffpin" to pin
                )
            )
        ) { data ->
            Log.d(tag, "addFriend >>>> $data")
        }
    }

    suspend fun searchFriend(name: String, completion: (Boolean, String) -> Unit) {
        Service.sendSync(
            Data(
                code = "SSU24",
                status = System.nanoTime().toString(),
                bodies = mutableMapOf(
                    "A92" to name
                )
            )
        )?.let {
            withContext(Dispatchers.Main) {
                completion(it.isOk(), it.bodies["A112"] ?: "")
            }
        }
    }

    suspend fun suggestFriend(lastSequence: String, completion: (Boolean, String) -> Unit) {
        Service.sendSync(
            Data(
                code = "SSS24",
                status = System.nanoTime().toString(),
                bodies = mutableMapOf(
                    "BF" to lastSequence
                )
            )
        )?.let {
            withContext(Dispatchers.Main) {
                completion(it.isOk(), it.bodies["A112"] ?: "")
            }
        }
    }

    fun changeProfile(me: String, file: File, completion: (Boolean) -> Unit) {
        Network().upload("https://digixplatform.com/uploader", file) {
            if (it) {
                Service.sendAsync(
                    Data(
                        code = "A003",
                        status = System.nanoTime().toString(),
                        f_pin = me,
                        bodies = mutableMapOf(
                            "A74" to file.name
                        )
                    )
                ) { data ->
                    if (data.isOk()) {
                        dao.updateImageMe(image = file.name)
                    }
                    withContext(Dispatchers.Main) {
                        completion(data.isOk())
                    }
                }
            }
        }
    }
}