import { loadSprite } from "./loadSprite.js";
import { Signalant } from "./signalant.js";
import { storageUi } from "./storageUi.js";
import { tutorial } from "./tutorial.js";

export class StatusUi {
    constructor() {
        this.layout = {
            margin: 10,
            width: 370,
            height: 266,
            previewX: 24,
            previewY: 52,
            previewScale: 3.5,
            colorsX: 144,
            colorsY: 68,
            colorRowHeight: 26,
            colorSwatchSize: 18,
            rangeX: 24,
            rangeY: 168,
            buttonGap: 14,
            buttonX: 24,
            buttonY: 214,
            buttonWidth: 154,
            buttonHeight: 38
        };
        this.panelSprite = loadSprite("assets/ui/statusUi.png");
        this.fixedOverlaySprite = loadSprite("assets/ui/statusUi_fixed.png");
        this.unfixedOverlaySprite = loadSprite("assets/ui/statusUi_unfixed.png");
        this.x = 0;
        this.y = 0;
    }

    reposition() {
        this.x = window.innerWidth - this.layout.margin - this.layout.width;
        this.y = this.layout.margin;
    }

    isVisible(activeSignalant) {
        return Boolean(activeSignalant);
    }

    getSignalant(ui) {
        return ui.activeSignalant || ui.ghostSignalant || null;
    }

    getPanelRect() {
        return {
            x: this.x,
            y: this.y,
            width: this.layout.width,
            height: this.layout.height
        };
    }

    getStoreButtonRect() {
        return {
            x: this.x + this.layout.buttonX,
            y: this.y + this.layout.buttonY,
            width: this.layout.buttonWidth,
            height: this.layout.buttonHeight
        };
    }

    getFixButtonRect() {
        return {
            x: this.x + this.layout.buttonX + this.layout.buttonWidth + this.layout.buttonGap,
            y: this.y + this.layout.buttonY,
            width: this.layout.buttonWidth,
            height: this.layout.buttonHeight
        };
    }

    isPointInRect(x, y, rect) {
        return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
    }

    isPointInside(x, y, ui) {
        return this.isVisible(this.getSignalant(ui)) && this.isPointInRect(x, y, this.getPanelRect());
    }

    getClickAction(x, y, ui) {
        if (!this.isPointInside(x, y, ui)) {
            return null;
        }

        if (this.isPointInRect(x, y, this.getStoreButtonRect())) {
            return { type: "store-signalant" };
        }

        if (this.isPointInRect(x, y, this.getFixButtonRect())) {
            return { type: "toggle-fixed" };
        }

        return { type: "panel" };
    }

    toggleCurrentSignalantFixedState(ui) {
        const signalant = this.getSignalant(ui);
        if (!signalant) {
            return false;
        }

        signalant.isFixed = !signalant.isFixed;
        if (signalant.isFixed) {
            tutorial.trigger("signalant.fix");
        } else {
            tutorial.trigger("signalant.unfix");
        }
        return true;
    }

    handleLeftClick(x, y, ui) {
        const action = this.getClickAction(x, y, ui);
        if (!action) {
            return false;
        }

        if (action.type === "store-signalant") {
            return storageUi.storeCurrentSignalant(ui);
        }

        if (action.type === "toggle-fixed") {
            return this.toggleCurrentSignalantFixedState(ui);
        }

        return action.type === "panel";
    }

    getColorRows(signalant) {
        const colors = signalant?.affectsColors || [];
        const rows = [];

        for (let i = 0; i < 3; i++) {
            const color = colors[i] || null;
            rows.push({
                label: color ? color.toUpperCase() : "EMPTY",
                fill: color ? signalant.getColorCode(color) : "#8B8660"
            });
        }

        return rows;
    }

    drawColorRows(ctx, signalant, panelX, panelY) {
        const rows = this.getColorRows(signalant);

        ctx.save();
        ctx.font = "bold 16px monospace";
        ctx.textBaseline = "middle";

        rows.forEach((row, index) => {
            const rowY = panelY + this.layout.colorsY + index * this.layout.colorRowHeight;

            ctx.fillStyle = row.fill;
            ctx.fillRect(panelX + this.layout.colorsX, rowY - 9, this.layout.colorSwatchSize, this.layout.colorSwatchSize);
            ctx.strokeStyle = "#4C311F";
            ctx.lineWidth = 2;
            ctx.strokeRect(panelX + this.layout.colorsX + 1, rowY - 8, this.layout.colorSwatchSize - 2, this.layout.colorSwatchSize - 2);

            ctx.fillStyle = "#3F2517";
            ctx.fillText(row.label, panelX + this.layout.colorsX + 30, rowY);
        });

        ctx.restore();
    }

    drawRangeText(ctx, signalant, panelX, panelY) {
        ctx.save();
        ctx.fillStyle = "#3F2517";
        ctx.font = "bold 16px monospace";
        ctx.textBaseline = "middle";
        ctx.fillText(`Affection Range: ${signalant.affectionRadius}`, panelX + this.layout.rangeX + 8, panelY + this.layout.rangeY + 8);
        ctx.restore();
    }

    getTitle(signalant) {
        if (signalant instanceof Signalant) {
            return "Pheromone Ant";
        }

        return "Ant";
    }

    drawTitle(ctx, signalant, panelX, panelY) {
        ctx.save();
        ctx.fillStyle = "#3F2517";
        ctx.font = "bold 20px monospace";
        ctx.textBaseline = "top";
        ctx.fillText(this.getTitle(signalant), panelX + 24, panelY + 20);
        ctx.restore();
    }

    drawPanelSprite(ctx, sprite, x, y) {
        if (!sprite || !sprite.complete) {
            return;
        }

        ctx.drawImage(sprite, x, y, this.layout.width, this.layout.height);
    }

    draw(ctx, ui) {
        const signalant = this.getSignalant(ui);
        if (!this.isVisible(signalant)) {
            return;
        }

        const panelX = this.x;
        const panelY = this.y;
        const stateOverlaySprite = signalant.isFixed ? this.fixedOverlaySprite : this.unfixedOverlaySprite;

        this.drawPanelSprite(ctx, this.panelSprite, panelX, panelY);
        this.drawTitle(ctx, signalant, panelX, panelY);
        signalant.drawAt(ctx, panelX + this.layout.previewX + 8, panelY + this.layout.previewY + 10, this.layout.previewScale);
        this.drawColorRows(ctx, signalant, panelX, panelY);
        this.drawRangeText(ctx, signalant, panelX, panelY);
        this.drawPanelSprite(ctx, stateOverlaySprite, panelX, panelY);
    }
}

export const statusUi = new StatusUi();