const RU = Resources;
const MM = ModelManager;
const MCU = MinecraftClient;
include(Resources.id("aphrodite:library/code/util/error_supplier.js"));
include(Resources.id("aphrodite:library/code/gui/orderly_responder.js"));

// Load models
const MODELS = ModelManager.loadPartedRawModel(RU.manager(), RU.id("mtrsteamloco:eyecandies/signals/routeindicator_modern.obj"), null);

const BASE = ModelManager.uploadVertArrays(MODELS.get("base"));

const L1 = ModelManager.uploadVertArrays(MODELS.get("left1"));
const L2 = ModelManager.uploadVertArrays(MODELS.get("left2"));
const L3 = ModelManager.uploadVertArrays(MODELS.get("left3"));

const R1 = ModelManager.uploadVertArrays(MODELS.get("right1"));
const R2 = ModelManager.uploadVertArrays(MODELS.get("right2"));
const R3 = ModelManager.uploadVertArrays(MODELS.get("right3"));

const TOP = ModelManager.uploadVertArrays(MODELS.get("top"));

const PIVOTWHITE = ModelManager.uploadVertArrays(MODELS.get("pivot_white"));
const PIVOTBLUE = ModelManager.uploadVertArrays(MODELS.get("pivot_blue"));

const POS1 = ModelManager.uploadVertArrays(MODELS.get("pos1"));
const POS2 = ModelManager.uploadVertArrays(MODELS.get("pos2"));
const POS3 = ModelManager.uploadVertArrays(MODELS.get("pos3"));
const POS4 = ModelManager.uploadVertArrays(MODELS.get("pos4"));
const POS5 = ModelManager.uploadVertArrays(MODELS.get("pos5"));
const POS6 = ModelManager.uploadVertArrays(MODELS.get("pos6"));


// Setup config responders
const armnum = "arm";
const aspectKey = "aspect";
const pivotcolour = "colour";
const modeKey = "mode";
const nodePosKey = "nodepos";

const ARM = new ConfigResponder.TextField(
    armnum,
    ComponentUtil.translatable("number.arm"),
    "0"
).setErrorSupplier(str => {
    return Optional.empty();
}).setTooltipSupplier(str => Optional.of(asJavaArray([ComponentUtil.translatable("number of arms (e.g 03 means 1 on the left and 3 on the right)")], Component)));

const nodePosINPUT = new ConfigResponder.TextField(
    nodePosKey,
    ComponentUtil.literal("Node Pos (x,y,z)"),
    ""
).setTooltipSupplier(str => Optional.of(asJavaArray([
    ComponentUtil.literal("Leave empty to auto-detect."),
    ComponentUtil.literal("Format: x,y,z")
], Component)))
    .setErrorSupplier(str => {
        if (!str) return Optional.empty();
        const parts = str.split(",");
        if (parts.length !== 3 || parts.some(p => isNaN(parseFloat(p)))) {
            return Optional.of(ComponentUtil.literal("Invalid format. Use x,y,z."));
        }
        return Optional.empty();
    })

const MODE_RESPONDER = new ConfigResponder.TextField(
    modeKey,
    ComponentUtil.translatable("name.raf.mode"),
    "0"
).setErrorSupplier(str => {
    if (!["0", "1"].includes(str)) {
        return Optional.of(ComponentUtil.translatable("error.aph.invalid_value"));
    }
    return Optional.empty();
}).setTooltipSupplier(str => Optional.of(asJavaArray([ComponentUtil.translatable("0-lit when clear 1-always lit")], Component)));


const RI_ASPECT = new ConfigResponder.TextField(
    aspectKey,
    ComponentUtil.translatable("route indicator aspect"),
    "0"
).setErrorSupplier(str => {
    if (!["0", "1", "2", "3", "4", "5", "6"].includes(str)) {
        return Optional.of(ComponentUtil.translatable("error.aph.invalid_value"));
    }
    return Optional.empty();
}).setTooltipSupplier(str => Optional.of(asJavaArray([ComponentUtil.translatable("pos 0~6,number only")], Component)));

const COLOUR_RESPONDER = new ConfigResponder.TextField(
    pivotcolour,
    ComponentUtil.translatable("name.raf.mode"),
    "w"
).setErrorSupplier(str => {
    if (!["w", "b"].includes(str)) {
        return Optional.of(ComponentUtil.translatable("error.aph.invalid_value"));
    }
    return Optional.empty();
}).setTooltipSupplier(str => Optional.of(asJavaArray([ComponentUtil.translatable("w-white b-blue")], Component)));


const RESS = orderlyResponder("Modern UK Signal", "Made by Andy_Wongg", [ARM, nodePosINPUT, RI_ASPECT, MODE_RESPONDER, COLOUR_RESPONDER]);

function create(ctx, state, entity) {
    entity.registerCustomConfig(RESS);
    entity.sendUpdateC2S();
}

function render(ctx, state, entity) {
    let mat = new Matrices();
    mat.translate(0, 0.00625, 0);
    mat.rotateY(Math.PI); // Slight lift
    ctx.drawModel(BASE, mat);

    let arm = entity.getCustomConfig(armnum) + "";
    let aspect = entity.getCustomConfig(aspectKey) + "";
    let colour = entity.getCustomConfig(pivotcolour) + "";
    let mode = entity.getCustomConfig(modeKey) + "";

    if (arm[1] === "1") {
        ctx.drawModel(R1, mat);
    }
    else if (arm[1] === "2") {
        ctx.drawModel(R2, mat);
    }
    else if (arm[1] === "3") {
        ctx.drawModel(R3, mat);
    }
    else { }
    if (arm[0] === "1") {
        ctx.drawModel(L1, mat);
    }
    else if (arm[0] === "2") {
        ctx.drawModel(L2, mat);
    }
    else if (arm[0] === "3") {
        ctx.drawModel(L3, mat);
    }
    else {

    }
    if (arm[0] !== "0" && arm[1] !== "0") ctx.drawModel(TOP, mat);

    let oa = -1;
    try {
        let pos = entity.getWorldPosVector3f();
        let facing = entity.getBlockYRot() + entity.rotateY / Math.PI * 180 + 90;
        let nodePosStr = entity.getCustomConfig(nodePosKey);
        let nodePos;

        if (nodePosStr && nodePosStr.trim() !== "") {
            const parts = nodePosStr.split(",").map(Number);
            if (parts.length === 3 && parts.every(n => !isNaN(n))) {
                nodePos = new Vector3f(parts[0], parts[1], parts[2]);
            }
        }

        if (!nodePos) {
            nodePos = MCU.getNodeAt(pos, facing);
        }
        oa = MCU.getOccupiedAspect(nodePos, facing, 4); // 4 possible aspects
    } catch (e) { }

    if (mode == 1 || (mode == 0 && oa != 1 && oa != -1)) {
        if (aspect == "1") ctx.drawModel(POS1, mat);
        else if (aspect == "2") ctx.drawModel(POS2, mat);
        else if (aspect == "3") ctx.drawModel(POS3, mat);
        else if (aspect == "4") ctx.drawModel(POS4, mat);
        else if (aspect == "5") ctx.drawModel(POS5, mat);
        else if (aspect == "6") ctx.drawModel(POS6, mat);
        if (aspect != "0") {
            if (colour == "b") ctx.drawModel(PIVOTBLUE, mat);
            else ctx.drawModel(PIVOTWHITE, mat)
        }
    }


}
