#include <inttypes.h>
#include "str_helper.h"

void TCIC_turno_baza(uint8_t jugador_i){
    printf("\nTurno de jugador %" PRIu8 ".\n", jugador_i+1);
}

void TCIC_turno_canto(uint8_t jugador_i, uint8_t canto_i){
    printf("\nJugador %" PRIu8 " responde a %s.\n", jugador_i+1, nombreCanto(canto_i));
}

void TCIC_turno_tantos(uint8_t jugador_i){
    printf("\nTurno de jugador %" PRIu8 " de cantar sus tantos.\n", jugador_i+1);
}

void TCIC_render_carta(uint8_t carta_i){
    printf("%" PRIu8 " de %s ", 
    cartas[carta_i].valor_carta, 
    nombrePalo(cartas[carta_i].palo));
}

void TCIC_render_controles_carta(uint8_t carta_i, uint8_t carta_id, uint8_t control_i){
    printf("(%u) ", control_i);
    TCIC_render_carta(carta_id);
}

void TCIC_render_controles_canto(uint8_t canto_i, uint8_t control_i){
    printf("(%u) %s ", control_i, nombreCanto(canto_i));
}

void TCIC_render_controles_canto_tantos(uint8_t tantos, uint8_t control_i){
    printf("(%u) %u ", control_i, tantos);
}

void TCIC_render_jugada_invalida(uint8_t jugador_i){
    printf("Jugada inválida\n");
}

void TCIC_render_carta_jugada(uint8_t jugador_i, uint8_t carta_i){
    printf("\nJugador %u jugó: ", jugador_i+1);
    TCIC_render_carta(carta_i);
    printf("\n");
}

void TCIC_render_canto_realizado(uint8_t jugador_i, uint8_t canto_i){
    printf("\nJugador %u cantó: %s\n", jugador_i+1, nombreCanto(canto_i));
}

void TCIC_render_tantos_cantados(uint8_t jugador_i, uint8_t tantos){
    printf("\nJugador %u cantó: %u puntos de tantos.", jugador_i+1, tantos);
}

void TCIC_render_puntos_ganados(uint8_t numero_jugadores, uint8_t equipo_puntero, uint8_t puntos_ganados){
    printf("\n%s %u anotó %u puntos.", jugador_o_equipo(numero_jugadores), equipo_puntero+1, puntos_ganados);
}

void TCIC_render_puntaje(uint8_t numero_jugadores, uint8_t puntos_1, uint8_t puntos_2){
    printf("\n%s 1: %u puntos ======== %s 2: %u puntos\n", jugador_o_equipo(numero_jugadores), puntos_1,
    jugador_o_equipo(numero_jugadores), puntos_2);
}

void TCIC_render_victoria(uint8_t numero_jugadores, uint8_t equipo_i){
    printf("\n%s %u gana la partida.", jugador_o_equipo(numero_jugadores), equipo_i+1);
}

void TCIC_render_ronda_terminada(uint8_t numero_jugadores, uint8_t ganador_i){
    printf("\n%s %u gana la ronda.", jugador_o_equipo(numero_jugadores), ganador_i+1);
}

void TCIC_render_nueva_ronda(uint8_t jugador_mano){
    printf("\nEmpieza una nueva ronda. Jugador %u es mano.", jugador_mano+1);
}

void TCIC_render_nueva_baza(uint8_t baza_i){
    printf("\nComienza la baza %u\n", baza_i+1);
}

void TCIC_render_flag_activada(uint8_t flag_i){
    printf("\nFlag %u (%s) activada.", flag_i, nombreCanto(flag_i));
}

void TCIC_render_envido_no_disponible(){
    printf("\nEl envido ya no se encuentra disponible.");
}

void TCIC_render_flor_no_disponible(){
    printf("\nLa flor ya no se encuentra disponible.");
}

void TCIC_render_envido_en_mesa(uint8_t mayor_tanto){
    printf("\n%u en mesa: ", mayor_tanto);
}

