/* global React, fmt, I, MiniMap */
// Three card concepts for House Hunt Diary.
//
// All cards share:
//   - hero image area (placeholder)
//   - source badge
//   - location signal
//   - title / price / facts
//   - private/public dot
//   - graceful degradation when data is missing
//
// They differ in HOW location is treated and how much editorial weight vs
// utility weight they carry.

// ─────────────────────────────────────────────────────────────
// Shared bits
// ─────────────────────────────────────────────────────────────
function HeroImg({ p, h, label }) {
  return (
    <div
      className="hhd-img-ph"
      style={{
        width: '100%', height: h,
        '--ph-bg': p.color,
        '--ph-label': label === undefined ? `"${p.label}"` : `"${label}"`,
      }}
    >
      {/* a faint lighter band — feels like a real photo without drawing one */}
      <div style={{
        position: 'absolute', inset: 0,
        background: `linear-gradient(160deg, rgba(255,255,255,.12) 0%, rgba(0,0,0,0) 35%, rgba(0,0,0,.10) 100%)`,
      }} />
    </div>
  );
}

function SourceBadge({ source, dark = false, position = 'topleft' }) {
  const isPrivate = source === 'private';
  const text = isPrivate ? 'Added by you' : `via ${source}`;
  const pos = {
    topleft:    { top: 10, left: 10 },
    topright:   { top: 10, right: 10 },
    bottomleft: { bottom: 10, left: 10 },
  }[position];
  return (
    <div style={{
      position: 'absolute', ...pos,
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '4px 8px', borderRadius: 999,
      background: dark ? 'rgba(31,27,22,.72)' : 'rgba(247,243,236,.92)',
      backdropFilter: 'blur(6px)',
      color: dark ? '#f3ece0' : 'var(--ink-2)',
      fontSize: 11, fontWeight: 500, letterSpacing: 0.1,
      boxShadow: '0 1px 3px rgba(0,0,0,.10)',
    }}>
      {!isPrivate && <span style={{ width: 5, height: 5, borderRadius: 999, background: dark ? '#f3ece0' : 'var(--accent)' }} />}
      {text}
    </div>
  );
}

function VisibilityDot({ visibility, mode = 'soft' }) {
  // mode: soft | strong
  const isPublic = visibility === 'public';
  if (mode === 'soft') {
    return (
      <span title={isPublic ? 'Public' : 'Private'} style={{
        display: 'inline-flex', alignItems: 'center', gap: 4,
        color: 'var(--ink-3)', fontSize: 11,
      }}>
        <span style={{
          width: 6, height: 6, borderRadius: 999,
          background: isPublic ? 'var(--accent)' : 'transparent',
          border: isPublic ? 'none' : '1.5px solid var(--ink-3)',
        }} />
        {isPublic ? 'Public' : 'Private'}
      </span>
    );
  }
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '2px 6px', borderRadius: 4,
      background: isPublic ? 'var(--accent-soft)' : 'var(--paper-3)',
      color: isPublic ? 'var(--accent-ink)' : 'var(--ink-2)',
      fontSize: 11, fontWeight: 500,
    }}>
      {isPublic ? I.globe(11) : I.lock(11)}
      {isPublic ? 'Public' : 'Private'}
    </span>
  );
}

function StatusPip({ status }) {
  if (!status) return null;
  const map = {
    shortlisted: { color: 'var(--shortlist)', label: 'Shortlisted', icon: I.bookmark(10, true) },
    visited:     { color: 'var(--visited)',   label: 'Visited',     icon: I.eye(10) },
    favorite:    { color: 'var(--accent)',    label: 'Favorite',    icon: I.heart(10, true) },
  };
  const s = map[status]; if (!s) return null;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      color: s.color, fontSize: 11, fontWeight: 500,
    }}>
      {s.icon}{s.label}
    </span>
  );
}

