import settings from "../settings/settings";
import { makeObjectDraggable } from "Draggable";
import { addAction } from "../util/broadcast";
import { rgbToColorInt, addCommas, secondsToMessage } from "../util/helperFunctions";

let first = false;
let ping = 0.82;
let abilityReady = 0;
let selectedAbility = "Mining Speed Boost";
let idkabilityyet = true;
let level = settings().cotmLevel ? 2 : 1;
let abilityStartTime = 0;
let abilityDuration = 0;
let ingui = false;
let endTime = 0;
let started = null;
let mouseDown = false;
let hasBalPet = null;
let cooldownBuffActive = false;
let cooldownBuffEndTime = 0;
const isCooldownBuffActive = () => cooldownBuffActive && Date.now() < cooldownBuffEndTime;

function cleanPetName(text) {
    return text
        .replace(/§.|&[0-9a-fk-or]/gi, "")
        .replace(/\[LVL ?\d+\]/i, "")
        .replace("!", "")
        .trim();
}


function isPlayerHoldingItem(itemList) {
    const lore = Player.getHeldItem()?.getLore();
    return lore && itemList.some(item => lore.some(line => line.toLowerCase().includes(item.toLowerCase())));
}


function getDrillFuelTankCooldownModifier() {
    if (isPlayerHoldingItem(["perfectly-cut fuel tank"])) return 0.90;
    if (isPlayerHoldingItem(["gemstone fuel tank"])) return 0.94;
    if (isPlayerHoldingItem(["titanium-infused fuel tank"])) return 0.96;
    if (isPlayerHoldingItem(["mithril-infused fuel tank"])) return 0.98;
    return 1;
}

register("chat", (pet) => {
    const cleaned = cleanPetName(pet);
    hasBalPet = cleaned.toLowerCase().includes("bal");
}).setCriteria("&cAutopet &eequipped your &7${pet}&e! &a&lVIEW RULE&r");

register("chat", (buff) => {
    if (buff.toLowerCase().includes("pickaxe ability cooldowns")) {
        cooldownBuffActive = true;
        cooldownBuffEndTime = Date.now() + 20 * 60 * 1000; // 20 minutes
    }
}).setCriteria("&r&eNew buff&r&r&r: ${buff}");
register("chat", (pet) => {
    const cleaned = cleanPetName(pet);
    hasBalPet = cleaned.toLowerCase().includes("bal");
}).setCriteria("&r&aYou summoned your ${&r&5Dolphin&r&a!&r}");

register("chat", () => { abilityReady = 0; })
    .setCriteria("${&r&a&r&6Pickobulus} &r&ais now available!&r");
function getEffectiveLevel() {
    return isPlayerHoldingItem(["blue cheese"]) ? level + 1 : level;
}

function isPlayerHoldingDrill() {
    const itemId = Player.getHeldItem()?.getItemNBT()?.getTag("tag")?.getTag("ExtraAttributes")?.getTag("id")?.toString()?.toLowerCase();
    return itemId && (itemId.includes("drill") || itemId.includes("gemstone_gauntlet") || itemId.includes("pickonimbus"));
}

const abilityStatsTable = {
    "pickobulus": { baseCooldown: 60, cooldownPerLevel: [60, 50, 40] },
    "mining speed boost": { baseDuration: 10, durationPerLevel: [10, 15, 20], baseCooldown: 120 },
    "anomalous desire": { baseCooldown: 120, cooldownPerLevel: [120, 110, 100] },
    "maniac miner": { baseDuration: 25, durationPerLevel: [25, 30, 35], baseCooldown: 120 },
    "gemstone infusion": { baseDuration: 20, durationPerLevel: [20, 25, 30], baseCooldown: 120 },
    "sheer force": { baseDuration: 20, durationPerLevel: [20, 25, 30], baseCooldown: 120 }
};

function getAbilityStats(ability) {
    return abilityStatsTable[ability] || null;
}
const updateAbilityReady = () => {
    first = false;
    const now = Date.now();
    const remainingTime = Math.max(0, Math.floor((endTime - now) / 1000));
    abilityReady = remainingTime;
    if (abilityReady > 0) setTimeout(updateAbilityReady, 1000);
};

function Widget() {
    const tablist = TabList.getNames();
    return tablist.some(line => line.includes('Bal§r'));
}
const currentTitle = { title: null, subtitle: null, time: null };

const _drawTitle = (title, subtitle) => {
    const [x, y] = [Renderer.screen.getWidth() / 2, Renderer.screen.getHeight() / 2];
    Renderer.translate(x, y);
    Renderer.scale(4, 4);
    Renderer.drawStringWithShadow(title, -(Renderer.getStringWidth(title) / 2), -10);
    Renderer.translate(x, y);
    Renderer.scale(2, 2);
    Renderer.drawStringWithShadow(subtitle, -(Renderer.getStringWidth(subtitle) / 2), 5);
};

