package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;

import java.util.Random;

public class AbsurdCityBuilder1 extends ApplicationAdapter {
    // Константы
    private static final int WIDTH = GameConfig.WIDTH;
    private static final int HEIGHT = GameConfig.HEIGHT;
    private static final int UI_INPUT_HEIGHT = GameConfig.UI_INPUT_HEIGHT;

    // Основные объекты
    private SpriteBatch batch;
    private ShapeRenderer shapeRenderer;
    private OrthographicCamera camera;
    private Viewport viewport;
    private BitmapFont font;
    private GlyphLayout glyphLayout;
    private Texture whitePixel;

    // Игровые объекты
    private Array<Building> buildings;
    private Building currentBuilding;
    private MathProblem currentProblem;
    private Random random;
    private Array<Citizen> citizens;
    private Array<JokeBubble> jokeBubbles;

    // Переменные игры
    private float time = 0;
    private boolean showWrongAnswerJoke = false;
    private String wrongAnswerJoke = "";
    private float jokeTimer = 0;

    // UI переменные
    private int selectedBuildingType = 0;
    private StringBuilder inputText = new StringBuilder();
    private boolean isTyping = false;
    private String messageText = "";
    private Color messageColor = Color.WHITE;
    private String problemText = "";

    // Текстуры и рендереры
    private Texture backgroundTexture;
    private BuildingRenderer buildingRenderer;
    private UIRenderer uiRenderer;
    private MenuRenderer menuRenderer;

    // Достижения
    private AchievementPopup achievementPopup;

    // Планета
    private Planet currentPlanet;
    private float planetSwitchTimer = 0;
    private boolean isSwitchingPlanets = false;
    private Planet targetPlanet;

    // Состояние игры
    private GameState gameState = GameState.MAIN_MENU;
    private boolean wasJustClicked = false;

    @Override
    public void create() {
        batch = new SpriteBatch();
        shapeRenderer = new ShapeRenderer();

        GameAssets.createFonts();
        font = GameAssets.getFont();
        glyphLayout = new GlyphLayout();
        whitePixel = GameAssets.createWhitePixel();

        camera = new OrthographicCamera();
        viewport = new FitViewport(WIDTH, HEIGHT, camera);
        viewport.apply();
        camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);

        random = new Random();
        buildings = new Array<>();
        citizens = new Array<>();
        jokeBubbles = new Array<>();

        // Начинаем с Земли
        currentPlanet = Planet.EARTH;

        // Загружаем настройки и достижения
        GameSave.loadSettings();

        try {
            backgroundTexture = new Texture(Gdx.files.internal("фон4.png"));
        } catch (Exception e) {
            backgroundTexture = null;
        }

        buildingRenderer = new BuildingRenderer(shapeRenderer, batch, font, glyphLayout, whitePixel);
        uiRenderer = new UIRenderer(batch, font, glyphLayout, whitePixel, WIDTH, HEIGHT, UI_INPUT_HEIGHT);
        menuRenderer = new MenuRenderer(batch, font, glyphLayout, whitePixel, WIDTH, HEIGHT);
        achievementPopup = new AchievementPopup();

        // Устанавливаем начальные сообщения
        messageText = Localization.welcomeTo(currentPlanet);
        problemText = Localization.isRu() ? "Нажмите ESC для возврата в меню" : "Press ESC to return to menu";