void TCIC_render_carta_envido_en_mesa(uint8_t carta_i){
    TCIC_render_carta(carta_i);
}

void TCIC_render_tiene_retruco(uint8_t equipo_i){
    printf("\nEl %s %u tiene el retruco ahora.", jugador_o_equipo(equipo_i), equipo_i+1);
}

void TCIC_render_controles_mostrados(){
    printf("\n");
}

void TCIC_mostrando_controles_en_canto(EstadoPartida *partida){
    printf("\nTus cartas son: ");
    TCIC_render_cartas_disponibles_jugador(partida, obtener_jugador_turno_actual(partida));
}

void TCIC_avisar_accion(){
    printf("\nAcción: ");
}

uint8_t TCIC_recibir_input(){
    TCIC_avisar_accion();

    uint8_t accion = 0;
    scanf("%" SCNu8, &accion);
    return accion;
}

#define ANSI_RESET   "\033[0m"
#define ANSI_BOLD    "\033[1m"
#define ANSI_DIM     "\033[2m"
#define ANSI_RED     "\033[31m"
#define ANSI_GREEN   "\033[32m"
#define ANSI_YELLOW  "\033[33m"
#define ANSI_BLUE    "\033[34m"
#define ANSI_CYAN    "\033[36m"
#define ANSI_WHITE   "\033[97m"
#define ANSI_BG_GREEN "\033[42m"

#define UI_LINEA "================================================================================================="

static const char *ui_color_palo(uint8_t palo) {
    switch (palo) {
        case PALO_ESPADA: return ANSI_CYAN;
        case PALO_BASTO:  return ANSI_GREEN;
        case PALO_ORO:    return ANSI_YELLOW;
        case PALO_COPA:   return ANSI_RED;
        default:          return ANSI_RESET;
    }
}

#define UI_CARTA_ANCHO 11
#define UI_CARTA_ALTO  6

static void ui_dibujar_cartas(const uint8_t cartas_i[], uint8_t cantidad, uint8_t i_es_jugador) {
    for (uint8_t fila = 0; fila < UI_CARTA_ALTO; fila++) {
        for (uint8_t i = 0; i < cantidad; i++) {
            uint8_t carta_i = cartas_i[i];

            const Carta *carta = NULL;
            const char *color = ANSI_DIM;

            if (carta_i < TOTAL_CARTAS) {
                carta = &cartas[carta_i];
                color = ui_color_palo(carta->palo);
            }

            printf("%s", color);


            switch (fila){
                case 0:
                    printf("  +---------+ ");
                    break;

                case 1:
                    if (carta != NULL) printf("  | %-7s | ", nombrePalo(carta->palo));
                    else printf("  |         | ");
                    break;

                case 2:
                    if (carta != NULL) printf("  |    %2u   | ", carta->valor_carta);
                    else printf("  |   --    | ");
                    break;

                case 3:
                    printf("  |         | ");
                    break;

                case 4:
                    printf("  +---------+ ");
                    break;
                case 5:
                    if(i_es_jugador) printf("  ----J%u----- ", i+1);
                    break;
            }

            printf(ANSI_RESET);
        }

        printf("\n");
    }
}

