let trail = [];
let velocities = [];
let particles = [];
let flashAlpha = 0;
let score = 0;
let bgBlue = 0;

let treeImgs = {};
let treeHits = 0;
const TREE_COUNT = 8;
let waveTime = 0;

let idleSprite;
let idleAni;

let coconut = {
  x: 0, y: 0,
  r: 0,
  state: 0,
  shakeX: 0,
  shakeTimer: 0,
  flying: false,
  flyVX: 0, flyVY: 0,
  flyAlpha: 255,
  flyRotation: 0, flyRotSpeed: 0
};

let coconutImgs = [];
let kakomoraImgs = [];
let flyingKakamoraList = [];

// ====== PRELOAD ======
function preload() {
  for (let i = 0; i < 5; i++) {
    coconutImgs[i] = loadImage(`assets/coconut/coconut_${i}.png`);
  }
  kakomoraImgs[0] = loadImage('assets/kakamora-characters/Kakamora-TikiRob-Claw-Edition.png');
  kakomoraImgs[1] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Fishhead-Edition.webp');
  kakomoraImgs[2] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Mickey-Mouse-Edition-1-250x250.png');
  kakomoraImgs[3] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Seashell-Edition.png');
  kakomoraImgs[4] = loadImage('assets/kakamora-characters/Kokomoro-TikiRob-Starfish-Edition-250x250.png');

  treeImgs.full = [
    loadImage('assets/tree/tree_full_1.png'),
    loadImage('assets/tree/tree_full_2.png'),
  ];
  treeImgs.half = [
    loadImage('assets/tree/tree_half_1.png'),
    loadImage('assets/tree/tree_half_2.png'),
  ];
  treeImgs.one = [loadImage('assets/tree/tree_one_1.png')];
  treeImgs.empty = [
    loadImage('assets/tree/tree_empty_1.png'),
    loadImage('assets/tree/tree_empty_2.png'),
    loadImage('assets/tree/tree_empty_3.png'),
  ];

  idleAni = loadAni('assets/kakamora-characters/co_ani_1.png', 5);
}

// ====== SETUP ======
function setup() {
  createCanvas(windowWidth, windowHeight);
  resetCoconutHome();

  world.gravity.y = 0;
  idleSprite = new Sprite();
  idleSprite.addAni('idle', idleAni);
  idleSprite.collider = 'none';
  idleSprite.visible = false; // p5play auto-draw 비활성 — 수동으로 그림
  idleSprite.ani.frameDelay = 8;
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  resetCoconutHome();
}

function resetCoconutHome() {
  coconut.r = min(windowWidth, windowHeight) * 0.13;
  coconut.x = width / 2;
  coconut.y = height * 0.42;
}

// ====== DRAW ======
function draw() {
  background(lerpColor(color(30, 50, 80), color(25, 90, 200), bgBlue / 255));
  if (bgBlue > 0) bgBlue = max(0, bgBlue - 4);

  drawBackground();
  drawTrees();
  updateShake();
  updateFlyAway();
  drawCoconut();
  drawTrail();

  drawParticles();
  drawFlash();
  drawScore();
  drawKakamoraSlots();
  updateFlyingKakamoraList();
  drawFlyingKakamoraList();
}

// ====== BACKGROUND ======
function drawBackground() {
  const horizonY = height * 0.60;
  const sandY = height * 0.70;
  waveTime += 0.016;
  noStroke();

  // Ocean base
  fill(18, 90, 165);
  rect(0, horizonY, width, sandY - horizonY);

  // Ocean depth gradient (slightly lighter toward shore)
  fill(40, 120, 190, 80);
  rect(0, (horizonY + sandY) / 2, width, (sandY - horizonY) / 2);

  // 3 animated wave layers (far → near)
  const waveLayers = [
    { t: 0.18, amp: 3, freq: 0.007, speed: 0.7, alpha: 60, wh: 3 },
    { t: 0.52, amp: 6, freq: 0.009, speed: 1.1, alpha: 100, wh: 5 },
    { t: 0.82, amp: 9, freq: 0.011, speed: 1.6, alpha: 145, wh: 8 },
  ];
  for (let lyr of waveLayers) {
    let wy = horizonY + (sandY - horizonY) * lyr.t;
    fill(255, 255, 255, lyr.alpha);
    beginShape();
    vertex(0, wy + lyr.wh);
    for (let x = 0; x <= width; x += 8) {
      vertex(x, wy + sin(x * lyr.freq + waveTime * lyr.speed) * lyr.amp);
    }
    vertex(width, wy + lyr.wh);
    endShape(CLOSE);
  }

  // Shore foam
  fill(255, 255, 255, 90);
  beginShape();
  vertex(0, sandY + 6);
  for (let x = 0; x <= width; x += 6) {
    vertex(x, sandY + sin(x * 0.013 + waveTime * 2.2) * 4);
  }
  vertex(width, sandY + 6);
  endShape(CLOSE);

  // Sand
  fill(210, 185, 135);
  rect(0, sandY, width, height - sandY);

  // Wet sand strip at shore
  fill(185, 158, 105, 200);
  rect(0, sandY, width, 14);

  // Sand highlight
  fill(235, 215, 165, 50);
  rect(0, sandY + 10, width, 35);
}

