import { createCanvas, clear } from '../../../core/canvas.js';
import { computeLayout, hitTestEndpoint, getSnapRadius } from '../logic/layout.js';
import { drawTile, drawEndpointGlow } from './tile-renderer.js';
import { TILE_W, TILE_H, DOUBLE_W, DOUBLE_H } from '../logic/layout.js';

export class DominoBoard {
  constructor(container, options = {}) {
    this.container = container;
    this.onEndpointTap = options.onEndpointTap || null;

    const rect = container.getBoundingClientRect();
    this.width = rect.width || 370;
    this.height = rect.height || 360;

    const { canvas, ctx } = createCanvas(container, this.width, this.height);
    canvas.style.cssText = 'width:100%;height:100%;border-radius:12px;touch-action:none;';
    this.canvas = canvas;
    this.ctx = ctx;

    this.chain = [];
    this.layout = { tiles: [], endpoints: { left: null, right: null } };
    this.ghost = null;
    this.activeEndpoint = null;
    this.panOffset = { x: 0, y: 0 };
    this.animatingTile = null;

    this._setupPanListener();
  }

  setChain(chain) {
    this.chain = chain;
    this.layout = computeLayout(chain, this.width, this.height);
    this.draw();
  }

  setGhost(tile, end, valid) {
    if (!tile || !end) { this.ghost = null; this.draw(); return; }
    const ep = end === 'left' ? this.layout.endpoints.left : this.layout.endpoints.right;
    if (!ep) { this.ghost = null; this.draw(); return; }

    const dbl = tile.left === tile.right;
    const w = dbl ? DOUBLE_W : TILE_H;
    const h = dbl ? DOUBLE_H : TILE_W;

    this.ghost = { tile, x: ep.x, y: ep.y, w, h, rotation: 90, valid };
    this.draw();
  }

  clearGhost() {
    this.ghost = null;
    this.draw();
  }

  setActiveEndpoint(end) {
    this.activeEndpoint = end;
    this.draw();
  }

  clearActiveEndpoint() {
    this.activeEndpoint = null;
    this.draw();
  }

  getEndpointScreenPos(end) {
    const ep = end === 'left' ? this.layout.endpoints.left : this.layout.endpoints.right;
    if (!ep) return null;
    const rect = this.canvas.getBoundingClientRect();
    const scaleX = rect.width / this.width;
    const scaleY = rect.height / this.height;
    return { x: rect.left + ep.x * scaleX, y: rect.top + ep.y * scaleY, value: ep.value };
  }

  hitTestEndpoints(screenX, screenY) {
    const rect = this.canvas.getBoundingClientRect();
    const canvasX = (screenX - rect.left) * (this.width / rect.width);
    const canvasY = (screenY - rect.top) * (this.height / rect.height);

    const leftEp = this.layout.endpoints.left;
    const rightEp = this.layout.endpoints.right;

    if (leftEp && hitTestEndpoint(canvasX, canvasY, leftEp)) return { end: 'left', value: leftEp.value };
    if (rightEp && hitTestEndpoint(canvasX, canvasY, rightEp)) return { end: 'right', value: rightEp.value };
    return null;
  }

  animatePlacement(tile, end, callback) {
    const ep = end === 'left' ? this.layout.endpoints.left : this.layout.endpoints.right;
    if (!ep) { callback?.(); return; }

    const dbl = tile.left === tile.right;
    const w = dbl ? DOUBLE_W : TILE_H;
    const h = dbl ? DOUBLE_H : TILE_W;

    const startScale = 1.3;
    const duration = 180;
    const startTime = performance.now();

    const animate = (now) => {
      const t = Math.min((now - startTime) / duration, 1);
      const ease = 1 - Math.pow(1 - t, 3);
      const scale = startScale + (1 - startScale) * ease;

      this.animatingTile = { tile, x: ep.x, y: ep.y, w, h, rotation: 90, scale };
      this.draw();

      if (t < 1) {
        requestAnimationFrame(animate);
      } else {
        this.animatingTile = null;
        callback?.();
      }
    };
    requestAnimationFrame(animate);
  }

  draw() {
    const ctx = this.ctx;
    clear(ctx, this.width, this.height);

    ctx.fillStyle = '#0d3815';
    ctx.fillRect(0, 0, this.width, this.height);

    this._drawFelt(ctx);

    if (this.chain.length === 0) {
      ctx.fillStyle = 'rgba(255,255,255,0.12)';
      ctx.font = '600 14px system-ui, sans-serif';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText('ضع أول قطعة', this.width / 2, this.height / 2);
      this._drawEndpointIndicators(ctx);
      return;
    }

    for (const lt of this.layout.tiles) {
      drawTile(ctx, lt.x, lt.y, lt.w, lt.h, lt.tile, { rotation: lt.rotation === 90 ? 0 : 90 });
    }

    this._drawEndpointIndicators(ctx);

    if (this.ghost) {
      drawTile(ctx, this.ghost.x, this.ghost.y, this.ghost.w, this.ghost.h,
        this.ghost.tile, { rotation: 0, ghost: true, invalid: !this.ghost.valid });
    }

    if (this.animatingTile) {
      const at = this.animatingTile;
      ctx.save();
      ctx.translate(at.x, at.y);
      ctx.scale(at.scale, at.scale);
      ctx.translate(-at.x, -at.y);
      drawTile(ctx, at.x, at.y, at.w, at.h, at.tile, { rotation: 0 });
      ctx.restore();
    }
  }

  _drawFelt(ctx) {
    ctx.fillStyle = 'rgba(30,80,40,0.3)';
    for (let i = 0; i < this.width; i += 16) {
      for (let j = 0; j < this.height; j += 16) {
        if ((i + j) % 32 === 0) ctx.fillRect(i, j, 8, 8);
      }
    }
  }

  _drawEndpointIndicators(ctx) {
    const leftEp = this.layout.endpoints.left;
    const rightEp = this.layout.endpoints.right;

    if (this.chain.length === 0) {
      drawEndpointGlow(ctx, this.width / 2, this.height / 2, getSnapRadius(), true);
      return;
    }

    if (this.activeEndpoint === 'left' || this.activeEndpoint === 'both') {
      if (leftEp) drawEndpointGlow(ctx, leftEp.x, leftEp.y, getSnapRadius(), true);
    }
    if (this.activeEndpoint === 'right' || this.activeEndpoint === 'both') {
      if (rightEp) drawEndpointGlow(ctx, rightEp.x, rightEp.y, getSnapRadius(), true);
    }
  }

  _setupPanListener() {
    let startX, startY, isPanning = false;

    this.canvas.addEventListener('pointerdown', (e) => {
      if (this.onEndpointTap) {
        const hit = this.hitTestEndpoints(e.clientX, e.clientY);
        if (hit) { this.onEndpointTap(hit); return; }
      }
      startX = e.clientX;
      startY = e.clientY;
      isPanning = false;
    });

    this.canvas.addEventListener('pointermove', (e) => {
      if (startX === undefined) return;
      const dx = e.clientX - startX;
      const dy = e.clientY - startY;
      if (Math.abs(dx) + Math.abs(dy) > 15) isPanning = true;
    });

    this.canvas.addEventListener('pointerup', () => { startX = undefined; });
  }

  destroy() {
    this.canvas.remove();
  }
}