// ─────────────────────────────────────────────────────────────
// Concept A — Editorial / Pinterest-like
// Image-forward. Location is a quiet neighborhood subtitle, set in serif.
// Facts collapse into a single line of meta that gracefully shrinks.
// ─────────────────────────────────────────────────────────────
function CardEditorial({ p, w = 280 }) {
  const h = Math.round(w * (p.aspect || 1));
  const facts = fmt.facts(p);
  return (
    <article className="hhd-lift" style={{
      width: w, background: 'transparent', borderRadius: 0,
    }}>
      <div style={{ position: 'relative', borderRadius: 'var(--r-md)', overflow: 'hidden', boxShadow: 'var(--shadow-1)' }}>
        <HeroImg p={p} h={h} />
        <SourceBadge source={p.source} position="topleft" />
        {p.status && (
          <div style={{ position: 'absolute', top: 10, right: 10 }}>
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 4,
              padding: '4px 8px', borderRadius: 999,
              background: 'rgba(247,243,236,.92)', backdropFilter: 'blur(6px)',
              color: p.status === 'shortlisted' ? 'var(--shortlist)' : (p.status === 'visited' ? 'var(--visited)' : 'var(--accent)'),
              fontSize: 11, fontWeight: 500, boxShadow: '0 1px 3px rgba(0,0,0,.10)',
            }}>
              {p.status === 'shortlisted' && I.bookmark(11, true)}
              {p.status === 'visited' && I.eye(11)}
              {p.status === 'favorite' && I.heart(11, true)}
              {p.status[0].toUpperCase() + p.status.slice(1)}
            </span>
          </div>
        )}
      </div>
      <div style={{ padding: '12px 4px 0' }}>
        <div style={{
          fontFamily: 'var(--serif)', fontSize: 17, fontWeight: 500, lineHeight: 1.25,
          letterSpacing: -0.2, color: 'var(--ink)',
          textWrap: 'pretty',
          display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
        }}>{p.title}</div>
        <div style={{
          marginTop: 4, fontFamily: 'var(--serif)', fontSize: 13, fontStyle: 'italic',
          color: 'var(--ink-3)',
        }}>{p.neighborhood} <span style={{ opacity: .5 }}>·</span> {p.city.split(',')[0]}</div>
        <div style={{
          marginTop: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          fontSize: 12, color: 'var(--ink-2)',
        }}>
          <span style={{ fontWeight: 600, color: 'var(--ink)' }}>{fmt.price(p.price)}</span>
          <span style={{ display: 'flex', gap: 8, color: 'var(--ink-3)' }}>
            {facts.length ? facts.join(' · ') : <em style={{ opacity: .7 }}>details pending</em>}
          </span>
        </div>
        {p.note && (
          <div style={{
            marginTop: 10, padding: '8px 10px',
            background: 'var(--paper-2)', borderRadius: 'var(--r-sm)',
            fontFamily: 'var(--serif)', fontSize: 13, fontStyle: 'italic', lineHeight: 1.4,
            color: 'var(--ink-2)',
            display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
          }}>"{p.note}"</div>
        )}
        <div style={{ marginTop: 10, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>Saved {p.saved}</span>
          <VisibilityDot visibility={p.visibility} />
        </div>
      </div>
    </article>
  );
}

