/**
 * Developer: Molla Samser
 * Organization: RSK World
 * Website: https://rskworld.in
 * Email: hello@rskworld.in, support@rskworld.in
 * Phone: +91 93305 39277
 * Address: Nutanhat, Mongolkote, Purba Burdwan, West Bengal, India, 713147
 * Copyright © 2026 RSK World. All rights reserved.
 */

const canvas = document.querySelector('canvas')
const c = canvas.getContext('2d')

canvas.width = 1024
canvas.height = 576

c.fillRect(0, 0, canvas.width, canvas.height)

const gravity = 0.7

// Audio Initialization
const sounds = {
  bg: new Audio('./Sound/bg.mp3'),
  hit: new Audio('./Sound/shot 2.mp3'),
  attack: new Audio('./Sound/shot 2.mp3'),
  jump: new Audio('./Sound/shot 1.mp3'),
  death: new Audio('./Sound/explosion.wav')
}

// Configure audio
sounds.bg.loop = true
sounds.bg.volume = 0.5
sounds.hit.volume = 0.8
sounds.attack.volume = 1.0

// Parallax Background Layers (v2 assets with scaling fix for no gaps)
const bgSky = new Sprite({
  position: { x: 0, y: 0 },
  imageSrc: './img/bg_layer_0.png',
  rows: 1,
  maxFrames: 1,
  scale: 1.1, // Scale up slightly to prevent parallax gaps
  repeat: true
})

const bgMountains = new Sprite({
  position: { x: 0, y: 0 },
  imageSrc: './img/bg_layer_1.png',
  rows: 1,
  maxFrames: 1,
  scale: 1.1,
  repeat: true
})

const bgForeground = new Sprite({
  position: { x: 0, y: 0 },
  imageSrc: './img/bg_layer_2.png',
  rows: 1,
  maxFrames: 1,
  scale: 1.1,
  repeat: true
})

const playerAssets = './img/fire_samurai.png'
const enemyAssets = './img/ice_samurai.png'

const rowHeight = 128 // 1024 / 8 rows

const player = new Fighter({
  position: { x: 100, y: 0 },
  velocity: { x: 0, y: 0 },
  offset: { x: 190, y: 120 },
  imageSrc: playerAssets,
  framesMax: 8,
  maxFrames: 8,
  scale: 4.0, // Large premium characters
  rows: 8,
  offsetY: 0,
  sprites: {
    idle: { imageSrc: playerAssets, framesMax: 8, offsetY: 0 },
    run: { imageSrc: playerAssets, framesMax: 8, offsetY: rowHeight * 1 },
    jump: { imageSrc: playerAssets, framesMax: 2, offsetY: rowHeight * 2 },
    fall: { imageSrc: playerAssets, framesMax: 2, offsetY: rowHeight * 3 },
    attack1: { imageSrc: playerAssets, framesMax: 6, offsetY: rowHeight * 4 },
    takeHit: { imageSrc: playerAssets, framesMax: 4, offsetY: rowHeight * 5 },
    death: { imageSrc: playerAssets, framesMax: 6, offsetY: rowHeight * 6 },
    specialAttack: { imageSrc: playerAssets, framesMax: 8, offsetY: rowHeight * 7 }
  },
  attackBox: {
    offset: { x: 140, y: 50 },
    width: 200,
    height: 50
  },
  sounds: { attack: sounds.attack, hit: sounds.hit }
})

const enemy = new Fighter({
  position: { x: 800, y: 100 },
  velocity: { x: 0, y: 0 },
  color: 'blue',
  offset: { x: 190, y: 120 },
  imageSrc: enemyAssets,
  framesMax: 8,
  maxFrames: 8,
  scale: 4.0,
  rows: 8,
  offsetY: 0,
  sprites: {
    idle: { imageSrc: enemyAssets, framesMax: 8, offsetY: 0 },
    run: { imageSrc: enemyAssets, framesMax: 8, offsetY: rowHeight * 1 },
    jump: { imageSrc: enemyAssets, framesMax: 2, offsetY: rowHeight * 2 },
    fall: { imageSrc: enemyAssets, framesMax: 2, offsetY: rowHeight * 3 },
    attack1: { imageSrc: enemyAssets, framesMax: 4, offsetY: rowHeight * 4 },
    takeHit: { imageSrc: enemyAssets, framesMax: 3, offsetY: rowHeight * 5 },
    death: { imageSrc: enemyAssets, framesMax: 7, offsetY: rowHeight * 6 },
    specialAttack: { imageSrc: enemyAssets, framesMax: 8, offsetY: rowHeight * 7 }
  },
  attackBox: {
    offset: { x: -240, y: 50 },
    width: 200,
    height: 50
  },
  sounds: { attack: sounds.attack, hit: sounds.hit }
})

