/* global React */
const { useState: useStateWG } = React;

// Bloco visual individual dentro da grade semanal
function Bloco({ bloco, top, altura, onClick, cadeia, isContinuacao, density, conflitoStatus }) {
  const [hover, setHover] = useStateWG(false);
  const h = bloco.tipo === 'plantao' ? window.getHospital(bloco.hospitalId)
          : (bloco.tipo === 'deslocamento' && bloco.hospitalDestinoId)
            ? window.getHospital(bloco.hospitalDestinoId)
            : (bloco.tipo === 'deslocamento' && bloco.hospitalOrigemId)
              ? window.getHospital(bloco.hospitalOrigemId)
              : null;

  let estilo = {};
  let conteudo = null;
  const compacto = altura < 56;

  if (bloco.tipo === 'plantao') {
    estilo = {
      background: h.corWash,
      color: h.corDeep,
      border: bloco.turnoIncerto ? `1px dashed ${h.corDeep}` : `1px solid ${h.corDeep}22`,
      borderLeft: `4px solid ${h.cor}`,
      paddingLeft: compacto ? '6px' : '8px',
    };
    conteudo = (
      <div style={{display:'flex', flexDirection:'column', gap: 2, height:'100%', justifyContent:'flex-start', position:'relative'}}>
        {bloco.turnoIncerto && (
          <div title={`Turno incerto: ${bloco.turnoIncerto.replace('-ou-', ' / ')}. Toque pra resolver.`} style={{
            position:'absolute', top: -2, right: -2,
            width: 16, height: 16, borderRadius: 999,
            background: 'var(--warn, #B98A3F)', color: '#fff',
            display:'grid', placeItems:'center',
            boxShadow: '0 0 0 2px var(--bg)',
            fontSize: 10, fontWeight: 900, lineHeight: 1,
          }}>?</div>
        )}
        {bloco.viaTroca && (
          <div title={`Recebido em troca · ${bloco.trocaCom || ''}`} style={{
            position:'absolute', top: -2, right: -2,
            width: 16, height: 16, borderRadius: 999,
            background: '#A299CB', color: '#fff',
            display:'grid', placeItems:'center',
            boxShadow: '0 0 0 2px var(--bg)',
          }}>
            <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
          </div>
        )}
        {bloco.fromRecorrencia && (
          <div title="Plantão recorrente" style={{
            position:'absolute', top: -2, left: -2,
            width: 14, height: 14, borderRadius: 999,
            background: 'var(--bg)', color: h.corDeep,
            display:'grid', placeItems:'center',
            boxShadow: `0 0 0 1px ${h.corDeep}55`,
            fontSize: 9, fontWeight: 700,
          }}>↻</div>
        )}
        <div style={{fontFamily:'var(--font-body)', fontWeight:700, fontSize: 13, letterSpacing:'0.02em', lineHeight: 1.1}}>
          {h.abrev}
        </div>
        {!compacto && (
          <div style={{fontSize: 11, opacity: 0.85, fontWeight: 500}}>
            {window.fmtHora(bloco.horaInicio)} · {bloco.duracao}h
          </div>
        )}
        {altura >= 110 && (
          <div style={{fontSize: 11, opacity: 0.7, marginTop: 'auto', fontWeight: 500}}>
            {h.endereco}
          </div>
        )}
      </div>
    );
  } else if (bloco.tipo === 'deslocamento') {
    const corBase = h ? h.cor : '#C5BE99';
    const corDeep = h ? h.corDeep : '#7A7350';
    estilo = {
      background: corBase,
      backgroundImage: 'repeating-linear-gradient(45deg, rgba(255,255,255,0.45) 0 3px, transparent 3px 7px)',
      color: corDeep,
      opacity: 0.7,
      border: `1px dashed ${corDeep}55`,
    };
    const direcao = bloco.paraCasa ? '→ casa'
                  : bloco.deCasa ? `casa → ${h?.abrev || ''}`
                  : h?.abrev ? `→ ${h.abrev}` : '';
    conteudo = (
      <div style={{display:'flex', alignItems:'center', gap: 4, height:'100%', overflow: 'hidden'}}>
        <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{flexShrink: 0}}><path d="M14 16H9m10 0h3v-3.15a1 1 0 0 0-.84-.99L16 11l-2.7-3.6a1 1 0 0 0-.8-.4H5.24a2 2 0 0 0-1.8 1.1l-.8 1.63A6 6 0 0 0 2 12.42V16h2"/><circle cx="6.5" cy="16.5" r="2.5"/><circle cx="16.5" cy="16.5" r="2.5"/></svg>
        {altura >= 20 && <span style={{fontSize: 10, fontWeight: 700, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{Math.round(bloco.duracao * 60)}min {altura >= 36 ? direcao : ''}</span>}
      </div>
    );
  } else if (bloco.tipo === 'outros') {
    const ICONS = { manicure: '💅', treino: '🏃', reuniao: '👥', consulta: '🩺', familia: '👨‍👩‍👧', pessoal: '💆' };
    const icon = ICONS[bloco.categoria] || '📌';
    estilo = {
      background: 'var(--colo-aqua-50, #E8F6F8)',
      color: '#3D7884',
      border: '1px solid #9AD8E166',
    };
    conteudo = (
      <div style={{display:'flex', flexDirection:'column', gap: 2, height:'100%'}}>
        <div style={{display:'flex', alignItems:'center', gap: 4, fontSize: compacto ? 11 : 12, fontWeight: 600}}>
          <span style={{fontSize: 13}}>{icon}</span>
          {!compacto && <span>{bloco.motivo || bloco.categoria || 'Atividade'}</span>}
        </div>
        {altura >= 60 && bloco.motivo && bloco.categoria && (
          <div style={{opacity: 0.8, fontSize: 10, marginTop: 2}}>{bloco.categoria}</div>
        )}
      </div>
    );
  } else if (bloco.tipo === 'sono') {
    estilo = {
      background: 'var(--colo-sage-50)',
      color: '#5A6E50',
      border: '1px solid #BEC99A',
    };
    conteudo = (
      <div style={{display:'flex', flexDirection:'column', gap: 2, height:'100%'}}>
        <div style={{display:'flex', alignItems:'center', gap: 6}}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>
          {!compacto && <span style={{fontSize: 12, fontWeight: 600}}>Descanso</span>}
        </div>
        {altura >= 80 && <div style={{opacity: 0.8, fontFamily: 'var(--font-hand)', fontSize: 16, marginTop: 4}}>{bloco.duracao}h protegidas</div>}
      </div>
    );
  } else if (bloco.tipo === 'cedido') {
    estilo = {
      background: 'transparent',
      backgroundImage: 'repeating-linear-gradient(45deg, var(--colo-sand-50) 0 4px, transparent 4px 8px)',
      color: 'var(--ink-2)',
      border: '1px dashed var(--line-2)',
    };
    conteudo = (
      <div style={{fontSize: 11, lineHeight: 1.2}}>
        <div style={{fontWeight: 600}}>Cedido</div>
        {altura >= 56 && <div style={{opacity: 0.7, marginTop: 2}}>→ {bloco.cedidoPara}</div>}
      </div>
    );
  } else if (bloco.tipo === 'trocado') {
    estilo = {
      background: 'transparent',
      backgroundImage: 'repeating-linear-gradient(135deg, var(--colo-lavender-50, #ECEAF4) 0 5px, transparent 5px 10px)',
      color: 'var(--ink-2)',
      border: '1px dashed #A299CB',
    };
    conteudo = (
      <div style={{fontSize: 11, lineHeight: 1.2}}>
        <div style={{fontWeight: 600, display:'flex', alignItems:'center', gap:4}}>
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
          Trocado
        </div>
        {altura >= 56 && <div style={{opacity: 0.7, marginTop: 2}}>↔ {bloco.trocadoCom}</div>}
      </div>
    );
  }

  // Tooltip resumido — sempre disponível em hover, especialmente útil em blocos compactos
  const tipoLabel = bloco.tipo === 'outros' ? (bloco.motivo || bloco.categoria || 'Atividade')
                  : bloco.tipo === 'plantao' ? (h?.abrev || 'Plantão')
                  : bloco.tipo === 'deslocamento'
                    ? (bloco.paraCasa ? 'Deslocamento → casa'
                        : bloco.deCasa ? `Deslocamento casa → ${h?.abrev || ''}`
                        : `Deslocamento → ${h?.abrev || ''}`)
                  : bloco.tipo === 'sono' ? 'Sono protegido'
                  : bloco.tipo === 'cedido' ? `Cedido → ${bloco.cedidoPara || ''}`
                  : bloco.tipo === 'trocado' ? `Trocado ↔ ${bloco.trocadoCom || ''}`
                  : 'Bloqueio';
  const horaFim = (bloco.horaInicio + bloco.duracao) % 24;
  const tooltip = `${tipoLabel} · ${window.fmtHora(bloco.horaInicio)} — ${window.fmtHora(horaFim)} (${bloco.duracao}h)`
    + (bloco.motivo ? ` · ${bloco.motivo}` : '')
    + (cadeia && !isContinuacao ? ` · em cadeia de ${Math.round(cadeia.horas)}h sem descanso` : '');

  const className = conflitoStatus === 'pendente' ? 'bloco-em-conflito'
                  : conflitoStatus === 'aceito' ? 'bloco-em-conflito-aceito'
                  : '';
  return (
    <button
      type="button"
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      title={conflitoStatus === 'pendente' ? `⚠ CONFLITO · ${tooltip}` : tooltip}
      aria-label={tooltip}
      className={className}
      style={{
        position: 'absolute', left: 4, right: 4,
        top: `${top}px`, height: `${altura}px`,
        padding: compacto ? '4px 8px' : '8px 10px',
        borderRadius: 'var(--r-sm)',
        cursor: 'pointer',
        font: 'inherit', textAlign: 'left',
        transition: 'transform var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease)',
        transform: hover ? 'translateY(-1px)' : 'none',
        boxShadow: hover ? 'var(--shadow-md)' : 'none',
        zIndex: hover ? 4 : 1,
        ...estilo,
      }}
    >
      {cadeia && !isContinuacao && (
        <div style={{
          position: 'absolute', top: -10, left: 8,
          padding: '2px 8px',
          background: 'var(--err)', color: 'white',
          borderRadius: 'var(--r-pill)',
          fontSize: 10, fontWeight: 700,
          fontFamily: 'var(--font-body)',
          letterSpacing: '0.02em',
          display: 'flex', alignItems: 'center', gap: 4,
          boxShadow: 'var(--shadow-sm)',
          whiteSpace: 'nowrap',
          zIndex: 5,
        }}>
          <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0Z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
          {Math.round(cadeia.horas)}h sem descanso
        </div>
      )}
      {conteudo}
    </button>
  );
}

function WeekGrid({ blocos, semanaInicio, onSelectBloco, carregando }) {
  const cadeias = window.calcCadeias(blocos);
  const idsConflito = window.idsBlocosEmConflito ? window.idsBlocosEmConflito(blocos) : new Set();

  // Auto-fit: a grade calcula sua própria altura por linha pra caber na viewport
  // sem scroll vertical. Considera o espaço a partir do topo do container.
  const containerRef = React.useRef(null);
  const [rowHeight, setRowHeight] = useStateWG(28);

  React.useLayoutEffect(() => {
    const compute = () => {
      const node = containerRef.current;
      if (!node) return;
      const rect = node.getBoundingClientRect();
      // Espaço disponível abaixo do dayrow do grid
      const dayRowH = 56;        // altura aprox do header de dias da grade
      const safety = 28;         // margem pra legenda + borda inferior
      const available = window.innerHeight - rect.top - dayRowH - safety;
      const h = Math.max(20, Math.min(60, Math.floor(available / 24)));
      setRowHeight(h);
    };
    compute();
    window.addEventListener('resize', compute);
    return () => window.removeEventListener('resize', compute);
  }, []);

  const ROW_HEIGHT = rowHeight;

  // Datas dos 7 dias
  const datas = Array.from({length: 7}, (_, i) => window.addDias(semanaInicio, i));

  const cadeiaDoBloco = (bloco) => {
    if (bloco.tipo !== 'plantao' && bloco.tipo !== 'deslocamento') return null;
    return cadeias.find(c => c.blocos[0].id === bloco.id) || null;
  };

  const hojeISO = window.HOJE_ISO;

  return (
    <div ref={containerRef} className="weekgrid-wrap" style={{
      background: 'var(--bg)',
      borderRadius: 'var(--r-lg)',
      boxShadow: 'var(--shadow-sm)',
      overflow: 'auto',
      border: '1px solid var(--line)',
      WebkitOverflowScrolling: 'touch',
    }}>
      {/* Em mobile, força min-width pra grade não comprimir os 7 dias */}
      <style>{`
        @media (max-width: 720px) {
          .weekgrid-wrap > div { min-width: 640px; }
        }
      `}</style>
      {/* Day row — header da grade */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: '52px repeat(7, 1fr)',
        borderBottom: '1px solid var(--line)',
        background: 'var(--bg-alt)',
      }}>
        <div style={{
          display: 'grid', placeItems: 'center',
          borderRight: '1px solid var(--line)',
        }}>
          <span className="eyebrow" style={{fontSize: 9, color: 'var(--ink-3)'}}>hora</span>
        </div>
        {window.DIAS_SEMANA.map((d, i) => {
          const iso = datas[i];
          const dt = window.fromISO(iso);
          const ehHoje = iso === hojeISO;
          const ehFds = i >= 5;
          return (
            <div key={d} style={{
              padding: '10px 12px',
              borderLeft: '1px solid var(--line)',
              textAlign: 'left',
              background: ehHoje ? 'var(--colo-blue-50)' : 'transparent',
              position: 'relative',
            }}>
              <div className="eyebrow" style={{
                fontSize: 10,
                color: ehHoje ? 'var(--colo-blue-tag)' : (ehFds ? 'var(--ink-2)' : 'var(--ink-3)'),
                fontWeight: ehHoje ? 800 : 700,
              }}>{d}</div>
              <div style={{
                display: 'flex', alignItems: 'baseline', gap: 4,
                marginTop: 2,
              }}>
                <span style={{
                  fontFamily: 'var(--font-display)',
                  fontSize: 22, fontWeight: ehHoje ? 600 : 500,
                  lineHeight: 1, letterSpacing: '-0.02em',
                  color: ehHoje ? 'var(--colo-blue-tag)' : 'var(--ink)',
                }}>{dt.getDate()}</span>
                <span style={{
                  fontSize: 11, fontWeight: 500, color: 'var(--ink-3)',
                  fontFamily: 'var(--font-body)',
                }}>{window.MESES_CURTO[dt.getMonth()]}</span>
              </div>
              {ehHoje && (
                <span aria-hidden="true" style={{
                  position: 'absolute', left: 12, right: 12, bottom: -1,
                  height: 2, background: 'var(--colo-blue-tag)', borderRadius: 2,
                }}/>
              )}
            </div>
          );
        })}
      </div>

      <div style={{
        display: 'grid',
        gridTemplateColumns: '52px repeat(7, 1fr)',
        position: 'relative',
      }}>
        {blocos.length === 0 && !carregando && (
          <div style={{
            position: 'absolute',
            top: 0, left: 52, right: 0, bottom: 0,
            display: 'grid', placeItems: 'center',
            pointerEvents: 'none',
            zIndex: 3,
          }}>
            <div style={{
              padding: '20px 28px',
              background: 'rgba(255, 250, 243, 0.94)',
              borderRadius: 'var(--r-md)',
              border: '1px dashed var(--line-2)',
              textAlign: 'center',
              maxWidth: 360,
            }}>
              <div style={{
                fontFamily: 'var(--font-display)',
                fontSize: 22, fontWeight: 500,
                color: 'var(--ink)',
                lineHeight: 1.2,
              }}>Nenhum plantão esta semana.</div>
              <div className="handwritten" style={{
                fontSize: 22,
                color: 'var(--colo-sage, #5A6E50)',
                marginTop: 4,
              }}>aproveite.</div>
            </div>
          </div>
        )}
        <div style={{borderRight: '1px solid var(--line)', background: 'var(--bg)'}}>
          {Array.from({length: 24}).map((_, h) => {
            const ehMarcador = h % 6 === 0;     // 00, 06, 12, 18 — divisores fortes
            const ehSubMarc = !ehMarcador && h % 3 === 0; // 03, 09, 15, 21 — leves
            return (
              <div key={h} style={{
                height: ROW_HEIGHT,
                borderTop: h !== 0
                  ? (ehMarcador ? '1px solid var(--line-2)' : '1px solid transparent')
                  : 'none',
                paddingRight: 8,
                display: 'flex', alignItems: 'flex-start', justifyContent: 'flex-end',
                fontFamily: 'var(--font-body)',
                fontVariantNumeric: 'tabular-nums',
                fontSize: ehMarcador ? 10 : 9,
                fontWeight: ehMarcador ? 700 : 500,
                color: ehMarcador ? 'var(--ink-2)' : 'var(--ink-3)',
                letterSpacing: '0.02em',
                lineHeight: 1,
                paddingTop: 3,
                opacity: ehMarcador || ehSubMarc ? 1 : 0,
              }}>
                {String(h).padStart(2, '0')}
              </div>
            );
          })}
        </div>

        {datas.map((iso, diaIdx) => {
          const ehFds = diaIdx >= 5;
          return (
          <div key={iso} style={{
            position: 'relative',
            borderLeft: '1px solid var(--line)',
            background: iso === hojeISO
              ? 'rgba(155,194,231,0.06)'
              : (ehFds ? 'rgba(58,46,42,0.012)' : 'transparent'),
          }}>
            {Array.from({length: 24}).map((_, h) => (
              <div key={h} style={{
                height: ROW_HEIGHT,
                borderTop: (h % 6 === 0 && h !== 0) ? '1px solid var(--line)' : 'none',
              }}/>
            ))}

            {blocos.filter(b => b.data === iso).map(b => {
              const top = b.horaInicio * ROW_HEIGHT;
              const altMax = (24 - b.horaInicio) * ROW_HEIGHT;
              const altura = Math.min(b.duracao * ROW_HEIGHT, altMax);
              const conflitoStatus = idsConflito.has(`${b.id}:pendente`) ? 'pendente'
                                  : idsConflito.has(`${b.id}:aceito`) ? 'aceito' : null;
              return (
                <Bloco key={b.id}
                  bloco={b} top={top} altura={altura}
                  cadeia={cadeiaDoBloco(b)}
                  conflitoStatus={conflitoStatus}
                  density={ROW_HEIGHT}
                  onClick={() => onSelectBloco(b)}
                />
              );
            })}

            {/* Continuação visual de blocos que viram meia-noite */}
            {diaIdx > 0 && blocos.filter(b => {
              return b.data === datas[diaIdx-1] && (b.horaInicio + b.duracao) > 24;
            }).map(b => {
              const altura = (b.horaInicio + b.duracao - 24) * ROW_HEIGHT;
              const conflitoStatus = idsConflito.has(`${b.id}:pendente`) ? 'pendente'
                                  : idsConflito.has(`${b.id}:aceito`) ? 'aceito' : null;
              return (
                <Bloco key={`${b.id}-cont`}
                  bloco={b} top={0} altura={altura}
                  cadeia={null} isContinuacao={true}
                  conflitoStatus={conflitoStatus}
                  density={ROW_HEIGHT}
                  onClick={() => onSelectBloco(b)}
                />
              );
            })}
          </div>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { WeekGrid, Bloco });