// ─────────────────────────────────────────────────────────────
// Concept B — Utility / Location-forward
// Mini-map sliver runs across the BOTTOM of the image area. Neighborhood
// chip overlays the corner. Tighter, more structured. Card is constant
// aspect ratio so the grid stays uniform — better for scanning many.
// ─────────────────────────────────────────────────────────────
function CardUtility({ p, w = 280 }) {
  const facts = fmt.facts(p);
  return (
    <article className="hhd-lift" style={{
      width: w, background: '#fff', borderRadius: 'var(--r-md)',
      border: '1px solid var(--line-2)', boxShadow: 'var(--shadow-1)', overflow: 'hidden',
    }}>
      <div style={{ position: 'relative' }}>
        <HeroImg p={p} h={180} />
        <SourceBadge source={p.source} position="topleft" />
        {/* neighborhood chip — over image, near bottom */}
        <div style={{
          position: 'absolute', left: 10, bottom: 10,
          display: 'inline-flex', alignItems: 'center', gap: 4,
          padding: '4px 9px 4px 7px', borderRadius: 999,
          background: 'rgba(31,27,22,.78)', backdropFilter: 'blur(8px)',
          color: '#f3ece0', fontSize: 11, fontWeight: 500,
        }}>
          {I.pin(11)} {p.neighborhood}
        </div>
        {p.status && (
          <div style={{ position: 'absolute', top: 10, right: 10 }}>
            <span style={{
              display: 'inline-flex', alignItems: 'center',
              width: 22, height: 22, borderRadius: 999, justifyContent: 'center',
              background: 'rgba(247,243,236,.92)', backdropFilter: 'blur(6px)',
              color: p.status === 'shortlisted' ? 'var(--shortlist)' : (p.status === 'visited' ? 'var(--visited)' : 'var(--accent)'),
              boxShadow: '0 1px 3px rgba(0,0,0,.10)',
            }}>
              {p.status === 'shortlisted' && I.bookmark(13, true)}
              {p.status === 'visited' && I.eye(13)}
              {p.status === 'favorite' && I.heart(13, true)}
            </span>
          </div>
        )}
      </div>
      {/* the location strip — mini-map ribbon */}
      <div style={{ position: 'relative', height: 40, borderBottom: '1px solid var(--line-2)', borderTop: '1px solid var(--line-2)' }}>
        <MiniMap width={w} height={40} neighborhood={p.neighborhood} accent={p.accent} />
        {p.commute && (
          <div style={{
            position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)',
            padding: '2px 6px', borderRadius: 4,
            background: 'rgba(247,243,236,.92)', backdropFilter: 'blur(4px)',
            color: 'var(--ink-2)', fontSize: 10, fontFamily: 'var(--mono)',
          }}>{p.commute}</div>
        )}
      </div>
      <div style={{ padding: '12px 14px 14px' }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 8 }}>
          <div style={{
            fontSize: 14, fontWeight: 600, color: 'var(--ink)', lineHeight: 1.3,
            display: '-webkit-box', WebkitLineClamp: 1, WebkitBoxOrient: 'vertical', overflow: 'hidden',
          }}>{p.title}</div>
          <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)', whiteSpace: 'nowrap' }}>{fmt.price(p.price)}</div>
        </div>
        <div style={{
          marginTop: 8, display: 'flex', alignItems: 'center', gap: 10,
          fontSize: 11, color: 'var(--ink-2)',
        }}>
          {facts.length ? facts.map((f, i) => (
            <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 3 }}>
              {f.includes('bd') && I.bed(12)}
              {f.includes('ba') && I.bath(12)}
              {f.includes('sf') && I.sqft(12)}
              {f}
            </span>
          )) : <em style={{ color: 'var(--ink-3)' }}>incomplete listing</em>}
        </div>
        <div style={{
          marginTop: 10, paddingTop: 10, borderTop: '1px solid var(--line-2)',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        }}>
          <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>Saved {p.saved}</span>
          <VisibilityDot visibility={p.visibility} />
        </div>
      </div>
    </article>
  );
}

