/* Capacity Lanes — the new paradigm
   Each lane is a horizontal track. The track WIDTH represents the person's
   contracted hours. Tickets stack inside as colored blocks sized by hours.
   PTO is a hatched block. Over-capacity tickets extend past the limit line
   into a red overflow zone. */

const { useState: useStateL, useRef: useRefL } = React;

function Lanes({ tickets, onAssign, onRemove, dragTicket, setDragTicket, scenario, state }) {
  const [hoverLane, setHoverLane] = useStateL(null);
  const PX_PER_H = 18;  // 18px per hour ⇒ 40h = 720px lane width
  const OVERFLOW_PX = 200;

  return (
    <section className="lanes">
      {PEOPLE.map(p => {
        const b = personBucket(p, tickets);
        const trackW = p.contracted * PX_PER_H;
        let cursor = 0;
        const isLocked = state === 'locked' || state === 'closed';

        // PTO block placement: each PTO chunk occupies its hours at the END of the lane
        // (visually parking unavailable time on the right side)
        const ptoH = b.ptoH;
        const ptoStart = (p.contracted - ptoH) * PX_PER_H;

        return (
          <article
            key={p.id}
            className={"lane" + (b.overH ? " is-over" : "") + (b.pct < 50 ? " is-light" : "") + (hoverLane === p.id ? " is-hover" : "")}
            onDragOver={e => { if (dragTicket) { e.preventDefault(); setHoverLane(p.id); } }}
            onDragLeave={() => setHoverLane(null)}
            onDrop={e => {
              e.preventDefault();
              setHoverLane(null);
              if (dragTicket) onAssign(dragTicket, p.id);
            }}
          >
            {/* Identity column */}
            <div className="lane__who">
              <div className={"avatar avatar--lg"} data-tone={p.tone}>{p.name.charAt(0)}</div>
              <div className="lane__who__txt">
                <div className="lane__who__name">{p.name}</div>
                <div className="lane__who__role">{p.role}</div>
              </div>
              <div className="lane__who__nums">
                <div className={"lane__who__hours" + (b.overH ? " is-bad" : b.pct > 90 ? " is-warn" : "")}>
                  <span className="lane__who__used">{b.usedH}h</span>
                  <span className="lane__who__avail"> / {b.availH}</span>
                </div>
                <div className="lane__who__pct">{b.pct}% loaded</div>
              </div>
            </div>

            {/* The track itself — width = contracted hours; scrollable on narrow viewports */}
            <div className="lane__right">
              <div
                className="lane__track-wrap"
                style={{ '--track-w': trackW + 'px', '--overflow-w': OVERFLOW_PX + 'px' }}
              >
              <div className="lane__track">
                {/* Background scale ticks (day markers — 8h each) */}
                <div className="lane__scale">
                  {Array.from({ length: Math.ceil(p.contracted / 8) }, (_, i) => (
                    <span key={i} className="lane__scale-tick" style={{ left: (i * 8 * PX_PER_H) + 'px' }}>
                      <span className="lane__scale-tick__lbl">D{i + 1}</span>
                    </span>
                  ))}
                </div>

                {/* Tickets — sized by hours */}
                {b.assigned.map((t, idx) => {
                  const w = t.hours * PX_PER_H;
                  const x = cursor;
                  cursor += w;
                  const overLimit = x >= b.availH * PX_PER_H;
                  const partialOver = (x + w > b.availH * PX_PER_H) && !overLimit;
                  return (
                    <div
                      key={t.id}
                      className={"lane-tix" + (overLimit ? " is-over" : "") + (partialOver ? " is-partial" : "")}
                      style={{ left: x + 'px', width: w + 'px' }}
                      data-type={t.type}
                      draggable={!isLocked}
                      onDragStart={e => { setDragTicket(t); e.dataTransfer.effectAllowed = 'move'; }}
                      onDragEnd={() => setDragTicket(null)}
                      title={`${t.id} · ${t.title} · ${t.hours}h`}
                    >
                      <span className="lane-tix__type">{TYPE_LABEL[t.type]}</span>
                      <span className="lane-tix__id">{t.id}</span>
                      <span className="lane-tix__title">{t.title}</span>
                      <span className="lane-tix__h">{t.hours}h</span>
                      {!isLocked && (
                        <button className="lane-tix__x" onClick={(e) => { e.stopPropagation(); onRemove(t.id); }} aria-label="Remove from sprint">
                          <Icon d={ICONS.x} size={10} />
                        </button>
                      )}
                    </div>
                  );
                })}

                {/* PTO block — at the end of contracted time */}
                {p.pto.map((x, i) => (
                  <div
                    key={i}
                    className="lane-pto"
                    style={{ left: ptoStart + 'px', width: (x.hours * PX_PER_H) + 'px' }}
                    title={`PTO · ${x.label}`}
                  >
                    <span className="lane-pto__lbl">PTO · {x.label}</span>
                  </div>
                ))}

                {/* Capacity limit line at contracted hours */}
                <div className="lane__limit" style={{ left: trackW + 'px' }} title="Contracted hours" />

                {/* Drop hint */}
                {hoverLane === p.id && dragTicket && (
                  <div className="lane__drop-hint" style={{ left: (b.usedH * PX_PER_H) + 'px' }}>
                    + add to {p.name.split(' ')[0]}
                  </div>
                )}
                </div>
              </div>

              {/* Slack/overflow indicator under the track (outside scroll area) */}
              <div className="lane__foot">
                {b.overH > 0 && (
                  <Suggestion person={p} tickets={tickets} bucket={b} onAssign={onAssign} />
                )}
                {b.overH === 0 && b.slackH > 8 && (
                  <Suggestion person={p} tickets={tickets} bucket={b} variant="pull" onAssign={onAssign} />
                )}
                {b.overH === 0 && b.slackH <= 8 && b.slackH > 0 && (
                  <div className="lane__foot__ok">
                    <Icon d={ICONS.check} size={11} />
                    <span>{b.slackH}h slack · ready to lock</span>
                  </div>
                )}
                {b.overH === 0 && b.slackH === 0 && (
                  <div className="lane__foot__ok">
                    <Icon d={ICONS.check} size={11} />
                    <span>Exactly at capacity · no buffer for unplanned work</span>
                  </div>
                )}
              </div>
            </div>
          </article>
        );
      })}
    </section>
  );
}