const keys = {
  a: { pressed: false },
  d: { pressed: false },
  ArrowRight: { pressed: false },
  ArrowLeft: { pressed: false }
}

let gameStarted = false
let isAIMode = true

function updateAI() {
  if (!gameStarted || enemy.dead || player.dead) return

  const attackRange = 210
  const idealDist = 180
  const distX = player.position.x - enemy.position.x
  const distAbs = Math.abs(distX)

  // Move towards player
  if (distAbs > idealDist) {
    if (distX > 0) {
      enemy.velocity.x = 3.5
      enemy.switchSprite('run')
      enemy.lastKey = 'd'
    } else {
      enemy.velocity.x = -3.5
      enemy.switchSprite('run')
      enemy.lastKey = 'a'
    }
  } else {
    enemy.velocity.x = 0
    enemy.switchSprite('idle')
  }

  // Attack logic
  if (distAbs <= attackRange && !enemy.isAttacking && !enemy.isSpecialAttacking) {
    if (enemy.mana >= 100) {
        enemy.specialAttack()
    } else if (Math.random() < 0.03) {
      enemy.attack()
    }
  }

  // Random Jumping
  if (Math.random() < 0.005 && enemy.velocity.y === 0) {
    enemy.velocity.y = -18
    sounds.jump.currentTime = 0
    sounds.jump.play().catch(e => {})
  }
}

function screenShake() {
  gsap.to('#gameContainer', {
    x: 'random(-5, 5)',
    y: 'random(-5, 5)',
    duration: 0.05,
    repeat: 5,
    yoyo: true,
    onComplete: () => {
      gsap.to('#gameContainer', { x: 0, y: 0, duration: 0.05 })
    }
  })
}

function updateHUD() {
  // Mana Bars
  gsap.to('#playerMana', { width: player.mana + '%' })
  gsap.to('#enemyMana', { width: enemy.mana + '%' })

  // Combo Counters
  const p1Combo = document.querySelector('#p1-combo')
  const p2Combo = document.querySelector('#p2-combo')

  if (player.combo > 1) {
    p1Combo.innerText = player.combo + ' HIT!'
    gsap.to(p1Combo, { opacity: 1, scale: 1.2, duration: 0.1, yoyo: true, repeat: 1 })
  } else {
    gsap.to(p1Combo, { opacity: 0, scale: 0.5, duration: 0.2 })
  }

  if (enemy.combo > 1) {
    p2Combo.innerText = enemy.combo + ' HIT!'
    gsap.to(p2Combo, { opacity: 1, scale: 1.2, duration: 0.1, yoyo: true, repeat: 1 })
  } else {
    gsap.to(p2Combo, { opacity: 0, scale: 0.5, duration: 0.2 })
  }
}

