// Lightbox — full-screen photo viewer w/ zoom, before/after, EXIF, develop panel trigger

function Lightbox({ items, index, onClose, onNav, onPick, onReject, onRate, onColor, devOpen, setDevOpen, edits, onEditChange, onEditReset, showExif, setShowExif, baMode, setBaMode, zoom, setZoom, exifCache, readOnly }) {
  const f = items[index];
  const [screenW, setScreenW] = React.useState(window.innerWidth);
  React.useEffect(() => {
    const fn = () => setScreenW(window.innerWidth);
    window.addEventListener('resize', fn);
    return () => window.removeEventListener('resize', fn);
  }, []);
  const isMobile = screenW < 768;

  React.useEffect(() => {
    if (!f) return;
    const onKey = (e) => {
      if (e.key === 'Escape') { onClose(); return; }
      if (e.key === 'ArrowRight') onNav(1);
      if (e.key === 'ArrowLeft') onNav(-1);
      if (!readOnly) {
        if (e.key === 'p' || e.key === 'P') onPick();
        if (e.key === 'x' || e.key === 'X') onReject();
        if (e.key >= '1' && e.key <= '5') onRate(parseInt(e.key));
        if (e.key === '0') onRate(0);
        if (e.key === 'e' || e.key === 'E') setDevOpen(!devOpen);
      }
      if (e.key === 'i' || e.key === 'I') setShowExif(!showExif);
      if (e.key === 'z' || e.key === 'Z') setZoom(!zoom);
      if (e.key === '\\') setBaMode(!baMode);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [f, index, onNav, showExif, zoom, devOpen, baMode, readOnly]);

  if (!f) return null;

  const hasEdits = edits && Object.values(edits).some(v => v !== 0);
  const exif = exifCache && exifCache[f.filename];

  // Bottom bar height: filmstrip (48px) + mobile actions (52px on mobile)
  const bottomPad = isMobile ? (readOnly ? 56 : 108) : 80;

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 100,
      background: 'rgba(5,5,7,0.96)', backdropFilter: 'blur(16px)',
      animation: 'fade-in 160ms',
      display: 'flex', flexDirection: 'column',
    }} onClick={onClose}>

      {/* ── Top bar ── */}
      <div style={{
        position: 'absolute', top: 0, left: 0, right: 0, zIndex: 5,
        padding: isMobile ? '12px 14px' : '14px 20px',
        display: 'flex', alignItems: 'center', gap: isMobile ? 8 : 10,
        background: 'linear-gradient(to bottom, rgba(5,5,7,0.85), transparent)',
      }} onClick={e => e.stopPropagation()}>

        {/* Counter */}
        <span className="mono" style={{ fontSize: 11, color: 'var(--ink-2)', letterSpacing: 0.1, flexShrink: 0 }}>
          <span style={{ color: 'var(--ink-0)' }}>{index+1}</span>
          <span style={{ margin: '0 5px', color: 'var(--ink-3)' }}>/</span>
          {items.length}
        </span>

        {/* Filename + pills */}
        <span className="mono" style={{ fontSize: 11, color: 'var(--ink-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1, minWidth: 0 }}>{f.filename}</span>
        <Pill color={f.file_type === 'RAW' ? 'raw' : 'jpg'}>{f.file_type}</Pill>
        {f.color && <span style={{ width: 8, height: 8, borderRadius: 2, background: colorHex(f.color), flexShrink: 0 }}/>}
        {hasEdits && <Pill color="accent">Edited</Pill>}

        {/* Desktop-only controls */}
        {!isMobile && <>
          <div style={{ flex: 1 }}/>
          {!readOnly && <>
            <Stars rating={f.rating} onRate={onRate} size={14} />
            <Divider vertical style={{ margin: '0 4px' }}/>
            <ColorPicker color={f.color} onColor={onColor}/>
            <Divider vertical style={{ margin: '0 4px' }}/>
            <Btn size="sm" onClick={onPick} active={f.pick}
              style={f.pick ? { background: 'var(--accent)', color: '#1a1200', borderColor: 'var(--accent)' } : {}}>
              <IconCheck size={12}/> Pick
            </Btn>
            <Btn size="sm" onClick={onReject} active={f.reject}
              style={f.reject ? { background: 'var(--reject-soft)', color: 'var(--reject)', border: '1px solid var(--reject)' } : {}}>
              <IconX size={12}/> Reject
            </Btn>
            <Divider vertical style={{ margin: '0 4px' }}/>
          </>}
          <Btn size="sm" active={showExif} onClick={() => setShowExif(!showExif)} icon={<IconInfo size={13}/>} title="EXIF (I)"/>
          <Btn size="sm" active={zoom} onClick={() => setZoom(!zoom)} title="Zoom (Z)">
            <span className="mono" style={{ fontSize: 10 }}>{zoom ? '100%' : 'FIT'}</span>
          </Btn>
          <Btn size="sm" active={baMode} onClick={() => setBaMode(!baMode)} icon={<IconBA size={13}/>} title="Before/After (\)"/>
          {!readOnly && (
            <Btn size="sm" active={devOpen} onClick={() => setDevOpen(!devOpen)} icon={<IconSliders size={13}/>} title="Develop (E)">Develop</Btn>
          )}
          <Divider vertical style={{ margin: '0 4px' }}/>
          <Btn size="sm" icon={<IconDownload size={13}/>} title="Download"
            onClick={() => window.open(f.download_url || `/download/${encodeURIComponent(f.filename)}`, '_blank')}/>
        </>}

        <Btn size="sm" onClick={onClose} icon={<IconX size={13}/>}/>
      </div>

      {/* ── Image area ── */}
      <div style={{
        flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
        position: 'relative', padding: `${isMobile ? 56 : 60}px 20px ${bottomPad}px`,
      }} onClick={e => e.stopPropagation()}>
        {baMode ? (
          <BeforeAfterView file={f} edits={edits}/>
        ) : (
          <img src={f.thumb_url} alt={f.filename}
            style={{
              maxWidth: zoom ? 'none' : `calc(100vw - ${isMobile ? 16 : 40}px)`,
              maxHeight: zoom ? 'none' : (devOpen ? 'calc(100vh - 200px)' : `calc(100vh - ${bottomPad + 60}px)`),
              width: zoom ? 'auto' : undefined, height: zoom ? 'auto' : undefined,
              objectFit: 'contain',
              cursor: zoom ? 'zoom-out' : 'zoom-in',
              filter: developFilter(edits),
              transition: 'filter 140ms',
              boxShadow: '0 24px 80px rgba(0,0,0,0.8), 0 0 0 1px rgba(255,255,255,0.03)',
            }}
            onClick={() => setZoom(!zoom)}
          />
        )}
        <button onClick={() => onNav(-1)} style={navArrowStyle('left', isMobile)}><IconChevL size={18}/></button>
        <button onClick={() => onNav(1)} style={navArrowStyle('right', isMobile)}><IconChevR size={18}/></button>
      </div>

      {/* ── EXIF overlay ── */}
      {showExif && (
        <div onClick={e => e.stopPropagation()} style={{
          position: 'absolute', bottom: bottomPad + 8, left: '50%', transform: 'translateX(-50%)',
          background: 'rgba(10,10,12,0.88)', backdropFilter: 'blur(14px)',
          border: '1px solid var(--line-2)', borderRadius: 8,
          padding: '10px 20px', display: 'flex', gap: isMobile ? 16 : 28,
          animation: 'fade-up 180ms ease', maxWidth: 'calc(100vw - 40px)', flexWrap: 'wrap',
        }}>
          {exif ? <>
            {exif.camera && <ExifItem label="Camera" val={exif.camera}/>}
            {exif.shutter && <ExifItem label="Shutter" val={exif.shutter} mono/>}
            {exif.aperture && <ExifItem label="Aperture" val={`f/${exif.aperture}`} mono/>}
            {exif.iso && <ExifItem label="ISO" val={exif.iso} mono/>}
            {exif.focal_length && <ExifItem label="Focal" val={exif.focal_length} mono/>}
            {exif.width && exif.height && <ExifItem label="Size" val={`${exif.width}×${exif.height}`} mono/>}
            {exif.datetime && <ExifItem label="Date" val={exif.datetime}/>}
          </> : (
            <span className="mono" style={{ fontSize: 10.5, color: 'var(--ink-3)' }}>Loading EXIF…</span>
          )}
        </div>
      )}

      {/* ── Mobile action bar (above filmstrip) ── */}
      {isMobile && !readOnly && (
        <div onClick={e => e.stopPropagation()} style={{
          position: 'absolute', bottom: 52, left: 0, right: 0, zIndex: 5,
          padding: '8px 14px',
          background: 'rgba(5,5,7,0.85)',
          display: 'flex', alignItems: 'center', gap: 8,
        }}>
          {/* Pick / Reject */}
          <Btn size="sm" onClick={onPick} active={f.pick}
            style={{ flex: 1, justifyContent: 'center', ...(f.pick ? { background: 'var(--accent)', color: '#1a1200', borderColor: 'var(--accent)' } : {}) }}>
            <IconCheck size={12}/> Pick
          </Btn>
          <Btn size="sm" onClick={onReject} active={f.reject}
            style={{ flex: 1, justifyContent: 'center', ...(f.reject ? { background: 'var(--reject-soft)', color: 'var(--reject)', border: '1px solid var(--reject)' } : {}) }}>
            <IconX size={12}/> Reject
          </Btn>
          <Divider vertical style={{ margin: '0 2px' }}/>
          {/* Stars */}
          <Stars rating={f.rating} onRate={onRate} size={16}/>
          <Divider vertical style={{ margin: '0 2px' }}/>
          {/* Download */}
          <Btn size="sm" icon={<IconDownload size={13}/>} title="Download"
            onClick={() => window.open(f.download_url || `/download/${encodeURIComponent(f.filename)}`, '_blank')}/>
          {/* EXIF toggle */}
          <Btn size="sm" active={showExif} onClick={() => setShowExif(!showExif)} icon={<IconInfo size={13}/>}/>
        </div>
      )}

      {/* ── Filmstrip ── */}
      <div onClick={e => e.stopPropagation()} style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, zIndex: 5,
        height: 52, padding: '8px 16px 10px', overflowX: 'auto',
        background: 'linear-gradient(to top, rgba(5,5,7,0.9), transparent)',
        display: 'flex', gap: 4, alignItems: 'flex-end',
      }}>
        {items.map((it, i) => (
          <button key={it.filename} onClick={() => onNav(i - index)}
            style={{
              background: 'none', border: 'none', padding: 0, cursor: 'pointer',
              width: 46, height: 32, flexShrink: 0, position: 'relative',
              borderRadius: 2, overflow: 'hidden',
              outline: i === index ? '2px solid var(--accent)' : '1px solid var(--line-1)',
              outlineOffset: i === index ? 1 : 0,
              opacity: i === index ? 1 : 0.5,
              transition: 'opacity 120ms, outline 120ms',
            }}
            onMouseEnter={e => e.currentTarget.style.opacity = 1}
            onMouseLeave={e => e.currentTarget.style.opacity = i === index ? 1 : 0.5}>
            <img src={it.thumb_url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }}/>
            {it.pick && <div style={{ position: 'absolute', top: 2, left: 2, width: 5, height: 5, borderRadius: '50%', background: 'var(--accent)' }}/>}
            {it.reject && <div style={{ position: 'absolute', top: 2, left: 2, width: 5, height: 5, borderRadius: '50%', background: 'var(--reject)' }}/>}
          </button>
        ))}
      </div>
    </div>
  );
}

