#include <stdio.h>

#include "game.h"

const char* nombrePalo(uint8_t palo) {
    switch(palo) {
        case PALO_ESPADA:
            return "Espada";

        case PALO_BASTO:
            return "Basto";

        case PALO_ORO:
            return "Oro";

        case PALO_COPA:
            return "Copa";
    }
    return "?";
}

const char* nombreCanto(uint8_t canto) {
    switch(canto) {
        case FLAG_TRUCO:
            return "Truco";

        case FLAG_RETRUCO:
            return "Retruco";

        case FLAG_VALE_CUATRO:
            return "Vale Cuatro";
        case CANTO_QUIERO:
            return "Quiero";
        case CANTO_NO_QUIERO:
            return "No Quiero";
        case FLAG_ENVIDO:
            return "Envido";
        case FLAG_ENVIDO_ENVIDO:
            return "Envido (Envido)";
        case FLAG_REAL_ENVIDO:
            return "Real Envido";
        case FLAG_FALTA_ENVIDO:
            return "Falta Envido";
    }

    return "?";
}

const char* jugador_o_equipo(uint8_t jugadores) {
    switch(jugadores) {
        case 2:
            return "Jugador";
    }

    return "Equipo";
}

int main(){

    uint8_t jugadores = 2;

    printf("\nInserte número de jugadores: ");
    scanf("%u", &jugadores);

    EstadoPartida partida;

    if(!iniciar_partida(&partida, jugadores, 14)){
        printf("Número inválido de jugadores.\n");
        return 1;
    }

    while(1){
        uint8_t jugador = partida.ronda_estado == ESTADO_PARTIDA_JUGANDO_BAZA ? partida.jugador_turno_actual : partida.jugador_turno_canto;
        uint8_t equipo_jugador = jugador % 2;
        uint8_t numero_jugador = jugador + 1;

        uint8_t truco_disponible = CANTO_INVALIDO;

        switch(partida.ronda_estado){
            case ESTADO_PARTIDA_JUGANDO_BAZA:
                if(!IS_BIT_SET(partida.flags_ronda, FLAG_TRUCO)) truco_disponible = FLAG_TRUCO;
                else if(IS_BIT_SET(partida.flags_ronda, FLAG_TIENE_RETRUCO) == equipo_jugador){
                    if(!IS_BIT_SET(partida.flags_ronda, FLAG_VALE_CUATRO)){
                        if(IS_BIT_SET(partida.flags_ronda, FLAG_RETRUCO)) truco_disponible = FLAG_VALE_CUATRO;
                        else truco_disponible = FLAG_RETRUCO;
                    }
                }

                printf("\nTurno de jugador %d \n", numero_jugador);

                printf("\nDEBUG: Jugador %d tiene %d de envido \n", numero_jugador, calcular_envido(&partida, jugador));
    
                for(uint8_t carta_i = 0; carta_i < 3; carta_i++){
                    uint8_t carta = partida.jugadores_cartas[partida.jugador_turno_actual][carta_i];
                    if(carta == CARTA_INVALIDA) continue;
                    printf("%u: %u de %s\n",
                        carta_i,
                        cartas[carta].valor_carta,
                        nombrePalo(cartas[carta].palo)
                    );
                }
    
                if(truco_disponible != CANTO_INVALIDO) printf("\n3: %s!", nombreCanto(truco_disponible));

                if(!partida.baza_actual && !IS_BIT_SET(partida.flags_ronda, FLAG_ENVIDO_CANTADO)){
                    printf("\n6: Envido");
                    printf("\n8: Real Envido");
                    printf("\n9: Falta Envido");
                } 

                break;
            case ESTADO_PARTIDA_EN_CANTO:
                printf("\nResponde jugador %d \n", numero_jugador);
                if(partida.canto_ofrecido >= FLAG_TRUCO && partida.canto_ofrecido < FLAG_VALE_CUATRO){
                    truco_disponible = partida.canto_ofrecido+1;
                    printf("\n\n3: %s!", nombreCanto(truco_disponible));
                }
                else if(partida.canto_ofrecido >= FLAG_ENVIDO && partida.canto_ofrecido < FLAG_FALTA_ENVIDO){

                    for(uint8_t i = partida.canto_ofrecido+1; i <= FLAG_FALTA_ENVIDO; i++){
                        printf("\n%u: %s", 6+i-FLAG_ENVIDO , nombreCanto(i));
                    }
                }
                printf("\n4: Quiero");
                printf("\n5: No Quiero");
                break;
            case ESTADO_PARTIDA_RONDA_ENVIDOS:
                    uint8_t envido = calcular_envido(&partida, jugador);
                    if(envido > partida.mayor_envido) printf("\n10: %u", envido);
                    if(partida.mayor_envido != 0) printf("\n11: Son buenas");
                break;
            default: break;
        }
        

        printf("\nAcción: ");

        uint8_t accion = 0;

        scanf("%u", &accion);

        ResultadoJugada resultado_jugada;

        if(accion >= 0 && accion <= 2) resultado_jugada = jugar_baza(&partida, jugador, accion);
        if(accion == 3) resultado_jugada = cantar(&partida, jugador, truco_disponible);
        if(accion == 4) resultado_jugada = cantar(&partida, jugador, CANTO_QUIERO);
        if(accion == 5) resultado_jugada = cantar(&partida, jugador, CANTO_NO_QUIERO);
        if(accion >= 6 && accion <= 9) resultado_jugada = cantar(&partida, jugador, (accion - 6) + FLAG_ENVIDO);
        if(accion == 10) cantar_tanto(&partida, jugador, calcular_envido(&partida, jugador));
        if(accion == 11) cantar(&partida, jugador, CANTO_SON_BUENAS);

        if(!resultado_jugada.eventos){
            printf("\nJugada inválida");
            continue;
        } 

        if(IS_BIT_SET(resultado_jugada.eventos, EVENTO_CARTA_JUGADA)){
            uint8_t carta_jugada_i = resultado_jugada.carta;
            if(carta_jugada_i == CARTA_INVALIDA){
                printf("Carta inválida\n\n");
                continue;
            }
            printf("Jugador %u jugó: %u de %s\n\n", numero_jugador, cartas[carta_jugada_i].valor_carta, 
            nombrePalo(cartas[carta_jugada_i].palo));
        }else if(IS_BIT_SET(resultado_jugada.eventos, EVENTO_CANTO)){
            printf("Jugador %u cantó: %s\n", numero_jugador, nombreCanto(resultado_jugada.canto));
        }


        if(IS_BIT_SET(resultado_jugada.eventos, EVENTO_RONDA_TERMINADA)){
            printf("%s %u gana la ronda.\n\n", jugador_o_equipo(jugadores), resultado_jugada.equipo_ganador+1);
            
            printf("%s 1: %u puntos === %s 2: %u puntos\n\n", jugador_o_equipo(jugadores), partida.equipos_puntos[0],
            jugador_o_equipo(jugadores), partida.equipos_puntos[1]);
        }

        if(IS_BIT_SET(resultado_jugada.eventos, EVENTO_VICTORIA)){
            printf("%s %u gana la partida.\n\n", jugador_o_equipo(jugadores), resultado_jugada.equipo_ganador+1);
        }
                
    }

    return 0;
}