// ============================================================================
// TIC-TAC-TOE GAME IMPLEMENTATION
// ============================================================================
// Game logic, input handling, and rendering for Tic-Tac-Toe

#include "tic_tac_toe.h"
#include "input_manager.h"
#include <stdio.h>
#include <string.h>

// Font reference from display system
extern Font font_5x5_obj;

TicTacToeGame::TicTacToeGame(uint16_t width, uint16_t height, LowLevelRenderer* renderer, LowLevelGUI* gui, InputManager* input_manager)
    : Game(width, height, renderer, gui, input_manager) {
    // Initialize statistics to zero
    state.x_wins = 0;
    state.o_wins = 0;
    state.ties = 0;
}

void TicTacToeGame::init() {
    // Clear the board
    for (int row = 0; row < 3; row++) {
        for (int col = 0; col < 3; col++) {
            state.board[row][col] = 0;
        }
    }
    
    state.current_player = 1;  // X starts
    state.winner = 0;
    state.selected_row = 1;    // Start in center
    state.selected_col = 1;
    state.game_over = false;
    state.total_moves = 0;
    
    // Keep win statistics across games
    // state.x_wins, state.o_wins, state.ties remain unchanged
}

uint8_t TicTacToeGame::check_winner() {
    // Check rows
    for (int row = 0; row < 3; row++) {
        if (state.board[row][0] != 0 && 
            state.board[row][0] == state.board[row][1] && 
            state.board[row][1] == state.board[row][2]) {
            return state.board[row][0];
        }
    }
    
    // Check columns
    for (int col = 0; col < 3; col++) {
        if (state.board[0][col] != 0 && 
            state.board[0][col] == state.board[1][col] && 
            state.board[1][col] == state.board[2][col]) {
            return state.board[0][col];
        }
    }
    
    // Check diagonals
    if (state.board[0][0] != 0 && 
        state.board[0][0] == state.board[1][1] && 
        state.board[1][1] == state.board[2][2]) {
        return state.board[0][0];
    }
    
    if (state.board[0][2] != 0 && 
        state.board[0][2] == state.board[1][1] && 
        state.board[1][1] == state.board[2][0]) {
        return state.board[0][2];
    }
    
    // Check for tie (board full)
    bool board_full = true;
    for (int row = 0; row < 3; row++) {
        for (int col = 0; col < 3; col++) {
            if (state.board[row][col] == 0) {
                board_full = false;
                break;
            }
        }
        if (!board_full) break;
    }
    
    if (board_full) return 3; // Tie
    return 0; // No winner yet
}

bool TicTacToeGame::update(const InputEvent& event) {
    bool needs_refresh = false;
    
    switch (event.type) {
        case INPUT_TOUCH_DOWN: {
            // If game is over, restart on touch
            if (state.game_over) {
                init();
                needs_refresh = true;
                break;
            }

            printf("Touch down at (%d,%d)\n", event.x, event.y);
            
            // Calculate board position (must match draw()!)
            int board_x = width - BOARD_SIZE - 20;
            
            // Check if touch is within board
            if (event.x >= board_x && event.x < board_x + BOARD_SIZE &&
                event.y >= BOARD_Y && event.y < BOARD_Y + BOARD_SIZE) {
                
                int touched_col = (event.x - board_x) / CELL_SIZE;
                int touched_row = (event.y - BOARD_Y) / CELL_SIZE;
                
                // Clamp to valid range (safety check)
                if (touched_row >= 0 && touched_row < 3 && touched_col >= 0 && touched_col < 3) {
                    // Place piece if cell is empty
                    if (state.board[touched_row][touched_col] == 0) {
                        state.board[touched_row][touched_col] = state.current_player;
                        state.total_moves++;
                        
                        // Check for winner
                        state.winner = check_winner();
                        if (state.winner != 0) {
                            state.game_over = true;
                            if (state.winner == 1) state.x_wins++;
                            else if (state.winner == 2) state.o_wins++;
                            else if (state.winner == 3) state.ties++;
                        } else {
                            // Switch player
                            state.current_player = (state.current_player == 1) ? 2 : 1;
                        }
                        
                        needs_refresh = true;
                        
                        printf("Touch at [%d,%d] (pixel %d,%d) by player %d\n", 
                               touched_row, touched_col, event.x, event.y,
                               state.current_player == 1 ? 2 : 1);
                    } else {
                        printf("Cell [%d,%d] already occupied\n", touched_row, touched_col);
                    }
                }
            } else {
                printf("Touch outside board: %d,%d\n", event.x, event.y);
            }
            break;
        }
            
        case INPUT_BUTTON_0:
            // KEY0: Move selection (for button-only boards)
            if (!state.game_over) {
                // Move to next cell, skipping occupied ones
                int attempts = 0;
                do {
                    state.selected_col++;
                    if (state.selected_col > 2) {
                        state.selected_col = 0;
                        state.selected_row++;
                        if (state.selected_row > 2) {
                            state.selected_row = 0;
                        }
                    }
                    attempts++;
                    // If we've tried all 9 cells, stop (game might be full)
                    if (attempts >= 9) break;
                } while (state.board[state.selected_row][state.selected_col] != 0);
                
                needs_refresh = true;
                printf("Selection moved to [%d,%d]\n", state.selected_row, state.selected_col);
            } else {
                // Restart game
                init();
                needs_refresh = true;
            }
            break;
            
        case INPUT_BUTTON_1:
            // KEY1: Place piece at selected position
            if (!state.game_over) {
                if (state.board[state.selected_row][state.selected_col] == 0) {
                    state.board[state.selected_row][state.selected_col] = state.current_player;
                    state.total_moves++;
                    
                    // Check for winner
                    state.winner = check_winner();
                    if (state.winner != 0) {
                        state.game_over = true;
                        if (state.winner == 1) state.x_wins++;
                        else if (state.winner == 2) state.o_wins++;
                        else if (state.winner == 3) state.ties++;
                    } else {
                        // Switch player
                        state.current_player = (state.current_player == 1) ? 2 : 1;
                    }
                    
                    needs_refresh = true;
                    
                    printf("Piece placed at [%d,%d]\n", state.selected_row, state.selected_col);
                }
            }
            break;
            
        default:
            break;
    }
    
    return needs_refresh;
}

