/* Voxel chibi avatar built from CSS-3D cubes.
   Each cube = 6 faces with darkened/lightened shades for pseudo-lighting.
   Layout is on a 16x16x16 grid; `U` is the unit size in px.
*/

function Cube({ x, y, z, size = 1, color, U, tint = 1 }) {
  const s = size * U;
  // simple faked lighting
  const base = color;
  const top   = shade(base,  0.18 * tint);
  const side1 = shade(base, -0.10 * tint);
  const side2 = shade(base, -0.22 * tint);
  const bottom= shade(base, -0.35 * tint);

  const style = {
    width: s, height: s,
    transform: `translate3d(${x*U}px, ${y*U}px, ${z*U}px)`,
  };
  return (
    <div className="cube" style={style}>
      <div className="face" style={{ background: top,    transform: `translateZ(${s}px)` }} />
      <div className="face" style={{ background: bottom, transform: `rotateX(180deg) translateZ(0)` }} />
      <div className="face" style={{ background: side1,  transform: `rotateY(90deg) translateZ(${s}px)`, width: s, height: s }} />
      <div className="face" style={{ background: side1,  transform: `rotateY(-90deg) translateZ(0)`, width: s, height: s }} />
      <div className="face" style={{ background: side2,  transform: `rotateX(-90deg) translateZ(0)`, width: s, height: s }} />
      <div className="face" style={{ background: side2,  transform: `rotateX(90deg) translateZ(${s}px)`, width: s, height: s }} />
    </div>
  );
}

function shade(hex, amt) {
  // amt in [-1,1]; lighten if +, darken if -
  const c = hex.replace('#',''); 
  const r = parseInt(c.substring(0,2),16);
  const g = parseInt(c.substring(2,4),16);
  const b = parseInt(c.substring(4,6),16);
  const f = (v) => {
    const t = amt < 0 ? 0 : 255;
    const p = Math.abs(amt);
    return Math.round((t - v) * p + v);
  };
  return `rgb(${f(r)},${f(g)},${f(b)})`;
}

/* Chibi palette — matches OneMoreDay app accents */
const PAL_ALIVE = {
  skin:  "#f7c9a5",
  hair:  "#2a1d18",
  eye:   "#101014",
  shirt: "#ebc726",   // app yellow
  pants: "#1f1f1f",
  shoe:  "#0c0c0c",
  cheek: "#FF6B35",   // app orange
};
const PAL_DYING = {
  skin:  "#8d7f78",
  hair:  "#1a1513",
  eye:   "#2a2a30",
  shirt: "#4a2a1a",
  pants: "#171717",
  shoe:  "#050505",
  cheek: "#FF4540",   // app red
};

/* Voxel list: [x, y, z, part]. Centered around x=y=0 for the body. 
   z is "up". Built as a chibi: big head, tiny body. ~16 voxels tall.
*/
const VOXELS = (() => {
  const list = [];
  const push = (x,y,z,part) => list.push([x,y,z,part]);

  // --- Shoes (z=0) ---
  for (let x = -2; x <= -1; x++) for (let y = -1; y <= 0; y++) push(x,y,0,"shoe");
  for (let x =  1; x <=  2; x++) for (let y = -1; y <= 0; y++) push(x,y,0,"shoe");

  // --- Legs (z=1..3) ---
  for (let z = 1; z <= 3; z++) {
    for (let y = -1; y <= 0; y++) {
      push(-2, y, z, "pants"); push(-1, y, z, "pants");
      push( 1, y, z, "pants"); push( 2, y, z, "pants");
    }
  }

  // --- Torso (z=4..7), 5 wide, 2 deep ---
  for (let z = 4; z <= 7; z++) {
    for (let x = -2; x <= 2; x++) for (let y = -1; y <= 0; y++) push(x,y,z,"shirt");
  }
  // Arms (z=4..6) out to sides
  for (let z = 4; z <= 6; z++) {
    for (let y = -1; y <= 0; y++) { push(-3,y,z,"shirt"); push(3,y,z,"shirt"); }
  }
  // hands
  for (let y = -1; y <= 0; y++) { push(-3,y,3,"skin"); push(3,y,3,"skin"); }

  // --- Neck (z=8) ---
  for (let y = -1; y <= 0; y++) { push(-1,y,8,"skin"); push(0,y,8,"skin"); }

  // --- Head: 7w x 6d x 6h (z=9..14) -- big chibi head ---
  for (let z = 9; z <= 14; z++) {
    for (let x = -3; x <= 3; x++) {
      for (let y = -2; y <= 1; y++) {
        // clip corners for a rounder look
        const corner = (Math.abs(x) === 3 && (y === -2 || y === 1)) && (z === 9 || z === 14);
        if (corner) continue;
        push(x,y,z,"skin");
      }
    }
  }

  // --- Hair cap (top of head, z=13..15) ---
  for (let x = -3; x <= 3; x++) {
    for (let y = -2; y <= 1; y++) {
      if (Math.abs(x) === 3 && (y === -2 || y === 1)) continue;
      push(x,y,15,"hair");
    }
  }
  // front fringe
  for (let x = -3; x <= 3; x++) push(x, 1, 14, "hair");
  for (let x = -2; x <= 2; x++) push(x, 1, 13, "hair");
  // side hair
  for (let z = 11; z <= 14; z++) { push(-3,-2,z,"hair"); push(3,-2,z,"hair"); push(-3,1,z,"hair"); push(3,1,z,"hair"); }

  // --- Eyes (on y=1 face of head, z=11) ---
  push(-2, 1, 11, "eye"); push(-1, 1, 11, "eye");
  push( 1, 1, 11, "eye"); push( 2, 1, 11, "eye");

  // --- Cheeks ---
  push(-3, 1, 10, "cheek"); push(3, 1, 10, "cheek");

  return list;
})();

function VoxelChibi({ unit = 7, dying = false, holding }) {
  // Compute bounds so we can center
  const xs = VOXELS.map(v=>v[0]), ys = VOXELS.map(v=>v[1]), zs = VOXELS.map(v=>v[2]);
  const minX = Math.min(...xs), maxX = Math.max(...xs);
  const minY = Math.min(...ys), maxY = Math.max(...ys);
  const minZ = Math.min(...zs), maxZ = Math.max(...zs);
  const w = (maxX - minX + 1) * unit;
  const h = (maxZ - minZ + 1) * unit;

  const palette = dying ? PAL_DYING : PAL_ALIVE;

  return (
    <div className={"voxel-stage " + (dying ? "dying" : "")}
         style={{ width: w * 1.8, height: h * 1.9 }}>
      <div className="voxel-scene">
        {VOXELS.map(([x,y,z,part], i) => (
          <Cube key={i}
            x={x - (minX+maxX)/2}
            y={y - (minY+maxY)/2}
            z={z - minZ}
            size={1}
            U={unit}
            color={palette[part] || "#888"}
            tint={part === "eye" ? 0 : 1}
          />
        ))}
        {/* Item being held — a tiny "day" cube floating */}
        {holding && (
          <Cube x={4} y={0} z={6} size={1.6} U={unit} color="#ffd86b" tint={1} />
        )}
      </div>
    </div>
  );
}

window.VoxelChibi = VoxelChibi;