        updateUI();
    }

    @Override
    public void render() {
        handleInput();
        update();

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();
        batch.setProjectionMatrix(camera.combined);
        shapeRenderer.setProjectionMatrix(camera.combined);

        switch (gameState) {
            case MAIN_MENU:
                renderMainMenu();
                break;
            case PLANET_SELECT:
                renderPlanetSelect();
                break;
            case HELP:
                renderHelp();
                break;
            case ABOUT:
                renderAbout();
                break;
            case ACHIEVEMENTS:
                renderAchievements();
                break;
            case PLAYING:
                renderGame();
                break;
        }

        // Рендер уведомления о достижении поверх всего
        if (achievementPopup.isActive()) {
            achievementPopup.render(batch, font, glyphLayout, whitePixel, WIDTH, HEIGHT);
        }
    }

    private void handleInput() {
        // Обработка кликов мыши
        boolean isClicked = Gdx.input.justTouched();
        float mouseX = Gdx.input.getX();
        float mouseY = HEIGHT - Gdx.input.getY(); // Инвертируем Y

        // ESC для возврата в меню из игры
        if (Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)) {
            if (gameState == GameState.PLAYING) {
                if (isTyping) {
                    // Отмена ввода
                    setTyping(false);
                    getInputText().setLength(0);
                    setMessageText(Localization.inputCanceled());
                    setMessageColor(Color.YELLOW);
                } else {
                    // Возврат в главное меню с сохранением
                    GameSave.save(this);
                    gameState = GameState.MAIN_MENU;
                }
            } else if (gameState != GameState.MAIN_MENU) {
                // Возврат в главное меню из других состояний
                gameState = GameState.MAIN_MENU;
            }
        }

        // Обработка состояний меню
        switch (gameState) {
            case MAIN_MENU:
                handleMainMenuInput(mouseX, mouseY, isClicked);
                break;
            case PLANET_SELECT:
                handlePlanetSelectInput(mouseX, mouseY, isClicked);
                break;
            case HELP:
                handleHelpInput(mouseX, mouseY, isClicked);
                break;
            case ABOUT:
                handleAboutInput(mouseX, mouseY, isClicked);
                break;
            case ACHIEVEMENTS:
                handleAchievementsInput(mouseX, mouseY, isClicked);
                break;
            case PLAYING:
                InputHandler.handleInput(this);
                break;
        }

        wasJustClicked = isClicked;
    }

    private void handleMainMenuInput(float mouseX, float mouseY, boolean isClicked) {
        if (isClicked) {
            // Проверяем клик на переключатель языка
            if (menuRenderer.checkLanguageClick(mouseX, mouseY)) {
                Localization.toggleLanguage();
                GameSave.saveSettings();
                menuRenderer.refreshMenuTexts();
                return;
            }

            MenuButton clickedButton = menuRenderer.getMainMenuButtonAt(mouseX, mouseY);
            if (clickedButton != null) {
                String buttonText = clickedButton.getText();

                if (buttonText.contains("ПРОДОЛЖИТЬ") || buttonText.contains("CONTINUE")) {
                    continueGame();
                } else if (buttonText.contains("НОВАЯ") || buttonText.contains("NEW")) {
                    startNewGame();
                } else if (buttonText.contains("ПЛАНЕТ") || buttonText.contains("PLANET")) {
                    gameState = GameState.PLANET_SELECT;
                } else if (buttonText.contains("ДОСТИЖЕНИЯ") || buttonText.contains("ACHIEVEMENTS")) {
                    gameState = GameState.ACHIEVEMENTS;
                } else if (buttonText.contains("ПОМОЩЬ") || buttonText.contains("HELP")) {
                    gameState = GameState.HELP;
                } else if (buttonText.contains("ВЫХОД") || buttonText.contains("EXIT")) {
                    GameSave.saveSettings();
                    Gdx.app.exit();
                }
            }
        }
    }

    private void handlePlanetSelectInput(float mouseX, float mouseY, boolean isClicked) {
        if (isClicked) {
            MenuButton clickedButton = menuRenderer.getPlanetSelectButtonAt(mouseX, mouseY);
            if (clickedButton != null) {
                String buttonText = clickedButton.getText();

                if (buttonText.contains("ЗЕМЛЯ") || buttonText.contains("EARTH")) {
                    startNewGameOnPlanet(Planet.EARTH);
                } else if (buttonText.contains("МАРС") || buttonText.contains("MARS")) {
                    startNewGameOnPlanet(Planet.MARS);
                } else if (buttonText.contains("ВЕНЕРА") || buttonText.contains("VENUS")) {
                    startNewGameOnPlanet(Planet.VENUS);
                } else if (buttonText.contains("НАЗАД") || buttonText.contains("BACK")) {
                    gameState = GameState.MAIN_MENU;
                }
            }
        }
    }

    private void handleHelpInput(float mouseX, float mouseY, boolean isClicked) {
        if (isClicked) {
            MenuButton clickedButton = menuRenderer.getHelpButtonAt(mouseX, mouseY);
            if (clickedButton != null) {
                gameState = GameState.MAIN_MENU;
            }
        }
    }

    private void handleAboutInput(float mouseX, float mouseY, boolean isClicked) {
        if (isClicked) {
            // Простая проверка на кнопку "Назад"
            if (mouseX >= 50 && mouseX <= 250 && mouseY >= 50 && mouseY <= 110) {
                gameState = GameState.MAIN_MENU;
            }
        }
    }

    private void handleAchievementsInput(float mouseX, float mouseY, boolean isClicked) {
        if (isClicked) {
            MenuButton clickedButton = menuRenderer.getAchievementsButtonAt(mouseX, mouseY);
            if (clickedButton != null) {
                gameState = GameState.MAIN_MENU;
            }
        }
    }

    private void continueGame() {
        // Загружаем сохранение и продолжаем игру
        GameSave.load(this);
        
        // Загружаем здания и жителей
        jokeBubbles.clear();
        currentBuilding = null;
        currentProblem = null;
        selectedBuildingType = 0;
        inputText.setLength(0);
        isTyping = false;
        isSwitchingPlanets = false;
        
        // Загружаем сохранённые здания
        GameSave.loadBuildings(buildings, citizens, random);

        // Отмечаем посещение текущей планеты
        Achievements.visitPlanet(currentPlanet);

        // Показываем прогресс
        String progressInfo = Localization.isRu() 
            ? " (Загружено зданий: " + buildings.size + ")"
            : " (Loaded buildings: " + buildings.size + ")";
        messageText = Localization.welcomeTo(currentPlanet) + progressInfo;
        messageColor = Color.GREEN;

        gameState = GameState.PLAYING;
        updateUI();
    }

    private void startNewGame() {
        // Сбрасываем ВСЮ статистику для новой игры
        GameSave.resetAll();
        Achievements.reset();
        
        // Очищаем всё и начинаем новую игру на Земле
        buildings.clear();
        citizens.clear();
        jokeBubbles.clear();
        currentBuilding = null;
        currentProblem = null;
        selectedBuildingType = 0;
        inputText.setLength(0);
        isTyping = false;

        currentPlanet = Planet.EARTH;
        isSwitchingPlanets = false;

        // Отмечаем посещение Земли
        Achievements.visitPlanet(Planet.EARTH);

        messageText = Localization.welcomeTo(currentPlanet);
        messageColor = Color.GREEN;

        gameState = GameState.PLAYING;
        updateUI();
    }

    private void startNewGameOnPlanet(Planet planet) {
        // Очищаем всё и начинаем новую игру на выбранной планете
        buildings.clear();
        citizens.clear();
        jokeBubbles.clear();
        currentBuilding = null;
        currentProblem = null;
        selectedBuildingType = 0;
        inputText.setLength(0);
        isTyping = false;

        currentPlanet = planet;
        isSwitchingPlanets = false;

        // Отмечаем посещение планеты
        Achievements.visitPlanet(planet);

        messageText = Localization.welcomeTo(planet);
        messageColor = Color.GREEN;

        gameState = GameState.PLAYING;
        updateUI();
    }

    private void update() {
        float deltaTime = Gdx.graphics.getDeltaTime();
        time += deltaTime;

        // Обновляем меню
        menuRenderer.update(deltaTime);

        // Обновляем уведомление о достижении
        achievementPopup.update(deltaTime);

        // Проверяем новые достижения
        if (Achievements.hasNewUnlock()) {
            Achievement newAchievement = Achievements.getLastUnlocked();
            if (newAchievement != null && !achievementPopup.isActive()) {
                achievementPopup.show(newAchievement);
                GameSave.saveSettings();
            }
        }

        // Обработка плавной смены планет
        if (isSwitchingPlanets) {
            planetSwitchTimer += deltaTime;
            if (planetSwitchTimer >= 1.0f) {
                currentPlanet = targetPlanet;
                isSwitchingPlanets = false;
                
                // Отмечаем посещение новой планеты и сохраняем
                Achievements.visitPlanet(currentPlanet);
                Achievements.check(this);
                GameSave.savePlanet(currentPlanet);
                GameSave.saveSettings();
                
                setMessageText(Localization.welcomeTo(currentPlanet));
            }
        }

        if (gameState == GameState.PLAYING) {
            for (Building b : buildings) {
                b.update(deltaTime);
            }
            if (currentBuilding != null) {
                currentBuilding.update(deltaTime);
            }

            // Обновляем жителей
            for (Citizen citizen : citizens) {
                citizen.update(deltaTime);
            }

            // Обновляем пузыри с шутками
            for (int i = jokeBubbles.size - 1; i >= 0; i--) {
                JokeBubble bubble = jokeBubbles.get(i);
                bubble.update(deltaTime);
                if (bubble.isExpired()) {
                    jokeBubbles.removeIndex(i);
                }
            }

            // Обновляем таймер шутки
            if (showWrongAnswerJoke) {
                jokeTimer += deltaTime;
                if (jokeTimer > 3.0f) {
                    showWrongAnswerJoke = false;
                }
            }
        }
    }

    public void checkAnswer() {
        AnswerChecker.checkAnswer(this);
    }

    public void startPlanetSwitch(Planet newPlanet) {
        if (currentPlanet == newPlanet || isSwitchingPlanets) return;

        isSwitchingPlanets = true;
        targetPlanet = newPlanet;
        planetSwitchTimer = 0;

        // Очищаем город при смене планеты
        buildings.clear();
        citizens.clear();
        jokeBubbles.clear();
        currentBuilding = null;
        currentProblem = null;
        selectedBuildingType = 0;

        setMessageText(Localization.flying(newPlanet));
        setMessageColor(Color.YELLOW);
        updateUI();
    }

    public void updateUI() {
        UIUpdater.updateUI(this);
    }

    private void renderMainMenu() {
        float mouseX = Gdx.input.getX();
        float mouseY = HEIGHT - Gdx.input.getY();
        menuRenderer.renderMainMenu(mouseX, mouseY);
    }

    private void renderPlanetSelect() {
        float mouseX = Gdx.input.getX();
        float mouseY = HEIGHT - Gdx.input.getY();
        menuRenderer.renderPlanetSelect(mouseX, mouseY);
    }

    private void renderHelp() {
        float mouseX = Gdx.input.getX();
        float mouseY = HEIGHT - Gdx.input.getY();
        menuRenderer.renderHelp(mouseX, mouseY);
    }

    private void renderAbout() {
        float mouseX = Gdx.input.getX();
        float mouseY = HEIGHT - Gdx.input.getY();
        menuRenderer.renderAbout(mouseX, mouseY);
    }

    private void renderAchievements() {
        float mouseX = Gdx.input.getX();
        float mouseY = HEIGHT - Gdx.input.getY();
        menuRenderer.renderAchievements(mouseX, mouseY);
    }

    private void renderGame() {
        renderBackground();
        renderBuildings();
        renderCitizens();
        renderJokeBubbles();
        renderBuildingNames();
        renderPlanetTransition();
        renderUI();
    }

    private void renderBackground() {
        batch.begin();

        Color bgColor;
        if (isSwitchingPlanets) {
            // Плавный переход между цветами
            Color fromColor = currentPlanet.getColor();
            Color toColor = targetPlanet.getColor();
            float progress = Math.min(planetSwitchTimer * 2, 1.0f);

            bgColor = new Color(
                fromColor.r + (toColor.r - fromColor.r) * progress,
                fromColor.g + (toColor.g - fromColor.g) * progress,
                fromColor.b + (toColor.b - fromColor.b) * progress,
                1
            );
        } else {
            bgColor = currentPlanet.getColor();
        }

        if (backgroundTexture != null) {
            batch.setColor(bgColor);
            batch.draw(backgroundTexture, 0, UI_INPUT_HEIGHT, WIDTH, HEIGHT - UI_INPUT_HEIGHT);
            batch.setColor(Color.WHITE);
        } else {
            batch.setColor(bgColor);
            batch.draw(whitePixel, 0, UI_INPUT_HEIGHT, WIDTH, HEIGHT - UI_INPUT_HEIGHT);
            batch.setColor(Color.WHITE);
        }

        batch.end();
    }

    private void renderBuildings() {
        buildingRenderer.renderBuildings(buildings, currentBuilding, time, currentPlanet);
    }

    private void renderCitizens() {
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        for (Citizen citizen : citizens) {
            citizen.draw(shapeRenderer, time);
        }
        shapeRenderer.end();
    }

    private void renderJokeBubbles() {
        for (JokeBubble bubble : jokeBubbles) {
            bubble.draw(batch, shapeRenderer, font, glyphLayout, whitePixel);
        }
    }

    private void renderBuildingNames() {
        buildingRenderer.renderBuildingNames(buildings, currentBuilding);
    }

    private void renderPlanetTransition() {
        if (!isSwitchingPlanets) return;

        batch.begin();

        // Затемнение экрана
        float alpha = Math.min(planetSwitchTimer * 2, 1.0f);
        batch.setColor(0, 0, 0, alpha * 0.7f);
        batch.draw(whitePixel, 0, 0, WIDTH, HEIGHT);

        // Текст перехода
        font.setColor(1, 1, 1, alpha);
        font.getData().setScale(1.5f);

        String transitionText;
        if (planetSwitchTimer < 0.5f) {
            transitionText = Localization.leaving(currentPlanet);
        } else {
            transitionText = Localization.arriving(targetPlanet);
        }

        glyphLayout.setText(font, transitionText);
        font.draw(batch, transitionText,
            WIDTH/2 - glyphLayout.width/2,
            HEIGHT/2 + 50);

        font.getData().setScale(1.0f);
        batch.end();
    }

    private void renderUI() {
        uiRenderer.renderUI(selectedBuildingType, problemText, messageText, messageColor,
            isTyping, currentProblem, inputText.toString(), showWrongAnswerJoke,
            wrongAnswerJoke, time, currentBuilding, currentPlanet, isSwitchingPlanets);
    }

    @Override
    public void resize(int width, int height) {
        viewport.update(width, height);
    }

    @Override
    public void dispose() {
        // Сохраняем настройки при выходе
        GameSave.saveSettings();
        
        batch.dispose();
        shapeRenderer.dispose();
        font.dispose();
        if (backgroundTexture != null) {
            backgroundTexture.dispose();
        }
        if (whitePixel != null) {
            whitePixel.dispose();
        }
        menuRenderer.dispose();
    }

    // Геттеры и сеттеры
    public int getWIDTH() { return WIDTH; }
    public int getHEIGHT() { return HEIGHT; }
    public int getUI_INPUT_HEIGHT() { return UI_INPUT_HEIGHT; }
    public int getSelectedBuildingType() { return selectedBuildingType; }
    public void setSelectedBuildingType(int selectedBuildingType) { this.selectedBuildingType = selectedBuildingType; }
    public StringBuilder getInputText() { return inputText; }
    public boolean isTyping() { return isTyping; }
    public void setTyping(boolean typing) { isTyping = typing; }
    public String getMessageText() { return messageText; }
    public void setMessageText(String messageText) { this.messageText = messageText; }
    public Color getMessageColor() { return messageColor; }
    public void setMessageColor(Color messageColor) { this.messageColor = messageColor; }
    public String getProblemText() { return problemText; }
    public void setProblemText(String problemText) { this.problemText = problemText; }
    public Array<Building> getBuildings() { return buildings; }
    public Building getCurrentBuilding() { return currentBuilding; }
    public void setCurrentBuilding(Building currentBuilding) { this.currentBuilding = currentBuilding; }
    public MathProblem getCurrentProblem() { return currentProblem; }
    public void setCurrentProblem(MathProblem currentProblem) { this.currentProblem = currentProblem; }
    public Random getRandom() { return random; }
    public Array<Citizen> getCitizens() { return citizens; }
    public Array<JokeBubble> getJokeBubbles() { return jokeBubbles; }
    public boolean isShowWrongAnswerJoke() { return showWrongAnswerJoke; }
    public void setShowWrongAnswerJoke(boolean showWrongAnswerJoke) { this.showWrongAnswerJoke = showWrongAnswerJoke; }
    public String getWrongAnswerJoke() { return wrongAnswerJoke; }
    public void setWrongAnswerJoke(String wrongAnswerJoke) { this.wrongAnswerJoke = wrongAnswerJoke; }
    public float getJokeTimer() { return jokeTimer; }
    public void setJokeTimer(float jokeTimer) { this.jokeTimer = jokeTimer; }
    public Texture getWhitePixel() { return whitePixel; }
    public BitmapFont getFont() { return font; }
    public GlyphLayout getGlyphLayout() { return glyphLayout; }
    public ShapeRenderer getShapeRenderer() { return shapeRenderer; }
    public SpriteBatch getBatch() { return batch; }
    public float getTime() { return time; }
    public Planet getCurrentPlanet() { return currentPlanet; }
    public void setCurrentPlanet(Planet planet) { this.currentPlanet = planet; }
    public boolean isSwitchingPlanets() { return isSwitchingPlanets; }
    public Planet getTargetPlanet() { return targetPlanet; }
    public float getPlanetSwitchTimer() { return planetSwitchTimer; }
    public GameState getGameState() { return gameState; }
    public void setGameState(GameState state) { this.gameState = state; }
}
