const ACTIVITY_PAY_CHECK_TICKS = 20
const ACTIVITY_PAY_INTERVAL_SECONDS = 10 * 60
const ACTIVITY_PAY_AMOUNTS = [100, 150, 200, 250]
const ACTIVITY_PAY_DAILY_PAYMENT_CAP = 15
const ACTIVITY_PAY_MIN_MOVEMENT_SQUARED = 3
const ACTIVITY_PAY_ACTION_SECONDS = 5
const ACTIVITY_PAY_ACTION_COOLDOWN_MS = 2000
const ACTIVITY_PAY_DAY_MS = 24 * 60 * 60 * 1000



let activityPayTicks = 0



ServerEvents.tick(event => {
    activityPayTicks++

    if (activityPayTicks < ACTIVITY_PAY_CHECK_TICKS) {
        return
    }

    activityPayTicks = 0

    event.server.players.forEach(player => {
        resetActivityPayDay(player)

        if (updateActivityPayMovement(player)) {
            addActivityPaySeconds(player, 1)
        }

        payActivityIfReady(player)
    })
})

BlockEvents.broken(event => {
    addActivityPayAction(event.player)
})

BlockEvents.placed(event => {
    addActivityPayAction(event.player)
})



function activityPayDay() {
    return Math.floor(Date.now() / ACTIVITY_PAY_DAY_MS)
}

function resetActivityPayDay(player) {
    const data = player.persistentData
    const today = activityPayDay()

    if (data.activityPayDay != today) {
        data.activityPayDay = today
        data.activityPayPayments = 0
        data.activityPaySeconds = 0
    }
}

function addActivityPaySeconds(player, seconds) {
    const data = player.persistentData
    data.activityPaySeconds = Math.min(
        ACTIVITY_PAY_INTERVAL_SECONDS,
        Number(data.activityPaySeconds || 0) + seconds
    )
}

function payActivityIfReady(player) {
    if (player.persistentData.activityPaySeconds < ACTIVITY_PAY_INTERVAL_SECONDS) {
        return
    }

    player.persistentData.activityPaySeconds = 0
    payForActivity(player)
}

function updateActivityPayMovement(player) {
    const data = player.persistentData
    const lastDimension = String(data.activityPayLastDimension || '')
    const dimension = String(player.level.dimension)
    const lastX = Number(data.activityPayLastX || player.x)
    const lastY = Number(data.activityPayLastY || player.y)
    const lastZ = Number(data.activityPayLastZ || player.z)
    const dx = player.x - lastX
    const dy = player.y - lastY
    const dz = player.z - lastZ
    const distanceSquared = dx * dx + dy * dy + dz * dz
    const active = lastDimension != dimension || distanceSquared >= ACTIVITY_PAY_MIN_MOVEMENT_SQUARED

    data.activityPayLastX = player.x
    data.activityPayLastY = player.y
    data.activityPayLastZ = player.z
    data.activityPayLastDimension = dimension

    return active
}

function addActivityPayAction(player) {
    if (!player) {
        return
    }

    resetActivityPayDay(player)

    const data = player.persistentData
    const now = Date.now()
    const lastAction = Number(data.activityPayLastAction || 0)

    if (now - lastAction < ACTIVITY_PAY_ACTION_COOLDOWN_MS) {
        return
    }

    data.activityPayLastAction = now
    addActivityPaySeconds(player, ACTIVITY_PAY_ACTION_SECONDS)
    payActivityIfReady(player)
}

function payForActivity(player) {
    const data = player.persistentData
    const payments = Number(data.activityPayPayments || 0)

    if (payments >= ACTIVITY_PAY_DAILY_PAYMENT_CAP) {
        return
    }

    const randomPay = ACTIVITY_PAY_AMOUNTS[Math.floor(Math.random() * ACTIVITY_PAY_AMOUNTS.length)]
    const playerName = player.name.string

    data.activityPayPayments = payments + 1
    player.server.runCommandSilent(`eco give ${playerName} ${randomPay}`)
    player.tell(`+$${randomPay} activity pay (${data.activityPayPayments}/${ACTIVITY_PAY_DAILY_PAYMENT_CAP} payments today)`)
}
