package wtf.beatrice.retrorender.engine.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
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.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.math.MathUtils;
import wtf.beatrice.retrorender.engine.config.GameSettings;

public class SettingsMenu {

    private final SpriteBatch batch;
    private final BitmapFont font;
    private final BitmapFont boldFont;
    private final Texture pixel;

    private final GameSettings settings;

    private boolean bobbingEnabled = true;

    // button / hit areas
    private float fovDecX, fovDecY, fovDecW, fovDecH;
    private float fovIncX, fovIncY, fovIncW, fovIncH;
    private float closeX,  closeY,  closeW,  closeH;

    public SettingsMenu(GameSettings settings) {
        this.settings = settings;

        batch = new SpriteBatch();

        FreeTypeFontGenerator generator =
            new FreeTypeFontGenerator(Gdx.files.internal("fonts/red-hat-mono.ttf"));
        FreeTypeFontGenerator.FreeTypeFontParameter param =
            new FreeTypeFontGenerator.FreeTypeFontParameter();

        param.size = 12;
        param.color = Color.WHITE;
        param.mono = true;
        param.hinting = FreeTypeFontGenerator.Hinting.None;
        param.borderWidth = 0f;
        param.borderColor = Color.WHITE;
        param.shadowOffsetX = 0;
        param.shadowOffsetY = 0;
        param.minFilter = Texture.TextureFilter.Nearest;
        param.magFilter = Texture.TextureFilter.Nearest;

        font = generator.generateFont(param);

        param.borderWidth = 0.2f;
        boldFont = generator.generateFont(param);

        generator.dispose();

        // 1x1 pixel
        Pixmap pm = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
        pm.setColor(1f, 1f, 1f, 1f);
        pm.fill();
        pixel = new Texture(pm);
        pm.dispose();
    }

    public void setFov(float fov) {
        settings.fov = MathUtils.clamp(fov, settings.minFov, settings.maxFov);
    }

    public float getFov() {
        return settings.fov;
    }

    public boolean isBobbingEnabled()
    {
        return bobbingEnabled;
    }

    public void setBobbingEnabled(boolean enabled){
        bobbingEnabled = enabled;
    }



    /**
     * @param width  RETRO_WIDTH
     * @param height RETRO_HEIGHT
     */
    public void render(int width, int height) {
        batch.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
        batch.begin();

        GlyphLayout layout = new GlyphLayout();

        // --- central panel ---
        float panelW = 300f;
        float panelH = 220f;
        float panelX = (width  - panelW) / 2f;
        float panelY = (height - panelH) / 2f;

        // background
        batch.setColor(0f, 0f, 0f, 0.9f);
        batch.draw(pixel, panelX, panelY, panelW, panelH);

        // border
        batch.setColor(1f, 1f, 1f, 1f);
        float border = 1f;

        // --- title ---
        String title = "Settings";
        layout.setText(boldFont, title);
        float titleX = panelX + (panelW - layout.width) / 2f;
        float titleY = panelY + panelH - 10f;
        boldFont.draw(batch, layout, titleX, titleY);

        // small separator line under title
        batch.draw(pixel, panelX + 8f, titleY - 14f, panelW - 16f, 1f);

        // --- FOV row ---
        float rowY = panelY + panelH - 50f;
        float rowH = 18f;

        // label
        String fovLabel = "Field of View";
        layout.setText(font, fovLabel);
        float labelX = panelX + 12f;
        float labelY = rowY + rowH - 4f;
        font.draw(batch, layout, labelX, labelY);

        // buttons + value area
        fovDecW = 20f;
        fovDecH = rowH;
        fovDecX = panelX + 180f;
        fovDecY = rowY;

        fovIncW = 20f;
        fovIncH = rowH;
        fovIncX = panelX + panelW - 32f;
        fovIncY = rowY;

        // draw dec button "<"
        drawButtonWithLabel("<", fovDecX, fovDecY, fovDecW, fovDecH);

        // draw inc button ">"
        drawButtonWithLabel(">", fovIncX, fovIncY, fovIncW, fovIncH);

        // numeric value centered between dec/inc
        String fovText = String.format("%3.0f°", settings.fov);
        layout.setText(font, fovText);

        float valueCenter = (fovDecX + fovDecW + fovIncX) / 2f;
        float valueX = valueCenter - layout.width / 2f;
        float valueY = rowY + rowH - 4f;
        font.draw(batch, layout, valueX, valueY);

        // --- Close button at bottom ---
        String closeLabel = " Close ";
        layout.setText(font, closeLabel);
        closeW = layout.width + 64f;
        closeH = layout.height + 12f;
        closeX = panelX + (panelW - closeW) / 2f;
        closeY = panelY + 16f;

        // button bg + border
        batch.setColor(0.1f, 0.1f, 0.1f, 1f);
        batch.draw(pixel, closeX, closeY, closeW, closeH);
        batch.setColor(1f, 1f, 1f, 1f);
        // border
        batch.draw(pixel, closeX, closeY + closeH - border, closeW, border);
        batch.draw(pixel, closeX, closeY, closeW, border);
        batch.draw(pixel, closeX, closeY, border, closeH);
        batch.draw(pixel, closeX + closeW - border, closeY, border, closeH);

        float closeTextX = closeX + (closeW - layout.width) / 2f;
        float closeTextY = closeY + closeH - (closeH - layout.height) / 2f;
        font.draw(batch, closeLabel, closeTextX, closeTextY);

        batch.end();
    }

    private void drawButtonWithLabel(String text, float x, float y, float w, float h) {
        // background
        batch.setColor(0.1f, 0.1f, 0.1f, 1f);
        batch.draw(pixel, x, y, w, h);
        // border
        batch.setColor(1f, 1f, 1f, 1f);
        float border = 1f;
        batch.draw(pixel, x, y + h - border, w, border);
        batch.draw(pixel, x, y, w, border);
        batch.draw(pixel, x, y, border, h);
        batch.draw(pixel, x + w - border, y, border, h);

        GlyphLayout layout = new GlyphLayout(font, text);
        float tx = x + (w - layout.width) / 2f;
        float ty = y + h - (h - layout.height) / 2f;
        font.draw(batch, layout, tx, ty);
    }

    /**
     * Handle a click in RETRO coords.
     *
     * @return true if the menu wants to close (Close button clicked)
     */
    public boolean handleClick(float x, float y) {
        // FOV -
        if (x >= fovDecX && x <= fovDecX + fovDecW &&
            y >= fovDecY && y <= fovDecY + fovDecH) {
            settings.fov = MathUtils.clamp(settings.fov - settings.fovStep, settings.minFov, settings.maxFov);
            return false;
        }

        // FOV +
        if (x >= fovIncX && x <= fovIncX + fovIncW &&
            y >= fovIncY && y <= fovIncY + fovIncH) {
            settings.fov = MathUtils.clamp(settings.fov + settings.fovStep, settings.minFov, settings.maxFov);
            return false;
        }

        // Close
        if (x >= closeX && x <= closeX + closeW &&
            y >= closeY && y <= closeY + closeH) {
            return true;
        }

        return false;
    }

    public void dispose() {
        batch.dispose();
        font.dispose();
        pixel.dispose();
    }
}
