package com.lona.tictactoe.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ClientHandler implements Runnable {
    private final Socket client;
    private PrintWriter out;
    private BufferedReader in;
    private String gameCode;

    public ClientHandler(Socket client) {
        this.client = client;
    }

    @Override
    public void run() {
        try {
            out = new PrintWriter(client.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(client.getInputStream()));

            // Send handshake / welcome
            out.println("WELCOME");

            String line;
            while ((line = in.readLine()) != null) {
                // Command processing
                String[] parts = line.split(" ");
                String cmd = parts[0].toUpperCase();

                switch (cmd) {
                    case "CREATE":
                        String newCode = GameManager.createGame(this);
                        this.gameCode = newCode;
                        out.println("GAME_CREATED " + newCode);
                        break;

                    case "JOIN":
                        if (parts.length < 2) {
                            out.println("ERROR: Missing game code");
                            break;
                        }
                        String code = parts[1];
                        GameInstance game = GameManager.getGame(code);
                        if (game != null) {
                            if (game.join(this)) {
                                this.gameCode = code;
                                out.println("JOIN_SUCCESS");
                            } else {
                                out.println("ERROR: Game full or already started");
                            }
                        } else {
                            out.println("ERROR: Game not found");
                        }
                        break;

                    case "MOVE":
                        if (gameCode == null) {
                            out.println("ERROR: Not in a game");
                            break;
                        }
                        GameInstance g = GameManager.getGame(gameCode);
                        if (g == null) {
                            out.println("ERROR: Game ended");
                            break;
                        }
                        if (parts.length < 3) {
                            out.println("ERROR: Missing coordinates");
                            break;
                        }
                        try {
                            int r = Integer.parseInt(parts[1]);
                            int c = Integer.parseInt(parts[2]);
                            g.move(this, r, c);
                        } catch (NumberFormatException e) {
                            out.println("ERROR: Invalid coordinates");
                        }
                        break;

                    case "SURRENDER":
                        if (gameCode != null) {
                            GameInstance active = GameManager.getGame(gameCode);
                            if (active != null)
                                active.surrender(this);
                        }
                        break;

                    case "RESTART":
                        if (gameCode != null) {
                            GameInstance active = GameManager.getGame(gameCode);
                            if (active != null)
                                active.restart();
                        }
                        break;

                    case "LEAVE":
                        if (gameCode != null) {
                            GameInstance active = GameManager.getGame(gameCode);
                            if (active != null) {
                                active.leave(this);
                                if (active.isEmpty()) {
                                    GameManager.removeGame(gameCode);
                                }
                            }
                            this.gameCode = null;
                        }
                        break;

                    default:
                        out.println("ERROR: Unknown command");
                }
            }
        } catch (IOException e) {
            System.err.println("Client disconnected unexpectedly: " + e.getMessage());
        } finally {
            if (gameCode != null) {
                GameInstance g = GameManager.getGame(gameCode);
                if (g != null) {
                    g.disconnect(this);
                    if (g.isEmpty()) {
                        GameManager.removeGame(gameCode);
                    }
                }
            }
            try {
                client.close();
            } catch (IOException e) {
                // ignore
            }
        }
    }

    public void sendMessage(String msg) {
        if (out != null) {
            out.println(msg);
        }
    }
}
