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/3led_position_light.obj"), null);

const BASE = ModelManager.uploadVertArrays(MODELS.get("base"));
const BOTTOM = ModelManager.uploadVertArrays(MODELS.get("bottom"));
const TOP = ModelManager.uploadVertArrays(MODELS.get("top"));
const RI_BASE = ModelManager.uploadVertArrays(MODELS.get("ri_base"));
const APL_ON = ModelManager.uploadVertArrays(MODELS.get("apl_on"));
const APL_OFF = ModelManager.uploadVertArrays(MODELS.get("apl_off"));
const GPL_ON = ModelManager.uploadVertArrays(MODELS.get("gpl_on"));
const GPL_OFF = ModelManager.uploadVertArrays(MODELS.get("gpl_off"));
const GPL_ON_1996 = ModelManager.uploadVertArrays(MODELS.get("gpl_on_1996"));
const GPL = ModelManager.uploadVertArrays(MODELS.get("gpl"));
const LOS = ModelManager.uploadVertArrays(MODELS.get("los"));
// Setup config responders
const nodePosKey = "custom"
const typeKey = "typeKey";
const modeKey = "modeKey";
const routeindicatorbase = "0"



const RI = new ConfigResponder.TextField(
    routeindicatorbase,
    ComponentUtil.translatable("route indicator base"),
    "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("has route indicator base? (1/0)")], 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 TYPE_RESPONDER = new ConfigResponder.TextField(
    typeKey,
    ComponentUtil.translatable("name.signal.type"),
    "0"
).setErrorSupplier(str => {
    if (!["0", "1", "2", "3"].includes(str)) {
        return Optional.of(ComponentUtil.translatable("error.aph.invalid_value"));
    }
    return Optional.empty();
}).setTooltipSupplier(str => Optional.of(asJavaArray([ComponentUtil.translatable("0-APL 1-GPL 2-GPL(pre-1996) 3-LOS")], Component)));

const MODE_RESPONDER = new ConfigResponder.TextField(
    modeKey,
    ComponentUtil.translatable("name.signal.mode"),
    "2"
).setErrorSupplier(str => {
    if (!["0", "1", "2","3"].includes(str)) {
        return Optional.of(ComponentUtil.translatable("error.aph.invalid_value"));
    }
    return Optional.empty();
}).setTooltipSupplier(str => Optional.of(asJavaArray([ComponentUtil.translatable("0-auto 1-off 2-on 3-extinguished")], Component)));



const RESS = orderlyResponder("GeneralLight", "Made by Aphrodite281", [TYPE_RESPONDER,MODE_RESPONDER,nodePosINPUT,RI]);

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

function render(ctx, state, entity) {
    let mat = new Matrices();
    mat.translate(0, 0, 0); // Slight lift
    ctx.drawModel(BASE, mat);
    let mode = entity.getCustomConfig(modeKey) + "";
    let type = entity.getCustomConfig(typeKey) + "";
    let ri = entity.getCustomConfig(routeindicatorbase) + "";


if (ri === "1")
    {  
    ctx.drawModel(RI_BASE, 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); 
    } catch (e) {}


    let modelToDraw = null;
    if (type === "3"){
            ctx.drawModel(BOTTOM, mat);
            ctx.drawModel(LOS, mat);
        }
    if (mode === "0"){//auto
        if (type === "0") {//APL
            if (oa === 1) {
                ctx.drawModel(TOP, mat);
                modelToDraw = APL_ON;
            }
            else {
                ctx.drawModel(TOP, mat);
                modelToDraw = APL_OFF;
            }
        } else if (type === "1") {//GPL
            ctx.drawModel(BOTTOM, mat);
            ctx.drawModel(TOP, mat);
            if (oa === 1) modelToDraw = GPL_ON;
            else if (oa !== -1) modelToDraw = GPL_OFF;
            else modelToDraw = GPL;
        } else if (type === "2") {//GPL1996
            ctx.drawModel(BOTTOM, mat);
            ctx.drawModel(TOP, mat);
            if (oa === 1) modelToDraw = GPL_ON_1996;
            else if (oa !== -1) modelToDraw = GPL_OFF;
            else modelToDraw = GPL;
        }
    }
    else if (mode === "1"){
        if (type === "0") {
            ctx.drawModel(TOP, mat);
            modelToDraw = APL_OFF;
        }
        else if (type === "1"||type === "2"){
            ctx.drawModel(TOP, mat);
            ctx.drawModel(BOTTOM, mat);
            modelToDraw = GPL_OFF
        }
    }
    else if (mode === "2"){
        if (type === "0"){
            ctx.drawModel(TOP, mat);
            modelToDraw = APL_ON;
        }
        else if (type === "1"){
            ctx.drawModel(TOP, mat);
            ctx.drawModel(BOTTOM, mat);
            modelToDraw = GPL_ON
        }
        else if (type === "2"){
            ctx.drawModel(TOP, mat);
            ctx.drawModel(BOTTOM, mat);
            modelToDraw = GPL_ON_1996
        }
    }
    else if (mode === "3"){
        if (type === "0") {
            ctx.drawModel(TOP, mat);
            modelToDraw = APL_ON;
        }
        else if (type === "1"||type === "2"){
            ctx.drawModel(TOP, mat);
            ctx.drawModel(BOTTOM, mat);
            modelToDraw = GPL
        }
    }
    if (modelToDraw != null) {
        ctx.drawModel(modelToDraw, mat);
    }
}
