// Premium 60fps board renderer — wood grain, 3D checkers, glow, particles
import { WHITE, BLACK } from '../logic/rules.js';
import { getColor } from '../../../core/theme.js';

const t = (k, fb) => getColor(k, null) || (window.__EL3AB_THEME?.[k]) || fb;

export function drawBoard(ctx, w, h, state, options = {}) {
  const { highlights = [], selectedPoint = null, animFrame, particles = [] } = options;

  const margin = 8;
  const barWidth = Math.round(w * 0.06);
  const bearW = Math.round(w * 0.07);
  const boardW = w - margin * 2;
  const boardH = h - margin * 2;
  const innerW = boardW - bearW;
  const pointW = (innerW - barWidth) / 12;
  const pointH = boardH * 0.42;
  const checkerR = Math.min(pointW * 0.43, 17);

  const layout = { margin, pointW, pointH, barWidth, boardW, boardH, bearW, innerW, checkerR, w, h };
  const barX = margin + 6 * pointW;

  ctx.clearRect(0, 0, w, h);

  // ── Board frame ──
  ctx.fillStyle = t('bg_board_border', '#5C3A0E');
  roundRect(ctx, margin - 3, margin - 3, boardW + 6, boardH + 6, 6);
  ctx.fill();

  // ── Board surface (wood grain) ──
  const woodGrad = ctx.createLinearGradient(margin, margin, margin, margin + boardH);
  woodGrad.addColorStop(0, t('bg_board_light', '#3D6B1E'));
  woodGrad.addColorStop(0.5, t('bg_board_dark', '#2D5016'));
  woodGrad.addColorStop(1, t('bg_board_light', '#3D6B1E'));
  ctx.fillStyle = woodGrad;
  ctx.fillRect(margin, margin, boardW, boardH);

  // Wood grain lines
  ctx.globalAlpha = 0.06;
  for (let i = 0; i < 30; i++) {
    const gy = margin + (boardH / 30) * i + Math.sin(i * 0.7) * 3;
    ctx.strokeStyle = '#000';
    ctx.lineWidth = 0.5 + Math.random() * 0.5;
    ctx.beginPath();
    ctx.moveTo(margin, gy);
    ctx.bezierCurveTo(margin + boardW * 0.3, gy + 2, margin + boardW * 0.7, gy - 2, margin + boardW, gy);
    ctx.stroke();
  }
  ctx.globalAlpha = 1;

  // ── Bar ──
  const barGrad = ctx.createLinearGradient(barX, 0, barX + barWidth, 0);
  barGrad.addColorStop(0, t('bg_bar_dark', '#2A1800'));
  barGrad.addColorStop(0.5, t('bg_bar_light', '#3D2B1A'));
  barGrad.addColorStop(1, t('bg_bar_dark', '#2A1800'));
  ctx.fillStyle = barGrad;
  ctx.fillRect(barX, margin, barWidth, boardH);

  // Bar edge shadows
  ctx.fillStyle = 'rgba(0,0,0,0.4)';
  ctx.fillRect(barX, margin, 1.5, boardH);
  ctx.fillRect(barX + barWidth - 1.5, margin, 1.5, boardH);

  // ── Bear-off tray ──
  const bearX = margin + innerW;
  ctx.fillStyle = t('bg_bearoff', '#1A0E00');
  roundRect(ctx, bearX, margin, bearW, boardH, 3);
  ctx.fill();
  ctx.strokeStyle = 'rgba(139,69,19,0.4)';
  ctx.lineWidth = 1;
  roundRect(ctx, bearX, margin, bearW, boardH, 3);
  ctx.stroke();

  // Bear-off divider
  ctx.strokeStyle = 'rgba(255,255,255,0.05)';
  ctx.beginPath();
  ctx.moveTo(bearX, margin + boardH / 2);
  ctx.lineTo(bearX + bearW, margin + boardH / 2);
  ctx.stroke();

  // ── Points (triangles) ──
  for (let i = 0; i < 24; i++) {
    const { x, y, isTop } = getPointCoords(i, margin, pointW, pointH, barWidth, boardH);
    const isDark = i % 2 === 0;
    const isValid = highlights.includes(i);
    const isSel = selectedPoint === i;

    ctx.beginPath();
    if (isTop) {
      ctx.moveTo(x, y);
      ctx.lineTo(x + pointW, y);
      ctx.lineTo(x + pointW / 2, y + pointH);
    } else {
      ctx.moveTo(x, y);
      ctx.lineTo(x + pointW, y);
      ctx.lineTo(x + pointW / 2, y - pointH);
    }
    ctx.closePath();

    if (isSel) {
      ctx.fillStyle = 'rgba(255, 215, 0, 0.35)';
      ctx.fill();
      ctx.strokeStyle = '#FFD700';
      ctx.lineWidth = 2;
      ctx.stroke();
    } else if (isValid) {
      ctx.fillStyle = 'rgba(16, 185, 129, 0.35)';
      ctx.fill();
      ctx.strokeStyle = '#10B981';
      ctx.lineWidth = 2.5;
      ctx.shadowColor = '#10B981';
      ctx.shadowBlur = 8;
      ctx.stroke();
      ctx.shadowBlur = 0;
    } else {
      const ptGrad = ctx.createLinearGradient(x, isTop ? y : y - pointH, x, isTop ? y + pointH : y);
      if (isDark) {
        ptGrad.addColorStop(0, t('bg_point_dark', '#8B4513'));
        ptGrad.addColorStop(1, t('bg_point_dark_tip', '#5C2D0A'));
      } else {
        ptGrad.addColorStop(0, t('bg_point_light', '#D2691E'));
        ptGrad.addColorStop(1, t('bg_point_light_tip', '#A0522D'));
      }
      ctx.fillStyle = ptGrad;
      ctx.fill();
      ctx.strokeStyle = 'rgba(0,0,0,0.2)';
      ctx.lineWidth = 0.5;
      ctx.stroke();
    }
  }

  // ── Point numbers ──
  ctx.font = `bold ${Math.max(8, pointW * 0.32)}px sans-serif`;
  ctx.textAlign = 'center';
  ctx.fillStyle = 'rgba(255,255,255,0.15)';
  for (let i = 0; i < 24; i++) {
    const { x, y, isTop } = getPointCoords(i, margin, pointW, pointH, barWidth, boardH);
    const ny = isTop ? y - 6 : y + 10;
    ctx.fillText(String(i + 1), x + pointW / 2, ny);
  }

  // ── Checkers ──
  for (let i = 0; i < 24; i++) {
    const pieces = state.points[i];
    if (pieces.length === 0) continue;
    const { x, y, isTop } = getPointCoords(i, margin, pointW, pointH, barWidth, boardH);
    const cx = x + pointW / 2;
    const maxVis = 5;
    const count = pieces.length;
    const vis = Math.min(count, maxVis);
    const spacing = Math.min(checkerR * 2, pointH / vis);

    const pointIsSelected = selectedPoint === i;
    const pointIsValid = highlights.includes(i);

    for (let j = 0; j < vis; j++) {
      const cy = isTop ? y + checkerR + j * spacing : y - checkerR - j * spacing;
      const isTopChecker = j === vis - 1;
      drawChecker(ctx, cx, cy, pieces[j].type, checkerR, {
        glow: pointIsSelected && isTopChecker,
        pulse: pointIsValid && isTopChecker
      });
    }
    if (count > maxVis) {
      const ly = isTop ? y + checkerR + (vis - 1) * spacing : y - checkerR - (vis - 1) * spacing;
      ctx.fillStyle = '#fff';
      ctx.font = `bold ${checkerR * 0.65}px sans-serif`;
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText(String(count), cx, ly);
    }
  }

  // ── Bar checkers ──
  const barCx = barX + barWidth / 2;
  drawBarCheckers(ctx, state.bar[WHITE], barCx, margin + boardH * 0.65, checkerR, WHITE, 1);
  drawBarCheckers(ctx, state.bar[BLACK], barCx, margin + boardH * 0.35, checkerR, BLACK, -1);

  // ── Bear-off ──
  drawBearOff(ctx, state.outside[WHITE], bearX, bearW, margin + boardH * 0.55, checkerR, WHITE, 1);
  drawBearOff(ctx, state.outside[BLACK], bearX, bearW, margin + boardH * 0.45, checkerR, BLACK, -1);

  // Highlight bear-off if valid
  if (highlights.includes('off')) {
    ctx.fillStyle = 'rgba(16, 185, 129, 0.25)';
    ctx.strokeStyle = '#10B981';
    ctx.lineWidth = 2;
    ctx.shadowColor = '#10B981';
    ctx.shadowBlur = 6;
    roundRect(ctx, bearX + 2, margin + 2, bearW - 4, boardH - 4, 3);
    ctx.fill();
    ctx.stroke();
    ctx.shadowBlur = 0;
  }

  // ── Particles ──
  if (particles.length) drawParticles(ctx, particles);

  return layout;
}