// ====== TREES ======
function drawTrees() {
  imageMode(CENTER);
  for (let i = 0; i < TREE_COUNT; i++) {
    let stage = constrain(treeHits - i * 3, 0, 3);
    let img;
    if (stage === 0) img = treeImgs.full[i % treeImgs.full.length];
    else if (stage === 1) img = treeImgs.half[i % treeImgs.half.length];
    else if (stage === 2) img = treeImgs.one[0];
    else img = treeImgs.empty[i % treeImgs.empty.length];

    let x = ((i + 0.5) / TREE_COUNT) * width;
    let h = height * (0.30 + (i % 3) * 0.02);
    let w = h * (img.width / img.height);
    let groundY = height * 0.82;
    let cy = groundY - h / 2;

    image(img, x, cy, w, h);
  }
}

// ====== COCONUT ======
function drawCoconut() {
  imageMode(CENTER);
  if (coconut.flying) {
    push();
    translate(coconut.x, coconut.y);
    rotate(coconut.flyRotation);
    tint(255, coconut.flyAlpha);
    image(coconutImgs[coconut.state], 0, 0, coconut.r * 2, coconut.r * 2);
    noTint();
    pop();
  } else if (coconut.state === 0) {
    // idle: p5play 애니메이션 현재 프레임을 수동 렌더링
    let frame = idleSprite && idleSprite.ani ? idleSprite.ani.src : null;
    let img = frame || coconutImgs[0];
    image(img, coconut.x + coconut.shakeX, coconut.y, coconut.r * 2, coconut.r * 2);
  } else {
    image(coconutImgs[coconut.state], coconut.x + coconut.shakeX, coconut.y, coconut.r * 2, coconut.r * 2);
  }
}

function updateShake() {
  if (coconut.shakeTimer > 0) {
    coconut.shakeX = sin(coconut.shakeTimer * 2.2) * coconut.shakeTimer * 0.55;
    coconut.shakeTimer--;
  } else {
    coconut.shakeX = 0;
  }
}

function updateFlyAway() {
  if (!coconut.flying) return;

  coconut.x += coconut.flyVX;
  coconut.y += coconut.flyVY;
  coconut.flyVY += 0.9;
  coconut.flyRotation += coconut.flyRotSpeed;
  coconut.flyAlpha -= 14;

  if (coconut.flyAlpha <= 0 || coconut.y > height + 100) {
    if (score < 10) launchKakamoraToSlot(score);
    score++;
    treeHits++;
    coconut.x = width / 2;
    coconut.y = height * 0.42;
    coconut.state = 0;
    coconut.flying = false;
    coconut.flyAlpha = 255;
    coconut.flyRotation = 0;
    coconut.shakeX = 0;
    coconut.shakeTimer = 0;
  }
}

// ====== TRAIL INPUT ======
function mouseDragged() {
  let pos = createVector(mouseX, mouseY);
  trail.push(pos);

  let dx = 0, dy = 0;
  if (trail.length > 1) {
    let prev = trail[trail.length - 2];
    dx = pos.x - prev.x;
    dy = pos.y - prev.y;
    velocities.push(sqrt(dx * dx + dy * dy));
  } else {
    velocities.push(0);
  }

  // 날아가는 중엔 드래그 무시
  if (dist(mouseX, mouseY, coconut.x, coconut.y) < coconut.r && !coconut.flying) {
    spawnParticles(mouseX, mouseY, dx, dy);
    coconut.shakeTimer = max(coconut.shakeTimer, 10);
  }

  if (trail.length > 15) trail.shift();
  if (velocities.length > 15) velocities.shift();
}

function mouseReleased() {
  // 드래그가 코코넛을 지나쳤는지 확인
  let hits = trail.filter(p => dist(p.x, p.y, coconut.x, coconut.y) < coconut.r).length;

  if (hits >= 2 && !coconut.flying) {
    coconut.state++;
    flashAlpha = 25;
    if (coconut.state >= 4) {
      // 4번째 드래그 → 날아가기 시작
      coconut.flying = true;
      coconut.flyVX = random([-1, 1]) * random(10, 16);
      coconut.flyVY = random(-22, -16);
      coconut.flyRotSpeed = random(-0.28, 0.28);
      bgBlue = 255;
    }
  }

  trail = [];
  velocities = [];
}

