import * as audio from '../../../core/audio.js';
import * as juice from '../../../core/juice.js';
import { canPlay } from '../logic/rules.js';

export class DominoDrag {
  constructor(options = {}) {
    this.board = options.board;
    this.onPlace = options.onPlace || null;
    this.onCancel = options.onCancel || null;
    this.getEnds = options.getEnds || (() => ({ leftEnd: null, rightEnd: null }));

    this.active = false;
    this.tile = null;
    this.proxyEl = null;
    this.nearEnd = null;
    this.isValid = false;

    this._onMove = this._onMove.bind(this);
    this._onUp = this._onUp.bind(this);
  }

  start(tile, startInfo) {
    this.tile = tile;
    this.active = true;
    this.nearEnd = null;
    this.isValid = false;

    this._createProxy(tile, startInfo.x, startInfo.y);

    document.addEventListener('pointermove', this._onMove);
    document.addEventListener('pointerup', this._onUp);
    document.addEventListener('pointercancel', this._onUp);
    document.addEventListener('touchend', this._onUp);

    juice.hapticLight?.();
    audio.play('click');
  }

  _createProxy(tile, x, y) {
    const el = document.createElement('div');
    el.className = 'drag-proxy';
    el.innerHTML = `
      <div style="width:40px;height:70px;background:#fffff0;border:2px solid #10b981;border-radius:6px;
                  display:flex;flex-direction:column;align-items:center;justify-content:space-between;padding:5px 4px;
                  box-shadow:0 8px 24px rgba(0,0,0,0.4);transform:scale(1.1);">
        <div style="display:flex;flex-wrap:wrap;width:22px;height:22px;align-items:center;justify-content:center;gap:1px;">
          ${this._renderPips(tile.left)}
        </div>
        <div style="width:80%;height:1px;background:#bbb;"></div>
        <div style="display:flex;flex-wrap:wrap;width:22px;height:22px;align-items:center;justify-content:center;gap:1px;">
          ${this._renderPips(tile.right)}
        </div>
      </div>
    `;
    el.style.cssText = `
      position:fixed;z-index:9999;pointer-events:none;
      left:${x - 20}px;top:${y - 35}px;
      transition:transform 0.1s;
    `;
    document.body.appendChild(el);
    this.proxyEl = el;
  }

  _renderPips(value) {
    let s = '';
    for (let i = 0; i < value; i++) {
      s += '<span style="width:5px;height:5px;border-radius:50%;background:#1a1a1a;"></span>';
    }
    return s;
  }

  _onMove(e) {
    if (!this.active) return;

    const x = e.clientX;
    const y = e.clientY;
    this.proxyEl.style.left = (x - 20) + 'px';
    this.proxyEl.style.top = (y - 35) + 'px';

    const hit = this.board.hitTestEndpoints(x, y);
    const { leftEnd, rightEnd } = this.getEnds();

    if (hit) {
      const endValue = hit.value;
      const tileMatches = this.tile.left === endValue || this.tile.right === endValue;

      if (tileMatches) {
        this.nearEnd = hit.end;
        this.isValid = true;
        this.board.setGhost(this.tile, hit.end, true);
        this.proxyEl.style.transform = 'scale(1.15)';
        this.proxyEl.querySelector('div').style.borderColor = '#10b981';
      } else {
        this.nearEnd = hit.end;
        this.isValid = false;
        this.board.setGhost(this.tile, hit.end, false);
        this.proxyEl.style.transform = 'scale(0.95)';
        this.proxyEl.querySelector('div').style.borderColor = '#ef4444';
      }
    } else {
      if (this.nearEnd) {
        this.board.clearGhost();
        this.nearEnd = null;
        this.isValid = false;
        this.proxyEl.style.transform = 'scale(1.1)';
        this.proxyEl.querySelector('div').style.borderColor = '#10b981';
      }
    }
  }

  _onUp(e) {
    if (!this.active) return;
    this.active = false;

    document.removeEventListener('pointermove', this._onMove);
    document.removeEventListener('pointerup', this._onUp);
    document.removeEventListener('pointercancel', this._onUp);
    document.removeEventListener('touchend', this._onUp);

    // Re-check hit from proxy position (touchend may not update pointer coords)
    if (!this.nearEnd && this.proxyEl) {
      const left = parseInt(this.proxyEl.style.left) || 0;
      const top = parseInt(this.proxyEl.style.top) || 0;
      const hit = this.board.hitTestEndpoints(left + 20, top + 35);
      if (hit) {
        const tileMatches = this.tile.left === hit.value || this.tile.right === hit.value;
        if (tileMatches) {
          this.nearEnd = hit.end;
          this.isValid = true;
        }
      }
    }

    this.board.clearGhost();

    if (this.nearEnd && this.isValid) {
      this._animateSnap(() => {
        juice.hapticMedium?.();
        audio.play('place', 'game');
        this.onPlace?.(this.tile, this.nearEnd);
        this._cleanup();
      });
    } else {
      this._animateBounceBack(() => {
        if (this.nearEnd && !this.isValid) {
          juice.hapticError?.();
        }
        this.onCancel?.();
        this._cleanup();
      });
    }
  }

  _animateSnap(callback) {
    if (!this.proxyEl) { callback(); return; }
    this.proxyEl.style.transition = 'all 0.15s cubic-bezier(0.16,1,0.3,1)';
    this.proxyEl.style.opacity = '0';
    this.proxyEl.style.transform = 'scale(0.5)';
    setTimeout(callback, 150);
  }

  _animateBounceBack(callback) {
    if (!this.proxyEl) { callback(); return; }
    this.proxyEl.style.transition = 'all 0.25s cubic-bezier(0.34,1.56,0.64,1)';
    this.proxyEl.style.opacity = '0';
    this.proxyEl.style.transform = 'translateY(40px) scale(0.7)';
    setTimeout(callback, 250);
  }

  _cleanup() {
    if (this.proxyEl) {
      this.proxyEl.remove();
      this.proxyEl = null;
    }
    this.tile = null;
    this.nearEnd = null;
    this.isValid = false;
  }

  getStyle() {
    return `.drag-proxy { will-change: transform, left, top; }`;
  }

  destroy() {
    this._cleanup();
    document.removeEventListener('pointermove', this._onMove);
    document.removeEventListener('pointerup', this._onUp);
    document.removeEventListener('pointercancel', this._onUp);
    document.removeEventListener('touchend', this._onUp);
  }
}