function drawChecker(ctx, cx, cy, type, r, opts = {}) {
  const isWhite = type === WHITE;

  // Drop shadow
  ctx.beginPath();
  ctx.arc(cx + 1, cy + 2, r, 0, Math.PI * 2);
  ctx.fillStyle = 'rgba(0,0,0,0.35)';
  ctx.fill();

  // Base
  ctx.beginPath();
  ctx.arc(cx, cy, r, 0, Math.PI * 2);
  const grad = ctx.createRadialGradient(cx - r * 0.3, cy - r * 0.3, r * 0.1, cx, cy, r);
  if (isWhite) {
    grad.addColorStop(0, '#FFFFFF');
    grad.addColorStop(0.6, '#F5E6D3');
    grad.addColorStop(1, '#C8A882');
  } else {
    grad.addColorStop(0, '#555555');
    grad.addColorStop(0.6, '#2A2A2A');
    grad.addColorStop(1, '#0A0A0A');
  }
  ctx.fillStyle = grad;
  ctx.fill();

  // Edge ring
  ctx.strokeStyle = isWhite ? 'rgba(160,120,60,0.5)' : 'rgba(100,100,100,0.5)';
  ctx.lineWidth = 1.5;
  ctx.stroke();

  // Inner decoration ring
  ctx.beginPath();
  ctx.arc(cx, cy, r * 0.62, 0, Math.PI * 2);
  ctx.strokeStyle = isWhite ? 'rgba(180,140,80,0.25)' : 'rgba(120,120,120,0.25)';
  ctx.lineWidth = 1;
  ctx.stroke();

  // Specular highlight
  ctx.beginPath();
  ctx.ellipse(cx - r * 0.2, cy - r * 0.25, r * 0.35, r * 0.2, -0.3, 0, Math.PI * 2);
  ctx.fillStyle = `rgba(255,255,255,${isWhite ? 0.3 : 0.12})`;
  ctx.fill();

  // Glow for selected
  if (opts.glow) {
    ctx.beginPath();
    ctx.arc(cx, cy, r + 3, 0, Math.PI * 2);
    ctx.strokeStyle = '#FFD700';
    ctx.lineWidth = 2.5;
    ctx.shadowColor = '#FFD700';
    ctx.shadowBlur = 12;
    ctx.stroke();
    ctx.shadowBlur = 0;
  }
}

