local function createNailCollider(func, collider)
  return celeste.Mod.CrossoverCollab.CrossoverCollabModule.CreateNailColliderDelegate(func, collider)
end

local function hurt()
  if puppet.BossHitCooldown <= 0 then
    celeste.Mod.Kelper.Mechanics.Nail.NailRebound(0.5)
    boss:DecreaseHealth()
    resetHitCooldown()
    player:Play("event:/CC/CC_HollowKnight/SFX/Boss SFX/Damage") --Play hit/squish sound
  end
  return true
end

local function switchHitboxes()
  local nailCollider = createNailCollider(hurt)
  addComponentToBoss(nailCollider)

  local shrieking = false
  setFlag("nosk_change", false)
  while true do
      if getFlag("nosk_change") then
          shrieking = not shrieking
          if shrieking then
              changeBaseHitboxTo("shriek")
          else
              changeBaseHitboxTo("main")
          end
          setFlag("nosk_change", false)
      end
      wait()
  end
end

local function followRain()
  local count = 3
  local delay = 0.033
  local maxSpeed = 230

  local looped = false
  local readIndex = 1
  local saveIndex = 1
  local playerPositions = {n=count}
  for i = 1, count, 1 do playerPositions[i] = player.Position.X end

  setFlag("nosk_rain", false)
  while true do
    local newPos = player.Position.X
    playerPositions[saveIndex] = newPos
    if saveIndex >= count then looped = true end
    saveIndex = (saveIndex % count) + 1
    if looped then readIndex = saveIndex end

    if getFlag("nosk_rain") then
      local dir = playerPositions[readIndex] - puppet.Position.X
      if dir > maxSpeed then dir = maxSpeed end
      if dir < -maxSpeed then dir = -maxSpeed end
      setXSpeed(dir)
      setYSpeedDuring(-10, delay) --stay on the ceiling
    end

    wait(delay)
  end
end

local function healthTracking()
  setFlag("nosk_begin", false)
  storeObjectInBoss("spawn_center", puppet.Position.X)

  while getCurrentPatternID() ~= 2 do
    wait()
  end

  while getHealth() > 14 do
    wait()
  end

  waitForAttackToEnd()
  startNextAttackPattern()
  --includes rain attack
  
  while getHealth() > 0 do
    wait()
  end

  disableCollisions()

  interruptPattern()
  startNextAttackPattern()
end

function setup()
  addConstantBackgroundCoroutine(healthTracking)
  addConstantBackgroundCoroutine(followRain)
  addConstantBackgroundCoroutine(switchHitboxes)
end