// Map screen — 390×844 iPhone artboard. Light only. Three map style toggle.

const { useState: useStateMS } = React;
const TM = window.DAIL_TOKENS;
const cm = TM.colors, fsm = TM.fontSizes, fwm = TM.fontWeights, spm = TM.spacing, rm = TM.radius;

const baseTextM = { fontFamily: TM.fonts.primary, color: cm.textPrimary, lineHeight: 1.4 };

// Reaction icon — drawn as a tiny SVG so we don't ship emoji as the brand mark.
function RxIcon({ kind, size = 14, color = cm.textSecondary }) {
  if (kind === 'fire') return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none">
      <path d="M8 1.5 C 9 4 11.5 4.5 11.5 8 C 11.5 11 10 13.5 8 13.5 C 6 13.5 4.5 11 4.5 8 C 4.5 6 5.5 5 6.5 5.5 C 6 4 7 2.5 8 1.5 Z" stroke={color} strokeWidth="1.3" strokeLinejoin="round"/>
    </svg>
  );
  if (kind === 'love') return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none">
      <path d="M8 13 C 8 13 2.5 10 2.5 6 C 2.5 4 4 3 5.3 3 C 6.4 3 7.4 3.7 8 4.6 C 8.6 3.7 9.6 3 10.7 3 C 12 3 13.5 4 13.5 6 C 13.5 10 8 13 8 13 Z" fill="#A8A8A8" stroke="#A8A8A8" strokeWidth="1" strokeLinejoin="round"/>
    </svg>
  );
  if (kind === 'tasty') return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none">
      <circle cx="8" cy="8" r="5.5" stroke={color} strokeWidth="1.3"/>
      <circle cx="6.3" cy="7" r="0.7" fill={color}/>
      <circle cx="9.7" cy="7" r="0.7" fill={color}/>
      <path d="M5.5 9.8 C 6.3 10.8 7.1 11 8 11 C 8.9 11 9.7 10.8 10.5 9.8" stroke={color} strokeWidth="1.3" strokeLinecap="round" fill="none"/>
    </svg>
  );
  return null;
}

// 24x24 pin from the source — clip thumbnail in a circle, white border, tail.
function Pin({ active, photo }) {
  const ringColor = active ? '#1A1A1A' : '#FFFFFF';
  const size = active ? 36 : 28;
  return (
    <div style={{ position:'relative', display:'flex', flexDirection:'column', alignItems:'center', filter:'drop-shadow(0 2px 5px rgba(0,0,0,0.22))' }}>
      <div style={{
        width: size, height: size, borderRadius: '50%',
        background: '#FFF',
        border: `2px solid ${ringColor}`,
        padding: 2, boxSizing: 'border-box',
        transition: 'all 180ms ease',
      }}>
        <div style={{
          width:'100%', height:'100%', borderRadius:'50%',
          backgroundImage: `url(${photo})`,
          backgroundSize: 'cover', backgroundPosition: 'center',
        }}/>
      </div>
      <div style={{
        width: 0, height: 0,
        borderLeft:'5px solid transparent', borderRight:'5px solid transparent',
        borderTop: `7px solid ${ringColor}`,
        marginTop: -1,
      }}/>
    </div>
  );
}

// Cluster pin — multiple pins peek out from under the top one, slight rotations.
function ClusterPin({ clips, active, onTap }) {
  const [top, ...rest] = clips;
  return (
    <div style={{ position:'relative', display:'flex', flexDirection:'column', alignItems:'center', cursor:'pointer' }} onClick={onTap}>
      {/* peek layers — rendered behind the top pin, slight rotation + offset */}
      {rest.slice(0, 3).map((c, i) => {
        const rot = [-7, 6, -10][i] || 0;
        const dx = [-7, 6, -3][i] || 0;
        const dy = [-2, 2, 5][i] || 0;
        return (
          <div key={c.id} style={{
            position:'absolute', left: '50%', top: '0',
            transform: `translate(calc(-50% + ${dx}px), ${dy}px) rotate(${rot}deg)`,
            zIndex: 1 + i,
            filter:'drop-shadow(0 2px 4px rgba(0,0,0,0.18))',
          }}>
            <div style={{
              width: 26, height: 26, borderRadius:'50%',
              background:'#FFF', border:'2px solid #FFF',
              padding: 2, boxSizing:'border-box',
            }}>
              <div style={{
                width:'100%', height:'100%', borderRadius:'50%',
                backgroundImage: `url(${c.photo})`,
                backgroundSize:'cover', backgroundPosition:'center',
              }}/>
            </div>
          </div>
        );
      })}
      {/* top pin — always upright, fully visible */}
      <div style={{ position:'relative', zIndex: 5 }}>
        <Pin active={active} photo={top.photo} />
      </div>
      {/* count badge */}
      {clips.length >= 3 ? (
        <div style={{
          position:'absolute', top: -4, right: -8, zIndex: 6,
          background: '#1A1A1A', color:'#FFF',
          minWidth: 18, height: 18, borderRadius: 9,
          padding:'0 5px', display:'flex', alignItems:'center', justifyContent:'center',
          fontSize: 10, fontWeight: 700,
          border:'1.5px solid #FFF',
          boxShadow:'0 1px 3px rgba(0,0,0,0.2)',
          fontFamily: TM.fonts.primary, fontVariantNumeric:'tabular-nums',
        }}>{clips.length}</div>
      ) : null}
    </div>
  );
}

