package com.example.tolucagraphics

import android.annotation.SuppressLint
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.tolucagraphics.adapters.JugadoresAdapter
import com.example.tolucagraphics.adapters.MesaAdapter
import com.example.tolucagraphics.datas.CreateTable
import com.example.tolucagraphics.datas.GetRooms
import com.example.tolucagraphics.datas.JoinRoom
import com.example.tolucagraphics.events.*
import com.example.tolucagraphics.models.ModelForTables
import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_mesas_players.*
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener

class MesasActivity : AppCompatActivity() {
    var selector = 1
    val gson = Gson()
    val decoJson = Gson()
    private val conection = Socket
    var yaEntro = false
    var yaEntroMesaCreada = false
    var tamanioJugadores = 0
    var tamanioMesas = 0
    var listaJugadores = ArrayList<UserElementJoin>()
    var listaMesas = ArrayList<EventCreateMesa>()
    val listaTables = ArrayList<ModelForTables>()
    lateinit var jugadoresAdapter: JugadoresAdapter
    lateinit var mesasAdapter: MesaAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_mesas_players)

        conection.webSocketSingle?.close(1000, "Change Activity")
        conection.listener = TestListener()
        conection.conectarconWS()
        conection.webSocketSingle?.send(gson.toJson(GetRooms()))
        conection.webSocketSingle?.send(gson.toJson(JoinRoom()))
        btnCreaMesa.setOnClickListener {
            conection.webSocketSingle?.send(gson.toJson(CreateTable()))
        }
        /********************PETICION DE MESAS******************/
        val joinRoomJSON = gson.toJson(JoinRoom())
        Log.d("request",joinRoomJSON)
        conection.webSocketSingle?.send(joinRoomJSON)

        btnCreaMesa.setOnClickListener {
            Log.d("request", "mesnaje a enviar:{\"command\":\"create_room_table\",\"data\":{\"roomId\":\"1\",\"points\":30}} ")
            conection.webSocketSingle?.send(gson.toJson(CreateTable()))

        }

    }
    fun iniciarRecyclerJugadores(){
        jugadoresAdapter = JugadoresAdapter(listaJugadores)
        lista_jugadores.apply {
            layoutManager = LinearLayoutManager(this@MesasActivity)
            adapter = jugadoresAdapter
        }
    }
    fun iniciarRecyclerMesas(){
        mesasAdapter = MesaAdapter(listaMesas){ cadena, join ->
            Toast.makeText(this@MesasActivity, cadena, Toast.LENGTH_LONG).show()
            val intentJuego = Intent(this@MesasActivity, MesaEnJuego::class.java)
            intentJuego.putExtra("join", gson.toJson(join))
            startActivity(intentJuego)
        }
        lista_mesas.apply {
            layoutManager = LinearLayoutManager(this@MesasActivity)
            adapter = mesasAdapter
        }
    }
    fun agregarTableGetInit(entrada : EventGetRoom){
        for (indiceT in entrada.data?.rooms?.get(0)?.tables?.indices!!) {
            listaTables.add(ModelForTables(id = entrada.data.rooms[0].tables?.get(indiceT)?.id, state = entrada.data.rooms[0].tables?.get(indiceT)?.status, users = entrada.data.rooms[0].tables?.get(indiceT)?.positions))
        }

    }
    fun agregarTable(entrada : EventCreateMesa){

        listaTables.add(ModelForTables(id = entrada.data?.table?.id, state = entrada.data?.table?.status, users = entrada.data?.table?.users as List<OwnerClass>))
    }
    fun buscarDuplicados(){
        /*if(list.removeAll { it == item }) {
            println("Lista modificada: ${list}")
        } else {
            println("El elemento no existe!!")
        }    */
        if (tamanioMesas > 1) {
            for (indice in listaMesas.indices) {
                if (listaMesas.removeAll { it == listaMesas[indice] }) {
                    tamanioMesas = listaMesas.size
                    mesasAdapter.notifyItemRemoved(tamanioMesas)
                }
            }
        }
    }
    fun contieneId(lista: ArrayList<EventCreateMesa>, idNuevo : String?):Boolean{
        var contiene = false
        for (indice in lista.indices){
            contiene = lista[indice].data?.table?.id != idNuevo
        }
        return contiene
    }
    fun adaptarEvento(evento : EventCreateMesa) : EventCreateMesa{
        var resultado = EventCreateMesa()
        resultado.command = evento.command
        resultado.type = evento.type
        resultado.data?.user = evento.data?.user
        resultado.data?.room = evento.data?.room
        resultado.data?.eventName = evento.data?.eventName
        resultado.data?.table?.id = evento.data?.table?.id
        resultado.data?.table?.owner = evento.data?.table?.owner
        resultado.data?.table?.points = evento.data?.table?.points
        resultado.data?.table?.privateTable = evento.data?.table?.privateTable
        resultado.data?.table?.roomID = evento.data?.table?.roomID
        resultado.data?.table?.status = evento.data?.table?.status
        resultado.data?.table?.users?.add(evento.data?.table?.users!!.first())
        return resultado
    }
    inner class TestListener : WebSocketListener() {
        override fun onOpen(webSocket: WebSocket, response: Response) {
            //Log.d("request", "connection successfully")
            Log.d("request","vuelto a abrir???")
            //webSocket.close(1000, "finish")
        }
        @SuppressLint("SetTextI18n")
        override fun onMessage(webSocket: WebSocket, text: String) {
            //usernameReceived.text = "cargando Rooms"
            runOnUiThread {
                if (text.contains(KeysWebSocket.commandResponse,true) && text.contains(KeysWebSocket.commandGetRooms)){
                    Log.d("TAG", "GETROOMS -> $text")
                    agregarTableGetInit(gson.fromJson(text, EventGetRoom::class.java))
                    Log.d("TAG", "ListaTables Nueva -> $listaTables")
                    /**********************************************Parte para el Recycler de Jugadores**************************************/
                }else if (text.contains(KeysWebSocket.commandResponse,true) && text.contains(KeysWebSocket.commandJoinRoom)){
                    val eventJoinRoom = gson.fromJson(text, EventJoinRoom::class.java)
                    listaJugadores = eventJoinRoom.data?.room?.users!! as ArrayList<UserElementJoin>
                    tamanioJugadores = listaJugadores.size
                    iniciarRecyclerJugadores()
                }else if(text.contains(KeysWebSocket.trucoRoomEvent,true) && text.contains(KeysWebSocket.roomUserJoined)){
                    if (yaEntro) {
                        val eventTrucoRoom = gson.fromJson(text, EventJoinRoomTRE::class.java)
                        listaJugadores.add(UserElementJoin(user = UserUserJoin(eventTrucoRoom.data?.user!!.id, eventTrucoRoom.data.user.username ), online = true))
                        jugadoresAdapter.notifyItemInserted(tamanioJugadores)
                    }else yaEntro = true
                }else if(text.contains(KeysWebSocket.trucoRoomEvent, true) && text.contains(KeysWebSocket.roomLeftRoom, true)){
                    val eventLeftTrucoRoom = gson.fromJson(text, EventJoinRoomTRE::class.java)
                    listaJugadores.remove(UserElementJoin(user = UserUserJoin(eventLeftTrucoRoom.data?.user!!.id, eventLeftTrucoRoom.data.user.username ), online = true))
                    jugadoresAdapter.notifyItemRemoved(tamanioJugadores)
                    /************************************************Parte para el Recycler de Mesas ****************************************************/
                }else if (text.contains(KeysWebSocket.commandResponse,true) && text.contains(KeysWebSocket.commandCreateRoomTable)){
                    val eventoCreateTable = gson.fromJson(text, EventCreateMesa::class.java)
                    listaMesas.add(eventoCreateTable)
                    tamanioMesas = listaMesas.size
                    if (yaEntroMesaCreada){
                        mesasAdapter.notifyItemInserted(tamanioMesas)
                    }else {
                        iniciarRecyclerMesas()
                        buscarDuplicados()
                        yaEntroMesaCreada = true
                    }
                }else if(text.contains(KeysWebSocket.trucoRoomEvent,true) && text.contains(KeysWebSocket.roomTableCreated,true)){
                    val eventoCreateTable = gson.fromJson(text, EventCreateMesa::class.java)
                    // Users solo tiene el owner size = 1
                    Log.d("TAG", "MesaCreada-> $eventoCreateTable")
                    if (listaMesas.isEmpty()){
                        listaMesas.add(eventoCreateTable)
                        tamanioMesas = listaMesas.size
                        iniciarRecyclerMesas()
                    }else{

                        if (contieneId(listaMesas, eventoCreateTable.data?.table?.id))
                            listaMesas.add(eventoCreateTable)
                        tamanioMesas = listaMesas.size
                        mesasAdapter.notifyItemInserted(tamanioMesas)
                    }
                }else if(text.contains(KeysWebSocket.trucoRoomEvent, true) && text.contains(KeysWebSocket.roomTableUserJoined, true)){
                    var eventoJoined = gson.fromJson(text, EventCreateMesa::class.java)
                    var eventoJoinedAdaptado = adaptarEvento(eventoJoined)
                    for (indice in listaMesas.indices) {
                        if (listaMesas[indice].data?.table?.id == eventoJoinedAdaptado.data?.table?.id ) {
                            listaMesas[indice].data?.table?.users?.get(0)?.id = eventoJoinedAdaptado.data?.user?.id
                            listaMesas[indice].data?.table?.users?.get(0)?.username = eventoJoinedAdaptado.data?.user?.username
                            mesasAdapter.notifyItemChanged(indice)
                        }
                    }
                }else if(text.contains(KeysWebSocket.trucoTableEvent,true)&&text.contains(KeysWebSocket.tablePositionSetted,true)){
                    var eventoJoined = gson.fromJson(text, EventTablePositionSetted::class.java)
                    Log.d("TAG", "se Unio $eventoJoined")
                    Log.d("TAG", "tamanio de la mesa hecha: ${listaMesas.first().data?.table?.users?.size}")
                    Log.d("TAG", "tamanio de la mesa recibida: ${eventoJoined.data?.table?.positions?.size}")
                    for (indice in listaMesas.indices) {
                        if (listaMesas[indice].data?.table?.id == eventoJoined.data?.table?.id ) {
                            Log.d("TAG", "entra para agregar Player!!!")
                            listaMesas[indice].data?.table?.users = eventoJoined.data?.table?.positions as ArrayList<User>
                            //listaMesas[indice].data?.table?.users?.get(eventoJoined.data?.position!!.toInt())?.username = "X"
                            mesasAdapter.notifyItemChanged(tamanioMesas)
                        }
                    }
                }else{
                    Log.d("TAG", "Unidentified-> $text")
                }
            }
        }


        override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
            Log.d("request","testCierra : $code / $reason")
        }
        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            Log.d("request","Error : " + t.message +response.toString())
            conection.conectarconWS()
            val joinRoomJSON = gson.toJson(JoinRoom())
            Log.d("request",joinRoomJSON)
            conection.webSocketSingle?.send(joinRoomJSON)
        }
    }
}