function drawBarCheckers(ctx, pieces, cx, startY, r, type, dir) {
  const count = pieces.length;
  if (!count) return;
  const vis = Math.min(count, 4);
  for (let j = 0; j < vis; j++) {
    drawChecker(ctx, cx, startY + dir * j * r * 1.9, type, r);
  }
  if (count > 4) {
    ctx.fillStyle = '#fff';
    ctx.font = `bold ${r * 0.7}px sans-serif`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(String(count), cx, startY + dir * vis * r * 1.9);
  }
}

function drawBearOff(ctx, pieces, bearX, bearW, startY, r, type, dir) {
  const count = pieces.length;
  if (!count) return;
  const cx = bearX + bearW / 2;
  const sliceH = Math.min(6, r * 0.4);
  const vis = Math.min(count, 15);
  const isWhite = type === WHITE;

  for (let i = 0; i < vis; i++) {
    const sy = startY + dir * i * sliceH;
    ctx.fillStyle = isWhite ? '#F5E6D3' : '#2A2A2A';
    ctx.fillRect(cx - r + 2, sy, (r - 2) * 2, sliceH - 1);
    ctx.strokeStyle = isWhite ? 'rgba(160,120,60,0.3)' : 'rgba(80,80,80,0.3)';
    ctx.lineWidth = 0.5;
    ctx.strokeRect(cx - r + 2, sy, (r - 2) * 2, sliceH - 1);
  }
  ctx.fillStyle = '#fff';
  ctx.font = `bold ${r * 0.7}px sans-serif`;
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText(String(count), cx, startY + dir * (vis * sliceH + r));
}