/* AI-driven suggestion shown under each lane */
function Suggestion({ person, tickets, bucket, variant = 'reassign', onAssign }) {
  if (variant === 'pull') {
    // Find a P0/P1 backlog ticket that fits this person's slack
    const candidates = window.__backlog
      ? window.__backlog.filter(t => t.hours <= bucket.slackH && (t.priority === 'P0' || t.priority === 'P1'))
      : [];
    const pick = candidates[0];
    if (!pick) return null;
    return (
      <div className="suggestion suggestion--pull">
        <span className="suggestion__mark"><Icon d={ICONS.ai} size={10} /></span>
        <span className="suggestion__txt">
          <strong>{bucket.slackH}h slack.</strong> Pull <code>{pick.id}</code> · {pick.title} ({pick.hours}h)?
        </span>
        <button className="suggestion__act" onClick={() => onAssign(pick, person.id)}>
          Add →
        </button>
      </div>
    );
  }
  // reassign — find a ticket from this person to move to someone with slack
  const movable = bucket.assigned.slice().sort((a, b) => b.hours - a.hours);
  const target  = PEOPLE.find(p => p.id !== person.id && personBucket(p, tickets).slackH >= movable[0]?.hours);
  if (!movable[0] || !target) {
    return (
      <div className="suggestion suggestion--over">
        <span className="suggestion__mark suggestion__mark--bad"><Icon d={ICONS.alert} size={10} /></span>
        <span className="suggestion__txt">
          <strong>{bucket.overH}h over.</strong> No teammate with enough slack — remove a ticket or extend sprint.
        </span>
      </div>
    );
  }
  const tix = movable[0];
  return (
    <div className="suggestion suggestion--over">
      <span className="suggestion__mark suggestion__mark--bad"><Icon d={ICONS.alert} size={10} /></span>
      <span className="suggestion__txt">
        <strong>{bucket.overH}h over.</strong> Reassign <code>{tix.id}</code> ({tix.hours}h) to <strong>{target.name.split(' ')[0]}</strong> (free: {personBucket(target, tickets).slackH}h)?
      </span>
      <button className="suggestion__act" onClick={() => onAssign(tix, target.id)}>
        Reassign →
      </button>
    </div>
  );
}

window.Lanes = Lanes;
window.Suggestion = Suggestion;