void TCIC_dibujar_pantalla(EstadoPartida *estado_partida, uint8_t desde_jugador_i) {
    if (estado_partida == NULL) {
        return;
    }

    if (estado_partida->numero_jugadores > MAX_JUGADORES ||
        estado_partida->numero_jugadores == 0) {
        return;
    }

    uint8_t jugador_abajo = desde_jugador_i >= JUGADOR_INVALIDO
            ? obtener_jugador_turno_actual(estado_partida)
            : desde_jugador_i;

    printf(ANSI_DIM "  %s\n" ANSI_RESET, UI_LINEA);

    /* Marcador */
    printf(ANSI_BOLD "  MARCADOR\n" ANSI_RESET);

    printf("  Equipo 1: " ANSI_CYAN "%2u" ANSI_RESET, estado_partida->equipos_puntos[0]);

    printf("                  ");

    printf("Equipo 2: " ANSI_YELLOW "%2u" ANSI_RESET "\n", estado_partida->equipos_puntos[1]);

    printf("  Jugando a: %u puntos\n", estado_partida->max_puntos);

    printf("  Baza: %u/%u\n", estado_partida->baza_actual + 1, MAX_BAZAS_RONDA);

    printf(ANSI_DIM "  %s\n\n" ANSI_RESET, UI_LINEA);

    /* Jugadores */
    printf(ANSI_BOLD "  JUGADORES\n" ANSI_RESET);

    for (uint8_t i = 0; i < estado_partida->numero_jugadores; i++) {
        printf("  ");

        if (i == jugador_abajo) printf(ANSI_BG_GREEN ANSI_WHITE ANSI_BOLD " > JUGADOR %u " ANSI_RESET, i + 1);
        else printf("   JUGADOR %u", i + 1);

        if (i == estado_partida->jugador_mano) printf(" " ANSI_YELLOW "[MANO]" ANSI_RESET);


        if (i == estado_partida->jugador_turno_actual) printf(" " ANSI_CYAN "[TURNO]" ANSI_RESET);

        if(jugador_esta_en_mazo(estado_partida, i)) printf(" " ANSI_WHITE "[EN MAZO]" ANSI_RESET);

        printf("\n");
    }

    printf("\n" ANSI_DIM "  %s\n\n" ANSI_RESET, UI_LINEA);

    /* Mesa: cartas en horizontal */

    printf(ANSI_BOLD "  MESA\n\n" ANSI_RESET);

    for(uint8_t i = 0; i <= estado_partida->baza_actual; i++){
        if(i == estado_partida->baza_actual) printf(ANSI_BOLD "  BAZA %u [ACTUAL]\n\n" ANSI_RESET, estado_partida->baza_actual+1);
        else printf(ANSI_BOLD "  BAZA %u\n\n" ANSI_RESET, i+1);

        ui_dibujar_cartas(estado_partida->cartas_bazas[i], 
        estado_partida->numero_jugadores, 1);

        printf("\n\n");
    }

    printf("\n" ANSI_DIM "  %s\n\n" ANSI_RESET, UI_LINEA);



    /* Mano: cartas en horizontal */
    printf(ANSI_BOLD "  TU MANO - JUGADOR %u\n\n" ANSI_RESET,
           jugador_abajo + 1);

    ui_dibujar_cartas(estado_partida->jugadores_cartas[jugador_abajo], MAX_CARTAS_MANO, 0);

    /* Estado de la partida */
    printf("\n" ANSI_DIM "  %s\n" ANSI_RESET, UI_LINEA);
    // printf(ANSI_BOLD "  ESTADO DE LA PARTIDA\n" ANSI_RESET);

    // switch (estado_partida->ronda_estado) {
    //     case RONDA_ESTADO_JUGANDO_BAZA:
    //         printf("  Fase: jugando baza\n");
    //         break;

    //     case RONDA_ESTADO_EN_CANTO:
    //         printf("  Fase: respondiendo a canto\n");
    //         break;

    //     case RONDA_ESTADO_RONDA_TANTOS:
    //         printf("  Fase: ronda de tantos\n");
    //         break;

    //     default:
    //         printf("  Fase desconocida: %u\n",
    //                estado_partida->ronda_estado);
    //         break;
    // }

    if (estado_partida->ronda_estado == RONDA_ESTADO_EN_CANTO) {
        const char *canto =
            nombreCanto(estado_partida->canto_ofrecido);

        printf(ANSI_YELLOW ANSI_BOLD
               "  CANTO: %s\n" ANSI_RESET,
               canto != NULL ? canto : "PENDIENTE");
    }

    printf("\n");
}