// ─────────────────────────────────────────────────────────────
// Concept C — Hybrid (RECOMMENDED)
// Editorial face by default. On hover (desktop) the bottom 1/3 of the image
// peels back to reveal a mini-map + commute. Location-as-progressive-
// disclosure. Below the image: neighborhood subtitle (always visible),
// title in serif, price, facts. Notes appear if present. Variable aspect
// ratio supports masonry feel without becoming chaotic.
// ─────────────────────────────────────────────────────────────
function CardHybrid({ p, w = 280, mapPeek = false }) {
  const [hover, setHover] = React.useState(false);
  const showMap = hover || mapPeek;
  const h = Math.round(w * (p.aspect || 1) * 0.78); // a bit less tall than editorial
  return (
    <article className="hhd-lift"
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        width: w, background: 'transparent',
      }}>
      <div style={{
        position: 'relative', borderRadius: 'var(--r-md)', overflow: 'hidden',
        boxShadow: 'var(--shadow-1)',
      }}>
        <HeroImg p={p} h={h} />
        <SourceBadge source={p.source} position="topleft" />
        {p.status && (
          <div style={{ position: 'absolute', top: 10, right: 10 }}>
            <StatusBadgeOverlay status={p.status} />
          </div>
        )}
        {/* peeling map drawer */}
        <div style={{
          position: 'absolute', left: 0, right: 0, bottom: 0,
          height: 64,
          transform: showMap ? 'translateY(0)' : 'translateY(64px)',
          transition: 'transform .25s cubic-bezier(.2,.7,.3,1)',
          background: 'var(--paper-2)', borderTop: '1px solid rgba(0,0,0,.06)',
        }}>
          <MiniMap width={w} height={64} neighborhood={p.neighborhood} accent={p.accent} />
          <div style={{
            position: 'absolute', left: 10, bottom: 8,
            display: 'flex', alignItems: 'center', gap: 6,
            padding: '3px 8px', borderRadius: 999,
            background: 'rgba(247,243,236,.95)',
            color: 'var(--ink)', fontSize: 11, fontWeight: 500,
            boxShadow: '0 1px 2px rgba(0,0,0,.08)',
          }}>
            {I.pin(11)} {p.neighborhood} <span style={{ opacity: .4 }}>·</span> {p.region}
          </div>
          {p.commute && (
            <div style={{
              position: 'absolute', right: 10, bottom: 8,
              padding: '3px 8px', borderRadius: 999,
              background: 'rgba(31,27,22,.78)', color: '#f3ece0',
              fontSize: 11, fontFamily: 'var(--mono)', letterSpacing: 0.2,
            }}>{p.commute}</div>
          )}
        </div>
      </div>
      <div style={{ padding: '12px 4px 0' }}>
        <div style={{
          fontFamily: 'var(--serif)', fontSize: 16, fontWeight: 500, lineHeight: 1.25,
          letterSpacing: -0.15, color: 'var(--ink)', textWrap: 'pretty',
          display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
        }}>{p.title}</div>
        <div style={{
          marginTop: 4, display: 'flex', alignItems: 'center', gap: 6,
          fontSize: 12, color: 'var(--ink-3)',
        }}>
          <span style={{ color: 'var(--ink-2)' }}>{p.neighborhood}</span>
          <span className="dot" />
          <span>{p.region}</span>
        </div>
        <div style={{
          marginTop: 8, display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
          fontSize: 12,
        }}>
          <span style={{ fontWeight: 600, fontSize: 13, color: 'var(--ink)' }}>{fmt.price(p.price)}</span>
          <span style={{ color: 'var(--ink-3)' }}>
            {fmt.facts(p).length ? fmt.facts(p).join(' · ') : <em>details pending</em>}
          </span>
        </div>
        {p.note && (
          <div style={{
            marginTop: 10, padding: '8px 10px',
            background: 'var(--paper-2)', borderRadius: 'var(--r-sm)',
            fontFamily: 'var(--serif)', fontSize: 12.5, fontStyle: 'italic', lineHeight: 1.4,
            color: 'var(--ink-2)', position: 'relative', paddingLeft: 22,
          }}>
            <span style={{ position: 'absolute', left: 8, top: 7, color: 'var(--accent)' }}>{I.note(11)}</span>
            <span style={{
              display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
            }}>{p.note}</span>
          </div>
        )}
        <div style={{
          marginTop: 10, display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          fontSize: 11,
        }}>
          <span style={{ display: 'flex', gap: 10, alignItems: 'center', color: 'var(--ink-3)' }}>
            <span>Saved {p.saved}</span>
            {p.status && <><span className="dot" /><StatusPip status={p.status} /></>}
          </span>
          <VisibilityDot visibility={p.visibility} />
        </div>
      </div>
    </article>
  );
}

function StatusBadgeOverlay({ status }) {
  const map = {
    shortlisted: { color: 'var(--shortlist)', icon: I.bookmark(11, true), label: 'Shortlisted' },
    visited:     { color: 'var(--visited)',   icon: I.eye(11),            label: 'Visited' },
    favorite:    { color: 'var(--accent)',    icon: I.heart(11, true),    label: 'Favorite' },
  };
  const s = map[status]; if (!s) return null;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '4px 8px', borderRadius: 999,
      background: 'rgba(247,243,236,.92)', backdropFilter: 'blur(6px)',
      color: s.color, fontSize: 11, fontWeight: 500,
      boxShadow: '0 1px 3px rgba(0,0,0,.10)',
    }}>{s.icon}{s.label}</span>
  );
}

Object.assign(window, {
  CardEditorial, CardUtility, CardHybrid,
  HeroImg, SourceBadge, VisibilityDot, StatusPip, StatusBadgeOverlay,
});