function drawParticles(ctx, particles) {
  for (const p of particles) {
    if (p.alpha <= 0) continue;
    ctx.globalAlpha = p.alpha;
    ctx.fillStyle = p.color || '#FFD700';
    if (p.shape === 'star') {
      drawStar(ctx, p.x, p.y, p.size, p.rot || 0);
    } else {
      ctx.beginPath();
      ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
      ctx.fill();
    }
  }
  ctx.globalAlpha = 1;
}

function drawStar(ctx, x, y, size, rotation) {
  ctx.save();
  ctx.translate(x, y);
  ctx.rotate(rotation);
  ctx.beginPath();
  for (let i = 0; i < 5; i++) {
    const a = (i * 4 * Math.PI) / 5 - Math.PI / 2;
    ctx[i === 0 ? 'moveTo' : 'lineTo'](Math.cos(a) * size, Math.sin(a) * size);
  }
  ctx.closePath();
  ctx.fill();
  ctx.restore();
}

export function getPointCoords(pointIndex, margin, pointW, pointH, barWidth, boardH) {
  let x, y, isTop;
  if (pointIndex >= 12) {
    const col = pointIndex - 12;
    x = margin + col * pointW + (col >= 6 ? barWidth : 0);
    y = margin;
    isTop = true;
  } else {
    const col = 11 - pointIndex;
    x = margin + col * pointW + (col >= 6 ? barWidth : 0);
    y = margin + boardH;
    isTop = false;
  }
  return { x, y, isTop };
}

export function hitTest(canvasX, canvasY, layout, state) {
  if (!layout) return null;
  const { margin, pointW, pointH, barWidth, boardH, bearW, innerW, checkerR } = layout;
  const barX = margin + 6 * pointW;
  const bearX = margin + innerW;

  if (canvasX >= barX && canvasX <= barX + barWidth) {
    if (canvasY > margin + boardH / 2) return { type: 'bar', player: WHITE };
    return { type: 'bar', player: BLACK };
  }
  if (canvasX >= bearX && canvasX <= bearX + bearW) {
    return { type: 'bearoff' };
  }
  for (let i = 0; i < 24; i++) {
    const { x, y, isTop } = getPointCoords(i, margin, pointW, pointH, barWidth, boardH);
    if (canvasX >= x && canvasX <= x + pointW) {
      if (isTop && canvasY >= margin && canvasY <= margin + pointH + checkerR * 2) {
        return { type: 'point', index: i };
      }
      if (!isTop && canvasY >= margin + boardH - pointH - checkerR * 2 && canvasY <= margin + boardH) {
        return { type: 'point', index: i };
      }
    }
  }
  return null;
}

export function getCheckerScreenPos(pointIndex, stackIdx, layout) {
  const { margin, pointW, pointH, barWidth, boardH, bearW, innerW, checkerR } = layout;
  const barX = margin + 6 * pointW;
  const bearX = margin + innerW;

  if (pointIndex === 'bar-white') return { x: barX + barWidth / 2, y: margin + boardH * 0.65 + stackIdx * checkerR * 1.9 };
  if (pointIndex === 'bar-black') return { x: barX + barWidth / 2, y: margin + boardH * 0.35 - stackIdx * checkerR * 1.9 };
  if (pointIndex === 'off') return { x: bearX + bearW / 2, y: margin + boardH / 2 };

  const { x, y, isTop } = getPointCoords(pointIndex, margin, pointW, pointH, barWidth, boardH);
  const spacing = Math.min(checkerR * 2, pointH / 5);
  const cx = x + pointW / 2;
  const cy = isTop ? y + checkerR + stackIdx * spacing : y - checkerR - stackIdx * spacing;
  return { x: cx, y: cy };
}

function roundRect(ctx, x, y, w, h, r) {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.arcTo(x + w, y, x + w, y + h, r);
  ctx.arcTo(x + w, y + h, x, y + h, r);
  ctx.arcTo(x, y + h, x, y, r);
  ctx.arcTo(x, y, x + w, y, r);
  ctx.closePath();
}
