/* Sub-guia Mapa — grid do galpão, drag-and-drop, barra de rascunho */

const { useState, useRef } = React;

function StackDots({ n, total = 4 }) {
  return (
    <div className="dots" aria-label={n + ' de ' + total + ' níveis'}>
      {Array.from({ length: total }).map((_, i) => (
        <span key={i} className={'d' + (i < n ? '' : ' off')}></span>
      ))}
    </div>
  );
}

function CellView({ cell, pallets, drag, placing, showCodes, justMoved, shake, onDown, onMove, onUp, onPlace }) {
  const isOrigin = drag && drag.fromCode === cell.code;
  const stack = isOrigin ? cell.stack.slice(0, -1) : cell.stack;
  const topId = stack[stack.length - 1];
  const pal = topId ? pallets[topId] : null;
  const prod = pal ? ESTQ.PRODUTOS[pal.prod] : null;

  const cls = ['cell'];
  if (!pal) cls.push('vazia'); else cls.push('ocupada');
  if (pal && pal.status === 'ponta_sugerida') cls.push('ponta-sug');
  if (pal && pal.status === 'ponta') cls.push('ponta-conf');
  if (isOrigin) cls.push('origem');

  // Validade (somente material no topo)
  const vinfo = pal && ESTQ.isMat(pal) ? ESTQ.validadeEstado(pal.validade) : null;
  if (vinfo && vinfo.st === 'vencido') cls.push('vencido');
  if (vinfo && vinfo.st === 'breve') cls.push('vence-breve');

  const hasSpace = cell.stack.length < 4;
  if (drag && !isOrigin && hasSpace) cls.push('can-drop');
  if (drag && !isOrigin && !hasSpace) cls.push('full-block');
  if (drag && drag.over && drag.over.type === 'celula' && drag.over.code === cell.code && !isOrigin) cls.push('drop-over');
  if (placing && hasSpace) cls.push('place-ok');
  if (placing && !hasSpace) cls.push('full-block');
  if (justMoved && justMoved.code === cell.code) cls.push('just-moved');
  if (shake && shake.code === cell.code) cls.push('shake-cell');

  const blocked = (drag || placing) && !hasSpace && !isOrigin;

  const style = {};
  if (pal && pal.status === 'normal') {
    style.background = prod.cor;
    style.color = prod.escuro ? '#FFFFFF' : 'var(--navy-900)';
  }
  if (!pal && cell.tipo === 'pontas') {
    style.background = 'transparent';
    style.borderColor = 'var(--orange-300)';
  }

  return (
    <div
      className={cls.join(' ')}
      style={style}
      data-drop={cell.code}
      onPointerDown={placing ? undefined : (e) => onDown(e, cell)}
      onPointerMove={placing ? undefined : onMove}
      onPointerUp={placing ? undefined : onUp}
      onClick={placing && hasSpace ? () => onPlace(cell) : undefined}
    >
      <div className="top-line">
        {showCodes && pal && (pal.status !== 'normal') ? null : (showCodes && <span className="code">{cell.code.split('-')[1]}</span>)}
        {blocked && <span className="badge-block"><EIcon name="ban" size={13} strokeWidth={2.4} /> 4/4</span>}
        {!blocked && pal && pal.status === 'ponta_sugerida' && <span className="badge-cell sug">PONTA?</span>}
        {!blocked && pal && pal.status === 'ponta' && <span className="badge-cell conf">PONTA</span>}
        {!blocked && vinfo && vinfo.st === 'vencido' && <span className="badge-cell venc"><EIcon name="alert" size={9} strokeWidth={2.6} /> VENC.</span>}
        {!blocked && vinfo && vinfo.st === 'breve' && <span className="badge-cell breve"><EIcon name="alert" size={9} strokeWidth={2.6} /> {ESTQ.fmtValCurto(pal.validade)}</span>}
      </div>
      {pal ? (
        <div>
          <div className="nome">{prod.curto}</div>
          <StackDots n={stack.length} />
        </div>
      ) : (
        <div></div>
      )}
    </div>
  );
}

function DragGhost({ drag, pallets }) {
  if (!drag) return null;
  const pal = pallets[drag.palletId];
  const prod = ESTQ.PRODUTOS[pal.prod];
  const isSug = pal.status === 'ponta_sugerida';
  const isConf = pal.status === 'ponta';
  const style = {
    left: drag.x, top: drag.y,
    background: isSug ? 'var(--danger-500)' : isConf
      ? 'repeating-linear-gradient(135deg, var(--orange-600) 0 7px, var(--orange-500) 7px 14px)'
      : prod.cor,
    color: isSug || isConf || prod.escuro ? '#fff' : 'var(--navy-900)',
  };
  return (
    <div className="drag-ghost" style={style}>
      <div className="nome">{prod.curto}</div>
      <div style={{ fontSize: 11, fontWeight: 600, opacity: 0.85 }}>{ESTQ.qtdCurto(pal)}{ESTQ.isMat(pal) ? '' : ' · ' + ESTQ.palletM2(pal)}</div>
    </div>
  );
}