// ====== TRAIL DRAW ======
function drawTrail() {
  noFill();
  for (let i = 1; i < trail.length; i++) {
    let speed = velocities[i] || 0;
    strokeWeight(map(speed, 0, 50, 1, 8));
    stroke(255, 200);
    line(trail[i - 1].x, trail[i - 1].y, trail[i].x, trail[i].y);
  }
}


// ====== SCORE ======
function drawScore() {
  noStroke();
  textSize(22);
  textAlign(LEFT, TOP);

  fill(255, 255, 255, 220);
  text(`coconut x${score}`, 20, 20);
}

// ====== SLOT POSITION HELPER ======
function getSlotPos(i) {
  const gap = 8;
  const size = floor((width - 40 - gap * 9) / 10);
  const startX = 20 + size / 2;
  return {
    x: startX + i * (size + gap),
    y: height - size / 2 - 16,
    size
  };
}

// ====== KAKAMORA SLOTS ======
function drawKakamoraSlots() {
  for (let i = 0; i < 10; i++) {
    let { x, y, size } = getSlotPos(i);
    let filled = i < score;

    if (filled) {
      drawingContext.save();
      drawingContext.beginPath();
      drawingContext.arc(x, y, size / 2, 0, Math.PI * 2);
      drawingContext.clip();
      imageMode(CORNER);
      image(kakomoraImgs[i % 5], x - size / 2, y - size / 2, size, size);
      drawingContext.restore();

      noFill();
      stroke(255);
      strokeWeight(2.5);
      ellipse(x, y, size, size);
    } else {
      fill(50, 50, 50, 190);
      stroke(110, 110, 110);
      strokeWeight(1.5);
      ellipse(x, y, size, size);

      noStroke();
      fill(170, 170, 170);
      textSize(size * 0.28);
      textAlign(CENTER, CENTER);
      text('?', x, y);
    }
  }
}

// ====== FLYING KAKAMORA ======
function launchKakamoraToSlot(slotIdx) {
  let { x: tx, y: ty, size } = getSlotPos(slotIdx);
  flyingKakamoraList.push({
    startX: width / 2,
    startY: height * 0.42,
    targetX: tx,
    targetY: ty,
    t: 0,
    imgIdx: slotIdx % 5,
    size
  });
}

function updateFlyingKakamoraList() {
  for (let k of flyingKakamoraList) k.t += 0.032;
  flyingKakamoraList = flyingKakamoraList.filter(k => k.t <= 1);
}

function drawFlyingKakamoraList() {
  for (let k of flyingKakamoraList) {
    let ease = 1 - pow(1 - min(k.t, 1), 2);
    let x = lerp(k.startX, k.targetX, ease);
    let y = lerp(k.startY, k.targetY, ease) - sin(k.t * PI) * height * 0.3;
    let sz = lerp(k.size * 1.8, k.size, ease);

    drawingContext.save();
    drawingContext.beginPath();
    drawingContext.arc(x, y, sz / 2, 0, Math.PI * 2);
    drawingContext.clip();
    imageMode(CORNER);
    image(kakomoraImgs[k.imgIdx], x - sz / 2, y - sz / 2, sz, sz);
    drawingContext.restore();

    noFill();
    stroke(255, 200);
    strokeWeight(2);
    ellipse(x, y, sz, sz);
  }
}

// ====== PARTICLES ======
class Particle {
  constructor(x, y, dx, dy) {
    this.pos = createVector(x, y);
    // 드래그 반대 방향 + 랜덤 퍼짐
    let baseAngle = (dx !== 0 || dy !== 0)
      ? atan2(dy, dx) + PI + random(-0.7, 0.7)
      : random(TWO_PI);
    let spd = random(1.5, 5);
    this.vel = createVector(cos(baseAngle) * spd, sin(baseAngle) * spd);
    this.life = 255;
    this.r = random(3, 7);
    this.isHusk = random() > 0.4; // 60% 껍질(갈색), 40% 과육(크림)
  }

  update() {
    this.pos.add(this.vel);
    this.vel.y += 0.18; // 중력
    this.vel.mult(0.93); // 마찰
    this.life -= 7;
  }

  draw() {
    noStroke();
    if (this.isHusk) fill(158, 108, 52, this.life);
    else fill(242, 224, 188, this.life);
    ellipse(this.pos.x, this.pos.y, this.r, this.r * 0.55);
  }
}

function spawnParticles(x, y, dx, dy) {
  for (let i = 0; i < 5; i++) particles.push(new Particle(x, y, dx, dy));
}

function drawParticles() {
  for (let i = particles.length - 1; i >= 0; i--) {
    particles[i].update();
    particles[i].draw();
    if (particles[i].life <= 0) particles.splice(i, 1);
  }
}

// ====== FLASH ======
function drawFlash() {
  if (flashAlpha > 0) {
    fill(255, flashAlpha);
    rect(0, 0, width, height);
    flashAlpha -= 20;
  }
}