function animate() {
  window.requestAnimationFrame(animate)
  if (!gameStarted) return

  c.fillStyle = 'black'
  c.fillRect(0, 0, canvas.width, canvas.height)

  // Smooth parallax scrolling
  bgSky.update()
  bgMountains.position.x = (-player.position.x * 0.1) % (1024 * 1.1)
  bgMountains.update()
  bgForeground.position.x = (-player.position.x * 0.3) % (1024 * 1.1)
  bgForeground.update()

  c.fillStyle = 'rgba(255, 255, 255, 0.05)'
  c.fillRect(0, 0, canvas.width, canvas.height)

  player.update()
  enemy.update()

  player.velocity.x = 0
  enemy.velocity.x = 0

  // AI Update
  if (isAIMode) {
    updateAI()
  }

  // HUMAN Player movement
  if (keys.ArrowLeft.pressed && player.lastKey === 'ArrowLeft') {
    player.velocity.x = -5
    player.switchSprite('run')
  } else if (keys.ArrowRight.pressed && player.lastKey === 'ArrowRight') {
    player.velocity.x = 5
    player.switchSprite('run')
  } else {
    player.switchSprite('idle')
  }

  if (player.velocity.y < 0) {
    player.switchSprite('jump')
  } else if (player.velocity.y > 0) {
    player.switchSprite('fall')
  }

  // Enemy manual movement
  if (!isAIMode) {
    if (keys.a.pressed && enemy.lastKey === 'a') {
      enemy.velocity.x = -5
      enemy.switchSprite('run')
    } else if (keys.d.pressed && enemy.lastKey === 'd') {
      enemy.velocity.x = 5
      enemy.switchSprite('run')
    } else {
      enemy.switchSprite('idle')
    }

    if (enemy.velocity.y < 0) {
      enemy.switchSprite('jump')
    } else if (enemy.velocity.y > 0) {
      enemy.switchSprite('fall')
    }
  }

  // Collision Logic - Player HITS Enemy
  if (
    rectangularCollision({ rectangle1: player, rectangle2: enemy }) &&
    (player.isAttacking || player.isSpecialAttacking) &&
    ((player.isAttacking && player.framesCurrent === 4) || (player.isSpecialAttacking && player.framesCurrent === 6))
  ) {
    const damage = player.isSpecialAttacking ? 35 : 20
    enemy.takeHit(damage)
    
    player.isAttacking = false
    player.isSpecialAttacking = false
    
    player.mana += 15
    if (player.mana > 100) player.mana = 100
    player.updateCombo()
    
    gsap.to('#enemyHealth', { width: enemy.health + '%' })
    screenShake()
  }

  if (player.isAttacking && player.framesCurrent === 5) player.isAttacking = false
  if (player.isSpecialAttacking && player.framesCurrent === 7) player.isSpecialAttacking = false

  // Collision Logic - Enemy HITS Player
  if (
    rectangularCollision({ rectangle1: enemy, rectangle2: player }) &&
    (enemy.isAttacking || enemy.isSpecialAttacking) &&
    ((enemy.isAttacking && enemy.framesCurrent === 2) || (enemy.isSpecialAttacking && enemy.framesCurrent === 5))
  ) {
    const damage = enemy.isSpecialAttacking ? 35 : 20
    player.takeHit(damage)
    
    enemy.isAttacking = false
    enemy.isSpecialAttacking = false
    
    enemy.mana += 15
    if (enemy.mana > 100) enemy.mana = 100
    enemy.updateCombo()
    
    gsap.to('#playerHealth', { width: player.health + '%' })
    screenShake()
  }

  if (enemy.isAttacking && enemy.framesCurrent === 3) enemy.isAttacking = false
  if (enemy.isSpecialAttacking && enemy.framesCurrent === 7) enemy.isSpecialAttacking = false

  // Sync Global HUD
  updateHUD()

  // End game conditions
  if (enemy.health <= 0 || player.health <= 0) {
    determineWinner({ player, enemy, timerId })
    if (enemy.health <= 0 && !enemy.dead) sounds.death.play()
    if (player.health <= 0 && !player.dead) sounds.death.play()
  }
}

animate()

window.addEventListener('keydown', (event) => {
  if (!gameStarted) return
  
  if (!player.dead) {
    switch (event.key) {
      case 'ArrowRight':
        keys.ArrowRight.pressed = true
        player.lastKey = 'ArrowRight'
        break
      case 'ArrowLeft':
        keys.ArrowLeft.pressed = true
        player.lastKey = 'ArrowLeft'
        break
      case 'ArrowUp':
        if (player.velocity.y === 0) {
          player.velocity.y = -18
          sounds.jump.currentTime = 0
          sounds.jump.play().catch(e => {})
        }
        break
      case 'ArrowDown':
        player.specialAttack()
        break
      case ' ':
        player.attack()
        break
    }
  }

  if (!enemy.dead && !isAIMode) {
    switch (event.key) {
      case 'd':
        keys.d.pressed = true
        enemy.lastKey = 'd'
        break
      case 'a':
        keys.a.pressed = true
        enemy.lastKey = 'a'
        break
      case 'w':
        if (enemy.velocity.y === 0) {
          enemy.velocity.y = -18
          sounds.jump.currentTime = 0
          sounds.jump.play().catch(e => {})
        }
        break
      case 's':
        enemy.attack()
        break
      case 'x':
        enemy.specialAttack()
        break
    }
  }
})

window.addEventListener('keyup', (event) => {
  switch (event.key) {
    case 'ArrowRight': keys.ArrowRight.pressed = false; break
    case 'ArrowLeft': keys.ArrowLeft.pressed = false; break
    case 'd': keys.d.pressed = false; break
    case 'a': keys.a.pressed = false; break
  }
})

document.querySelector('#startBtn').addEventListener('click', () => {
  gameStarted = true
  document.querySelector('#startOverlay').style.opacity = '0'
  setTimeout(() => { document.querySelector('#startOverlay').style.display = 'none' }, 500)
  sounds.bg.play().catch(e => console.log('Audio blocked'))
  decreaseTimer()
})

document.querySelector('#aiToggleBtn').addEventListener('click', () => {
  isAIMode = !isAIMode
  document.querySelector('#modeText').innerText = isAIMode ? 'VS Computer' : '2 Player'
})

document.querySelector('#restartBtn').addEventListener('click', () => {
  location.reload()
})