function MapStyleToggle({ value, onChange }) {
  const opts = [
    { k:'naver',  label:'Naver' },
    { k:'apple',  label:'Apple' },
    { k:'google', label:'Google' },
  ];
  return (
    <div style={{
      position:'absolute', top: 116, left:'50%', transform:'translateX(-50%)',
      background: cm.card, border:`1px solid ${cm.border}`, borderRadius: 999,
      padding: 3, display:'flex', gap: 2,
      boxShadow:'0 2px 6px rgba(0,0,0,0.06)',
      zIndex: 5,
    }}>
      {opts.map(o => {
        const active = value === o.k;
        return (
          <button key={o.k} onClick={() => onChange(o.k)} style={{
            ...baseTextM,
            fontSize: fsm.caption, fontWeight: active ? fwm.semibold : fwm.medium,
            color: active ? '#FFF' : cm.textSecondary,
            background: active ? cm.textPrimary : 'transparent',
            border:'none', borderRadius: 999, cursor:'pointer',
            padding:'5px 12px',
            transition:'all 160ms ease',
          }}>{o.label}</button>
        );
      })}
    </div>
  );
}

function SearchBar() {
  return (
    <div style={{
      height: 44, borderRadius: 22,
      background: cm.card, border:`1px solid ${cm.border}`,
      display:'flex', alignItems:'center', gap: 10,
      padding:'0 16px', flex: 1,
      boxShadow:'0 2px 6px rgba(0,0,0,0.06)',
    }}>
      <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
        <circle cx="7" cy="7" r="4.5" stroke={cm.textTertiary} strokeWidth="1.4"/>
        <path d="m10.5 10.5 3 3" stroke={cm.textTertiary} strokeWidth="1.4" strokeLinecap="round"/>
      </svg>
      <span style={{ ...baseTextM, fontSize: fsm.body, color: cm.textTertiary }}>여기서 검색</span>
    </div>
  );
}

function ProfileButton({ initials = '박' }) {
  return (
    <div style={{
      width: 44, height: 44, borderRadius: 22,
      background: cm.card, border:`1px solid ${cm.border}`,
      display:'flex', alignItems:'center', justifyContent:'center',
      boxShadow:'0 2px 6px rgba(0,0,0,0.06)',
    }}>
      <span style={{ ...baseTextM, fontSize: fsm.body, fontWeight: fwm.semibold }}>{initials}</span>
    </div>
  );
}

function FAB({ hidden = false }) {
  return (
    <div style={{
      position:'absolute', right: 18, bottom: 38,
      opacity: hidden ? 0 : 1,
      transform: hidden ? 'translateY(8px) scale(0.9)' : 'translateY(0) scale(1)',
      pointerEvents: hidden ? 'none' : 'auto',
      transition: 'opacity 200ms ease, transform 200ms ease',
      width: 56, height: 56, borderRadius: 28,
      background: cm.accent,
      display:'flex', alignItems:'center', justifyContent:'center',
      boxShadow:'0 4px 12px rgba(61,90,128,0.32)',
      zIndex: 4,
    }}>
      <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
        <path d="M11 4v14M4 11h14" stroke="#FFF" strokeWidth="2.4" strokeLinecap="round"/>
      </svg>
    </div>
  );
}