void TicTacToeGame::draw() {
    // Draw main window
    LowLevelWindow *w1 = gui->draw_new_window(10, 10, width - 20, height - 20, "Tic-Tac-Toe");
    
    renderer->set_font(&font_5x5_obj);
    
    // Draw current player or game result
    if (state.game_over) {
        if (state.winner == 1) {
            renderer->draw_string(20, 40, "X WINS!", true);
        } else if (state.winner == 2) {
            renderer->draw_string(20, 40, "O WINS!", true);
        } else {
            renderer->draw_string(20, 40, "TIE GAME!", true);
        }
        if (input_manager->has_buttons()) {
            renderer->draw_string(20, 55, "Touch or KEY0 to restart", true);
        } else {
            renderer->draw_string(20, 55, "Touch to restart", true);
        }
    } else {
        char turn_text[30];
        snprintf(turn_text, sizeof(turn_text), "Turn: %s", state.current_player == 1 ? "X" : "O");
        renderer->draw_string(20, 40, turn_text, true);
        if (input_manager->has_buttons()) {
            renderer->draw_string(20, 55, "Touch cell or use keys", true);
        } else {
            renderer->draw_string(20, 55, "Touch cell to play", true);
        }
    }
    
    // Draw game board (use same layout as touch detection!)
    int board_x = width - BOARD_SIZE - 20;
    
    // Draw current turn indicator (large, on left side)
    if (!state.game_over) {
        int indicator_x = 60;
        int indicator_y = height / 2;
        int piece_offset = CELL_SIZE / 4;
        
        if (state.current_player == 1) {
            // Draw large X
            renderer->draw_line(indicator_x - piece_offset, indicator_y - piece_offset,
                              indicator_x + piece_offset, indicator_y + piece_offset, true, 4);
            renderer->draw_line(indicator_x + piece_offset, indicator_y - piece_offset,
                              indicator_x - piece_offset, indicator_y + piece_offset, true, 4);
        } else {
            // Draw large O
            int piece_radius = CELL_SIZE / 4;
            renderer->draw_circle(indicator_x, indicator_y, piece_radius, true);
            renderer->draw_circle(indicator_x, indicator_y, piece_radius - 1, true);
            renderer->draw_circle(indicator_x, indicator_y, piece_radius - 2, true);
            renderer->draw_circle(indicator_x, indicator_y, piece_radius - 3, true);
        }
    }
    
    // Draw grid lines
    for (int i = 1; i < 3; i++) {
        // Vertical lines
        renderer->draw_line(board_x + i * CELL_SIZE, BOARD_Y, 
                          board_x + i * CELL_SIZE, BOARD_Y + BOARD_SIZE, true, 2);
        // Horizontal lines
        renderer->draw_line(board_x, BOARD_Y + i * CELL_SIZE,
                          board_x + BOARD_SIZE, BOARD_Y + i * CELL_SIZE, true, 2);
    }
    
    // Draw outer border
    renderer->draw_rectangle(board_x, BOARD_Y, BOARD_SIZE, BOARD_SIZE, true, 3);
    
    // Draw X's and O's
    for (int row = 0; row < 3; row++) {
        for (int col = 0; col < 3; col++) {
            int cell_x = board_x + col * CELL_SIZE;
            int cell_y = BOARD_Y + row * CELL_SIZE;
            int center_x = cell_x + CELL_SIZE / 2;
            int center_y = cell_y + CELL_SIZE / 2;
            
            // Highlight selected cell (for button navigation)
            if (!state.game_over && row == state.selected_row && col == state.selected_col) {
                renderer->draw_rectangle(cell_x + 5, cell_y + 5, CELL_SIZE - 10, CELL_SIZE - 10, true, 1);
            }
            
            if (state.board[row][col] == 1) {
                // Draw X
                int offset = CELL_SIZE / 4;
                renderer->draw_line(center_x - offset, center_y - offset,
                                  center_x + offset, center_y + offset, true, 3);
                renderer->draw_line(center_x + offset, center_y - offset,
                                  center_x - offset, center_y + offset, true, 3);
            } else if (state.board[row][col] == 2) {
                // Draw O
                int radius = CELL_SIZE / 4;
                renderer->draw_circle(center_x, center_y, radius, true);
                renderer->draw_circle(center_x, center_y, radius - 1, true);
                renderer->draw_circle(center_x, center_y, radius - 2, true);
            }
        }
    }
    
    // Draw statistics at bottom
    char stats[60];
    snprintf(stats, sizeof(stats), "X:%d  O:%d  Tie:%d  Moves:%d", 
             state.x_wins, state.o_wins, state.ties, state.total_moves);
    renderer->draw_string(20, height - 40, stats, true);
}