function navArrowStyle(side, isMobile) {
  return {
    position: 'absolute', [side]: isMobile ? 8 : 16, top: '50%', transform: 'translateY(-50%)',
    width: isMobile ? 34 : 38, height: isMobile ? 34 : 38, borderRadius: '50%',
    background: 'rgba(10,10,12,0.7)', color: 'var(--ink-1)',
    border: '1px solid var(--line-2)', cursor: 'pointer',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    backdropFilter: 'blur(8px)', zIndex: 4,
  };
}

function ExifItem({ label, val, mono }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
      <span className="mono" style={{ fontSize: 8.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: 0.14 }}>{label}</span>
      <span className={mono ? 'mono' : ''} style={{ fontSize: 11.5, color: 'var(--ink-0)' }}>{val}</span>
    </div>
  );
}

function ColorPicker({ color, onColor }) {
  const colors = [null, 'red', 'yellow', 'green', 'blue', 'purple'];
  return (
    <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
      {colors.map(c => (
        <ColorDot key={c||'none'} color={c} size={14} active={color === c} onClick={() => onColor(c)}/>
      ))}
    </div>
  );
}

function BeforeAfterView({ file, edits }) {
  const [pos, setPos] = React.useState(50);
  const ref = React.useRef(null);
  const dragging = React.useRef(false);
  const imgStyle = { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'contain' };

  const calcPos = (clientX) => {
    if (!ref.current) return;
    const r = ref.current.getBoundingClientRect();
    setPos(Math.max(0, Math.min(100, ((clientX - r.left) / r.width) * 100)));
  };

  React.useEffect(() => {
    const onMouseMove = (e) => { if (dragging.current) calcPos(e.clientX); };
    const onMouseUp = () => { dragging.current = false; };
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);
    return () => {
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup', onMouseUp);
    };
  }, []);

  return (
    <div ref={ref} style={{
      position: 'relative', width: '90vw', maxWidth: 1100,
      aspectRatio: `${file.w || 4} / ${file.h || 3}`, maxHeight: 'calc(100vh - 180px)',
      userSelect: 'none', cursor: 'col-resize', touchAction: 'none',
    }}
      onMouseDown={(e) => { e.preventDefault(); dragging.current = true; calcPos(e.clientX); }}
      onTouchStart={(e) => { e.preventDefault(); calcPos(e.touches[0].clientX); }}
      onTouchMove={(e) => { e.preventDefault(); calcPos(e.touches[0].clientX); }}
    >
      {/* AFTER — with edits applied, full underneath */}
      <img src={file.thumb_url} style={{ ...imgStyle, filter: developFilter(edits) }} draggable={false}/>

      {/* BEFORE — original, clipped to left of divider */}
      <div style={{ position: 'absolute', inset: 0, clipPath: `inset(0 ${100 - pos}% 0 0)` }}>
        <img src={file.thumb_url} style={{ ...imgStyle, filter: 'none' }} draggable={false}/>
      </div>

      {/* Labels */}
      <span style={{ position: 'absolute', top: 14, left: 14, padding: '3px 8px', fontSize: 9, fontWeight: 700, letterSpacing: 0.15, background: 'rgba(10,10,12,0.8)', color: 'var(--ink-0)', borderRadius: 3, fontFamily: 'var(--mono)' }}>BEFORE</span>
      <span style={{ position: 'absolute', top: 14, right: 14, padding: '3px 8px', fontSize: 9, fontWeight: 700, letterSpacing: 0.15, background: 'rgba(10,10,12,0.8)', color: 'var(--accent)', borderRadius: 3, fontFamily: 'var(--mono)' }}>AFTER</span>

      {/* Divider */}
      <div style={{ position: 'absolute', top: 0, bottom: 0, left: `${pos}%`, width: 2, background: 'var(--accent)', transform: 'translateX(-1px)', boxShadow: '0 0 12px rgba(244,185,66,0.5)', pointerEvents: 'none' }}>
        <div style={{
          position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)',
          width: 32, height: 32, borderRadius: '50%',
          background: 'var(--accent)', color: '#1a1200',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 13, fontWeight: 700, boxShadow: '0 2px 8px rgba(0,0,0,0.5)',
        }}>◁▷</div>
      </div>
    </div>
  );
}

function developFilter(edits) {
  if (!edits) return 'none';
  const { exposure=0, contrast=0, highlights=0, shadows=0, temperature=0, tint=0, vibrance=0, saturation=0, sharpness=0 } = edits;
  const brightness = 1 + exposure * 0.14;
  const c = 1 + contrast * 0.005;
  const sat = 1 + saturation * 0.006 + vibrance * 0.004;
  const hue = temperature * 0.15;
  return `brightness(${brightness}) contrast(${c}) saturate(${sat}) hue-rotate(${hue}deg)`;
}

Object.assign(window, { Lightbox, developFilter });
