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

const PIP_POSITIONS = {
  0: [],
  1: [[0, 0]],
  2: [[-1, -1], [1, 1]],
  3: [[-1, -1], [0, 0], [1, 1]],
  4: [[-1, -1], [1, -1], [-1, 1], [1, 1]],
  5: [[-1, -1], [1, -1], [0, 0], [-1, 1], [1, 1]],
  6: [[-1, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [1, 1]]
};

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 class="drag-tile">
        <div class="drag-half">${this._renderPips(tile.left)}</div>
        <div class="drag-divider"></div>
        <div class="drag-half">${this._renderPips(tile.right)}</div>
      </div>
    `;
    el.style.cssText = `
      position:fixed;z-index:9999;pointer-events:none;
      left:${x - 24}px;top:${y - 42}px;
    `;
    document.body.appendChild(el);
    this.proxyEl = el;
  }

  _renderPips(value) {
    const positions = PIP_POSITIONS[value] || [];
    const spread = 7;
    const pipSize = 4.5;
    return positions.map(([px, py]) => {
      const cx = 20 + px * spread;
      const cy = 18 + py * spread;
      return `<span class="drag-pip" style="left:${cx - pipSize/2}px;top:${cy - pipSize/2}px;width:${pipSize}px;height:${pipSize}px;"></span>`;
    }).join('');
  }

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

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

    const hit = this.board.hitTestEndpoints(x, y);

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

      const tileEl = this.proxyEl.querySelector('.drag-tile');
      if (tileMatches) {
        this.nearEnd = hit.end;
        this.isValid = true;
        this.board.setGhost(this.tile, hit.end, true);
        tileEl.classList.add('drag-valid');
        tileEl.classList.remove('drag-invalid');
      } else {
        this.nearEnd = hit.end;
        this.isValid = false;
        this.board.setGhost(this.tile, hit.end, false);
        tileEl.classList.remove('drag-valid');
        tileEl.classList.add('drag-invalid');
      }
    } else {
      if (this.nearEnd) {
        this.board.clearGhost();
        this.nearEnd = null;
        this.isValid = false;
        const tileEl = this.proxyEl.querySelector('.drag-tile');
        tileEl.classList.remove('drag-valid', 'drag-invalid');
      }
    }
  }

  _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);

    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 + 24, top + 42);
      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.querySelector('.drag-tile').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.querySelector('.drag-tile').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; }
      .drag-tile {
        width: 48px;
        height: 84px;
        background: linear-gradient(160deg, #FFFDF5 0%, #F5EFE0 100%);
        border: 2px solid var(--gold);
        border-radius: 7px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-between;
        box-shadow: 0 10px 30px rgba(0,0,0,0.5), 0 0 20px rgba(228,172,56,0.3);
        transform: scale(1.15);
        transition: transform 0.15s cubic-bezier(0.34,1.56,0.64,1),
                    border-color 0.15s, box-shadow 0.15s;
      }
      .drag-tile.drag-valid {
        border-color: var(--emerald);
        transform: scale(1.2);
        box-shadow: 0 10px 30px rgba(0,0,0,0.5), 0 0 20px rgba(16,185,129,0.4);
      }
      .drag-tile.drag-invalid {
        border-color: var(--error);
        transform: scale(0.95);
        box-shadow: 0 6px 20px rgba(0,0,0,0.5), 0 0 12px rgba(239,68,68,0.3);
      }
      .drag-half {
        position: relative;
        width: 100%;
        flex: 1;
      }
      .drag-divider {
        width: 78%;
        height: 1.5px;
        background: linear-gradient(90deg, transparent, #B8A080, transparent);
        flex-shrink: 0;
      }
      .drag-pip {
        position: absolute;
        border-radius: 50%;
        background: radial-gradient(circle at 35% 35%, #3a3a3a, #0a0a0a);
        box-shadow: inset 0 1px 1px rgba(255,255,255,0.15);
      }
    `;
  }

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