// Bottom sheet — pin-tap reveals this. 16:9 photo, title, meta, 3 reactions.
function BottomSheet({ clip, onClose }) {
  const author = window.DAIL_FRIENDS[clip.author];
  const group  = window.DAIL_GROUPS[clip.group];
  const rxKinds = [
    { k:'fire',  c: clip.reactions.fire },
    { k:'love',  c: clip.reactions.love },
    { k:'tasty', c: clip.reactions.tasty },
  ];

  return (
    <div style={{
      position:'absolute', left: 0, right: 0, bottom: 0,
      background: cm.card,
      borderTopLeftRadius: 18, borderTopRightRadius: 18,
      borderTop:`1px solid ${cm.border}`,
      paddingBottom: 28,
      boxShadow:'0 -8px 24px rgba(0,0,0,0.08)',
      zIndex: 3,
    }}>
      {/* grabber — tappable to close */}
      <button onClick={onClose} aria-label="Close" style={{
        display:'flex', justifyContent:'center', padding:'8px 0 4px',
        width:'100%', background:'transparent', border:'none', cursor:'pointer',
      }}>
        <div style={{ width: 36, height: 4, background: cm.border, borderRadius: 2 }} />
      </button>

      {/* place name + chevron */}
      <div style={{ padding: `${spm.sm}px ${spm.lg}px ${spm.sm}px`, display:'flex', alignItems:'baseline', justifyContent:'space-between' }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ ...baseTextM, fontSize: fsm.title, fontWeight: fwm.bold, letterSpacing:'-0.01em' }}>{clip.place}</div>
          <div style={{ ...baseTextM, fontSize: fsm.caption, color: cm.textTertiary, marginTop: 2 }}>{clip.area}</div>
        </div>
        <span style={{ color: cm.textTertiary, fontSize: 18, lineHeight: 1 }}>›</span>
      </div>

      {/* 16:9 video — caption baked into video (preview style) */}
      <div style={{ margin: `0 ${spm.lg}px`, borderRadius: rm.md, overflow:'hidden', background: cm.videoArea, aspectRatio:'16 / 9', position:'relative' }}>
        <img src={clip.photo} alt="" style={{ width:'100%', height:'100%', objectFit:'cover', display:'block' }}/>
        {/* Caption — baked into video, center-bottom */}
        <div style={{ position:'absolute', left:0, right:0, top:'62%', textAlign:'center', padding:'0 20px' }}>
          <span style={{ ...baseTextM, color:'#FFF', fontSize:18, fontWeight:fwm.bold, textShadow:'0 2px 8px rgba(0,0,0,0.65)', letterSpacing:'-0.01em' }}>{clip.title}</span>
        </div>
        {/* mute badge — sits in corner, the spec says 음소거 기본 */}
        <div style={{ position:'absolute', top: 8, right: 8, background:'rgba(0,0,0,0.55)', borderRadius: 999, padding:'4px 8px', display:'flex', alignItems:'center', gap: 4 }}>
          <svg width="11" height="11" viewBox="0 0 12 12" fill="none">
            <path d="M2 4.5h2L6.5 2v8L4 7.5H2z" fill="#FFF"/>
            <path d="m9 4 2.5 4M11.5 4 9 8" stroke="#FFF" strokeWidth="1.2" strokeLinecap="round"/>
          </svg>
          <span style={{ ...baseTextM, color:'#FFF', fontSize: 10, fontWeight: fwm.medium }}>음소거</span>
        </div>
        {/* duration badge */}
        <div style={{ position:'absolute', bottom: 8, right: 8, background:'rgba(0,0,0,0.55)', borderRadius: 4, padding:'2px 6px' }}>
          <span style={{ ...baseTextM, color:'#FFF', fontSize: 10, fontWeight: fwm.medium, fontVariantNumeric:'tabular-nums' }}>0:05</span>
        </div>
      </div>

      {/* meta row: avatar · name · group tag · time */}
      <div style={{ padding: `0 ${spm.lg}px`, display:'flex', alignItems:'center', gap: spm.sm }}>
        <div style={{ width: 22, height: 22, borderRadius: 11, background: cm.bg, border:`1px solid ${cm.border}`, display:'flex', alignItems:'center', justifyContent:'center' }}>
          <span style={{ ...baseTextM, fontSize: 10, fontWeight: fwm.semibold }}>{author.initials}</span>
        </div>
        <span style={{ ...baseTextM, fontSize: fsm.caption, fontWeight: fwm.medium }}>{author.name}</span>
        <span style={{ width: 2, height: 2, borderRadius: 1, background: cm.textTertiary }} />
        <span style={{ ...baseTextM, fontSize: fsm.caption, color: cm.textSecondary, padding: '3px 8px', borderRadius: 999, background: cm.bg, border:`1px solid ${cm.border}` }}>👥 {group.name}</span>
        <span style={{ marginLeft:'auto', ...baseTextM, fontSize: fsm.caption, color: cm.textTertiary }}>{clip.when}</span>
      </div>

      {/* reactions row */}
      <div style={{ padding: `${spm.md}px ${spm.lg}px 0`, display:'flex', gap: 6 }}>
        {rxKinds.map(rx => (
          <button key={rx.k} style={{
            background: cm.bg, border:`1px solid ${cm.border}`, borderRadius: 999,
            padding:'6px 11px', display:'inline-flex', alignItems:'center', gap: 6,
            cursor:'pointer',
          }}>
            <RxIcon kind={rx.k} size={13} color={cm.textSecondary} />
            <span style={{ ...baseTextM, fontSize: fsm.caption, fontWeight: fwm.medium, color: cm.textSecondary, fontVariantNumeric:'tabular-nums' }}>{rx.c}</span>
          </button>
        ))}
      </div>
    </div>
  );
}