const showTitle = (title, subtitle, ms) => {
    currentTitle.title = title;
    currentTitle.subtitle = subtitle;
    currentTitle.time = ms;
};
register("renderOverlay", () => {
    if (!currentTitle.time) return;
    if (!started) started = Date.now();
    const remaining = currentTitle.time - (Date.now() - started);
    if (remaining <= 0) {
        currentTitle.title = null;
        currentTitle.subtitle = null;
        currentTitle.time = null;
        started = null;
        return;
    }
    _drawTitle(currentTitle.title, currentTitle.subtitle);
});

register("worldLoad", () => {
    first = false;
    idkabilityyet = true;
    endTime = Date.now() + abilityReady * 1000;
    updateAbilityReady();
    level = settings().cotmLevel ? 2 : 1;
    hasBalPet = null;
});

register("playerInteract", () => {
    if (!isPlayerHoldingDrill() || abilityReady !== 0 || idkabilityyet) return;

    const abilityStats = getAbilityStats(selectedAbility);
    if (!abilityStats) return;

    let cooldown = abilityStats.cooldownPerLevel
        ? abilityStats.cooldownPerLevel[getEffectiveLevel() - 1]
        : abilityStats.baseCooldown;

    let duration = abilityStats.durationPerLevel
        ? abilityStats.durationPerLevel[getEffectiveLevel() - 1]
        : 0;

    if (hasBalPet) cooldown *= 0.9;
    cooldown *= getDrillFuelTankCooldownModifier();
    if (isCooldownBuffActive()) cooldown *= 0.8;        // ← 20 % faster

    abilityReady = cooldown + ping;
    endTime = Date.now() + abilityReady * 1000;
    abilityStartTime = Date.now();
    abilityDuration = duration * 1000;
    updateAbilityReady();
});

register("chat", (abilityName) => {
    selectedAbility = abilityName.toLowerCase();
}).setCriteria(/&r&aYou selected &r&e(.+) &r&aas your Pickaxe Ability. This ability will apply to all of your pickaxes!&r/g);

register("chat", (abilityName) => {
    if (hasBalPet == null) hasBalPet = Widget();
    selectedAbility = abilityName.toLowerCase();

    if (idkabilityyet) {
        const abilityStats = getAbilityStats(selectedAbility);
        if (!abilityStats) return;

        let cooldown = abilityStats.cooldownPerLevel
            ? abilityStats.cooldownPerLevel[getEffectiveLevel() - 1]
            : abilityStats.baseCooldown;

        if (hasBalPet) cooldown *= 0.9;
        cooldown *= getDrillFuelTankCooldownModifier();
        if (isCooldownBuffActive()) cooldown *= 0.8;    // ← 20 % faster

        abilityReady = cooldown + ping;
        const duration = abilityStats.durationPerLevel
            ? abilityStats.durationPerLevel[getEffectiveLevel() - 1]
            : 0;

        abilityStartTime = Date.now();
        abilityDuration = duration * 1000;
        endTime = Date.now() + abilityReady * 1000;
        updateAbilityReady();
        idkabilityyet = false;
    }
}).setCriteria(/&r&aYou used your &r&6(.+) &r&aPickaxe Ability!&r/g);
const text = new Text("", 5, 15);

register("renderOverlay", () => {
    /* Active-ability duration overlay */
    if (settings().abilityDurationDisplay && abilityDuration > 0) {
        const remaining = Math.max(0, (abilityDuration - (Date.now() - abilityStartTime)) / 1000).toFixed(2);
        if (remaining > 0) new Text(remaining, (Renderer.screen.getWidth() / 2) - 10, (Renderer.screen.getHeight() / 2) - 10).draw();
    }

    /* Main cooldown text */
    if ((settings().miningAbilityTimer && !idkabilityyet) || ingui) {
        const lines = [`${selectedAbility.toUpperCase()} CD: ${abilityReady}s`];
        text.setString(lines.join("\n"));
        text.setColor(rgbToColorInt(...settings().abilityColor));
        text.draw();
    }

    /* Ready notification */
    if (abilityReady === 0 && !first && settings().miningAbility && !idkabilityyet) {
        showTitle(settings().abilityMessage, "", 5000);
        World.playSound("random.orb", 100, 0.79);
        first = true;
    }
});

/* GUI drag handler */
const gui = new Gui();
makeObjectDraggable("Mining Timer", text, () => gui.isOpen() && mouseDown);

register("guiMouseClick", (mx, my, b, activeGui) => {
    if (activeGui.equals(gui)) {
        mouseDown = true;
        ingui = true;
    }
});
register("guiMouseRelease", () => { mouseDown = false; ingui = false; });
addAction("moveTimerGUI", () => gui.open());
