#define MAX_OPCIONES_MENU 8

uint8_t opciones_menu = 0;

EstadoPartida estado_partida = {0};
uint8_t estado_menu = ESTADO_MENU_MENU;
uint8_t asiento_cambio_elegido = JUGADOR_INVALIDO;
uint8_t asientos_ocupados = 0;
uint8_t es_host = 0;
uint8_t numero_jugador;
uint8_t max_jugadores_sala = 6;

// typedef enum{
//     ACCION_A_15,
//     ACCION_A_30,
//     ACCION_SETEAR_2V2
// } AccionMenuConfiguracionSala;

typedef enum{
    ACCION_EMPEZAR_PARTIDA,
    ACCION_CAMBIAR_ASIENTO,
    ACCION_CAMBIAR_ASIENTO_OTRO,
    ACCION_DAR_ANFITRION
    ACCION_CONFIGURAR_SALA,
} AccionMenuSala;

typedef enum{
    ESTADO_MENU_MENU,

    ESTADO_MENU_CONECTANDO,

    ESTADO_MENU_EN_VESTIBULO,

    ESTADO_MENU_EN_SALA,
    ESTADO_MENU_CONFIGURANDO_SALA,

    ESTADO_MENU_DANDO_ANFITRION,
    ESTADO_MENU_CAMBIANDO_ASIENTO,
    ESTADO_MENU_CAMBIANDO_ASIENTO_OTRO,

    ESTADO_MENU_EN_PARTIDA
} EstadoMenu;

static uint8_t encontrar_indice_opcion_menu(uint8_t opcion_i){
    uint8_t indice_opcion = 0;

    for(uint8_t i = 0; i < MAX_OPCIONES_MENU; i++){
        if(IS_BIT_SET(opciones_menu, i)) indice_opcion++;
        if(i == opcion_i) break;
    }

    return indice_opcion;
}

typedef void (*RenderIFunc)(uint8_t indice_opcion, uint8_t opcion_i);

static void setear_y_renderizar_con_opcion_i(uint8_t opcion_i, RenderIFunc *func){
    SET_BIT(opciones_menu, opcion_i);
    func(encontrar_indice_opcion_menu(i), opcion_i);
}

typedef void (*RenderFunc)(uint8_t indice_opcion);

static void setear_y_renderizar(uint8_t opcion_i, RenderIFunc *func){
    SET_BIT(opciones_menu, opcion_i);
    func(encontrar_indice_opcion_menu(i));
}

uint8_t TCIC_obtener_jugadores_en_sala(){
    uint8_t set = 0;
    for(uint8_t i = 0; i < max_jugadores_sala; i++) if(IS_BIT_SET(asientos_ocupados), i) set++;
    return set;
};

void TCIC_render_cambio_disponible(uint8_t opcion_i, uint8_t asiento_i);

void TCIC_manejar_cambiando_asiento(){
    for(uint8_t i = 0; i < max_jugadores_sala; i++){
        if((IS_BIT_SET(asientos_ocupados, i) && !es_host) ||
        i == numero_jugador
        ) continue;

        setear_y_renderizar_con_opcion_i(i, TCIC_render_cambio_disponible);
    }
}

void TCIC_manejar_cambiar_asiento_otro(){
    for(uint8_t i = 0; i < max_jugadores_sala; i++){
        if(i == asiento_cambio_elegido) continue;

        setear_y_renderizar_con_opcion_i(i, TCIC_render_cambio_disponible);
    }
}

void TCIC_render_dar_anfitrion(){
    for(uint8_t i = 0; i < max_jugadores_sala; i++){
        if(i == numero_jugador) continue;

        setear_y_renderizar_con_opcion_i(i, TCIC_render_cambio_disponible);
    }
}

void TCIC_render_empezar_partida();
void TCIC_render_cambiar_asiento();
void TCIC_render_cambiar_asiento_otro();
void TCIC_render_cambiar_host();

void TCIC_render_opciones_sala(){
    if(es_host && !(TCIC_obtener_jugadores_en_sala() % 2)) setear_y_renderizar(ACCION_EMPEZAR_PARTIDA, TCIC_render_empezar_partida);

    if(TCIC_obtener_jugadores_en_sala() != max_jugadores_sala || es_host) setear_y_renderizar(ACCION_CAMBIAR_ASIENTO, TCIC_render_cambiar_asiento);

    if(es_host && TCIC_obtener_jugadores_en_sala > 1){
        setear_y_renderizar(ACCION_CAMBIAR_ASIENTO_OTRO, TCIC_render_cambiar_asiento_otro);
        setear_y_renderizar(ACCION_DAR_ANFITRION, TCIC_render_cambiar_host);
    }
}


void TCIC_manejar_accion_menu(uint8_t accion){
    uint8_t bits_seteados = 0;
    uint8_t comando = 0;

    for(uint8_t i = 0; i < MAX_OPCIONES_MENU; i++){
        if(IS_BIT_SET(opciones_menu, i)) bits_seteados++;
        if(bits_seteados == accion) {comando = i; break;}
    }

    if(bits_seteados != accion) return;

    opciones_menu = 0;

    switch(estado){
        case ESTADO_MENU_EN_SALA: {
            switch(comando){
                case ACCION_EMPEZAR_PARTIDA: {
                    TCIC_empezar_partida(); 
                    break;
                }
                case ACCION_CAMBIAR_ASIENTO: {
                    estado_menu = ESTADO_MENU_CAMBIANDO_ASIENTO;
                    TCIC_manejar_cambiando_asiento();
                    break;
                }
                case ACCION_CAMBIAR_ASIENTO_OTRO: {
                    estado_menu = ESTADO_MENU_CAMBIANDO_ASIENTO_OTRO;
                    TCIC_manejar_cambiar_asiento_otro();
                    break;
                }
                case ACCION_DAR_ANFITRION: {
                    estado_menu = ESTADO_MENU_DANDO_ANFITRION; 
                    TCIC_render_dar_anfitrion();
                    break;
                }
            }
            break;
        }
        case ESTADO_MENU_CAMBIANDO_ASIENTO: {
            TCIC_cambiar_asiento(comando);
            estado_menu = ESTADO_MENU_EN_SALA;
            break;
        }
        case ESTADO_MENU_CAMBIANDO_ASIENTO_OTRO: {
            if(asiento_cambio_elegido != JUGADOR_INVALIDO){
                TCIC_cambiar_asiento_otro(asiento_cambio_elegido, comando);
                estado_menu = ESTADO_MENU_EN_SALA;
                asiento_cambio_elegido = JUGADOR_INVALIDO;
            }else{
                asiento_cambio_elegido = comando;
            }
            break;
        }
        case ESTADO_MENU_DANDO_ANFITRION: {
            TCIC_dar_anfitrion(comando);
            estado_menu = ESTADO_MENU_EN_SALA;
            break;
        }
        case ESTADO_EN_PARTIDA: { 
            if(obtener_jugador_turno_actual(&estado_partida) == numero_jugador){
                TCIC_manejar_accion_turno(&estado_partida, accion, numero_jugador, 0);
            }
        }

        default: break;
    }

}