window.DAIL_MapScreen = function MapScreen({ initialStyle = 'naver', zoomed = false } = {}) {
  const [mapStyle, setMapStyle] = useStateMS(initialStyle);
  const [activeId, setActiveId] = useStateMS(window.DAIL_ACTIVE);
  const MapBg = window.DAIL_MAPS[mapStyle];
  const clip = activeId ? window.DAIL_CLIPS.find(c => c.id === activeId) : null;

  // Group clips by clusterId. Clips with no clusterId stand alone.
  const clusters = {};
  const standalone = [];
  window.DAIL_CLIPS.forEach(c => {
    if (c.clusterId) {
      (clusters[c.clusterId] ||= []).push(c);
    } else {
      standalone.push(c);
    }
  });

  // Zoomed = cluster spreads out (each clip gets its own offset position).
  const spreadOffsets = [{dx:0,dy:0},{dx:-14,dy:8},{dx:13,dy:10}];

  return (
    <div style={{ position:'relative', width:'100%', height:'100%', overflow:'hidden', background: cm.bg }}>
      <MapBg />

      <button
        onClick={() => setActiveId(null)}
        aria-label="Deselect"
        style={{
          position:'absolute', inset: 0, background:'transparent',
          border:'none', padding: 0, cursor: clip ? 'pointer' : 'default',
          zIndex: 1,
        }}
      />

      <div style={{
        position:'absolute', top: 60, left: 0, right: 0,
        padding:'0 18px', display:'flex', gap: 12, alignItems:'center', zIndex: 5,
      }}>
        <SearchBar />
        <ProfileButton />
      </div>

      <MapStyleToggle value={mapStyle} onChange={setMapStyle} />

      {/* standalone pins */}
      {standalone.map(c => (
        <button key={c.id} onClick={(e) => { e.stopPropagation(); setActiveId(c.id === activeId ? null : c.id); }}
          style={{
            position:'absolute', left: `${c.x}%`, top: `${c.y}%`,
            transform:'translate(-50%, -100%)',
            background:'transparent', border:'none', padding: 0, cursor:'pointer',
            zIndex: c.id === activeId ? 3 : 2,
          }}
        >
          <Pin active={c.id === activeId} photo={c.photo} />
        </button>
      ))}

      {/* clusters */}
      {Object.entries(clusters).map(([cid, clips]) => {
        if (zoomed) {
          // spread out — each clip gets its own pin nearby
          return clips.map((c, i) => {
            const o = spreadOffsets[i] || {dx:0,dy:0};
            return (
              <button key={c.id} onClick={(e) => { e.stopPropagation(); setActiveId(c.id === activeId ? null : c.id); }}
                style={{
                  position:'absolute',
                  left: `calc(${c.x}% + ${o.dx * 2.4}px)`,
                  top: `calc(${c.y}% + ${o.dy * 2.4}px)`,
                  transform:'translate(-50%, -100%)',
                  background:'transparent', border:'none', padding: 0, cursor:'pointer',
                  zIndex: c.id === activeId ? 3 : 2,
                }}
              >
                <Pin active={c.id === activeId} photo={c.photo} />
              </button>
            );
          });
        }
        const top = clips[0];
        const isActive = clips.some(c => c.id === activeId);
        return (
          <div key={cid} style={{
            position:'absolute', left:`${top.x}%`, top:`${top.y}%`,
            transform:'translate(-50%, -100%)',
            zIndex: isActive ? 3 : 2,
          }}>
            <ClusterPin
              clips={clips}
              active={isActive}
              onTap={(e) => { e?.stopPropagation?.(); setActiveId(top.id === activeId ? null : top.id); }}
            />
          </div>
        );
      })}

      <div style={{ position:'absolute', left: 8, bottom: 4, zIndex: 1 }}>
        <span style={{ ...baseTextM, fontSize: 9.5, color: cm.textTertiary, opacity: 0.8 }}>
          © Stadia · © OpenStreetMap · © Mapbox
        </span>
      </div>

      <FAB hidden={Boolean(clip)} />

      {clip ? <BottomSheet clip={clip} onClose={() => setActiveId(null)} /> : null}
    </div>
  );
};