// Rótulo/estilo das zonas que não são fileira de pallet (divisórias no mapa)
const ZONA_DIVIDER_CLS = { corridor: 'corridor', fixed: 'zona-fixed', door: 'zona-door', stairs: 'zona-stairs', note: 'zona-note' };

function MapView({ db, gal, canWrite, placing, showCodes, justMoved, shake, stageEl,
                   onTapCell, onDropMove, onDropRascunho, onReject, onPlace, onOpenRascunho }) {
  const galpao = db.galpoes[gal];
  const [drag, setDrag] = useState(null);
  const dragInfo = useRef(null);

  function stagePoint(e) {
    const rect = stageEl.current.getBoundingClientRect();
    const scale = rect.width / 1280;
    return { x: (e.clientX - rect.left) / scale, y: (e.clientY - rect.top) / scale };
  }

  function onDown(e, cell) {
    if (!cell.stack.length) return;
    dragInfo.current = { sx: e.clientX, sy: e.clientY, cell, active: false, over: null };
    try { e.currentTarget.setPointerCapture(e.pointerId); } catch (err) { /* eventos sintéticos */ }
  }

  function onMove(e) {
    const di = dragInfo.current;
    if (!di) return;
    if (!di.active) {
      if (Math.hypot(e.clientX - di.sx, e.clientY - di.sy) < 10) return;
      if (!canWrite) return; // offline / sem permissão: arrasto desabilitado, toque continua abrindo o card
      di.active = true;
    }
    const el = document.elementFromPoint(e.clientX, e.clientY);
    const dropEl = el && el.closest('[data-drop]');
    let over = null;
    if (dropEl) {
      const d = dropEl.getAttribute('data-drop');
      if (d === 'rascunho') {
        over = { type: 'rascunho' };
      } else {
        const c = galpao.cells.find((c) => c.code === d);
        if (c && c.code !== di.cell.code) {
          over = c.stack.length < 4 ? { type: 'celula', code: d } : { type: 'cheia', code: d };
        }
      }
    }
    di.over = over;
    const pt = stagePoint(e);
    setDrag({ palletId: di.cell.stack[di.cell.stack.length - 1], fromCode: di.cell.code, x: pt.x, y: pt.y, over });
  }

  function onUp() {
    const di = dragInfo.current;
    dragInfo.current = null;
    if (!di) return;
    if (!di.active) { setDrag(null); onTapCell(di.cell); return; }
    const over = di.over;
    setDrag(null);
    if (!over) return;
    if (over.type === 'rascunho') onDropRascunho(di.cell);
    else if (over.type === 'cheia') onReject(over.code);
    else onDropMove(di.cell, over.code);
  }

  const rascIds = galpao.rascunho;

  return (
    <React.Fragment>
      <div className="map-wrap" data-screen-label={'Mapa G' + gal}>
        <div className="map-grid">
          {galpao.layout.map((entry) =>
            entry.tipo === 'pallet-row' ? (
              <div className="map-row" key={entry.zonaId} style={{ gridTemplateColumns: '24px repeat(' + Math.max(1, galpao.cells.filter((c) => c.zonaId === entry.zonaId).length) + ', 1fr)' }}>
                <div className="row-label">{entry.rowLetter}</div>
                {galpao.cells.filter((c) => c.zonaId === entry.zonaId).map((cell) => (
                  <CellView
                    key={cell.code
                      + (justMoved && justMoved.code === cell.code ? '-m' + justMoved.k : '')
                      + (shake && shake.code === cell.code ? '-s' + shake.k : '')}
                    cell={cell} pallets={db.pallets}
                    drag={drag} placing={placing} showCodes={showCodes} justMoved={justMoved} shake={shake}
                    onDown={onDown} onMove={onMove} onUp={onUp} onPlace={onPlace}
                  />
                ))}
              </div>
            ) : (
              <div className={'zona-divider ' + (ZONA_DIVIDER_CLS[entry.tipo] || 'zona-fixed')} key={entry.zonaId}>
                {entry.label}
              </div>
            )
          )}
        </div>
      </div>

      {!placing && (
        <div
          className={'rasc-bar' + (drag && drag.over && drag.over.type === 'rascunho' ? ' drop-over' : '')}
          data-drop="rascunho"
          onClick={onOpenRascunho}
        >
          <div className="arrow"><EIcon name="arrowDown" size={24} strokeWidth={2.2} /></div>
          <div className="lbl">
            Soltar aqui → Rascunho
            <span className="sub">Pallets fora de posição ficam na guia Rascunho</span>
          </div>
          <div className="thumbs">
            {rascIds.slice(0, 6).map((id) => {
              const p = db.pallets[id];
              return <div key={id} className="thumb" style={{ background: ESTQ.PRODUTOS[p.prod].cor }} title={ESTQ.PRODUTOS[p.prod].nome}></div>;
            })}
            {rascIds.length > 0 && <div className="count">{rascIds.length}</div>}
            {rascIds.length === 0 && <span style={{ fontSize: 13, color: 'var(--gray-600)', fontWeight: 600 }}>Vazio</span>}
          </div>
        </div>
      )}

      <DragGhost drag={drag} pallets={db.pallets} />
    </React.Fragment>
  );
}

window.MapView = MapView;
