<script>
  import { toPng } from 'html-to-image';

  /** @type {{ entries: import('../shared/types.js').JournalEntry[], onClose: () => void }} */
  let { entries, onClose } = $props();

  let cardEl = $state(null);
  let downloading = $state(false);

  const continentMap = {
    'Japan': 'Asia', 'South Korea': 'Asia', 'China': 'Asia', 'Thailand': 'Asia',
    'Vietnam': 'Asia', 'Indonesia': 'Asia', 'Malaysia': 'Asia', 'Singapore': 'Asia',
    'India': 'Asia', 'Taiwan': 'Asia', 'Philippines': 'Asia', 'Cambodia': 'Asia',
    'Nepal': 'Asia', 'Bangladesh': 'Asia',
    'France': 'Europe', 'Spain': 'Europe', 'Italy': 'Europe', 'Germany': 'Europe',
    'UK': 'Europe', 'Netherlands': 'Europe', 'Portugal': 'Europe', 'Greece': 'Europe',
    'Sweden': 'Europe', 'Norway': 'Europe', 'Denmark': 'Europe', 'Finland': 'Europe',
    'Switzerland': 'Europe', 'Austria': 'Europe', 'Belgium': 'Europe', 'Poland': 'Europe',
    'Czech Republic': 'Europe', 'Hungary': 'Europe', 'Croatia': 'Europe', 'Turkey': 'Europe',
    'USA': 'N. America', 'Canada': 'N. America', 'Mexico': 'N. America',
    'Brazil': 'S. America', 'Argentina': 'S. America', 'Chile': 'S. America',
    'Peru': 'S. America', 'Colombia': 'S. America',
    'Australia': 'Oceania', 'New Zealand': 'Oceania',
    'Morocco': 'Africa', 'Egypt': 'Africa', 'Kenya': 'Africa', 'South Africa': 'Africa',
  };

  const flightHoursMap = {
    'Japan': 13, 'South Korea': 13, 'China': 12, 'Thailand': 11, 'Vietnam': 12,
    'Indonesia': 14, 'Malaysia': 11, 'Singapore': 11, 'India': 9, 'Taiwan': 13,
    'France': 9, 'Spain': 10, 'Italy': 10, 'Germany': 9, 'UK': 8, 'Netherlands': 9,
    'Portugal': 9, 'Greece': 11, 'Sweden': 10, 'Norway': 9, 'Switzerland': 9,
    'Turkey': 11, 'Austria': 10, 'Belgium': 9, 'Poland': 10,
    'USA': 14, 'Canada': 13, 'Mexico': 13,
    'Brazil': 10, 'Argentina': 12, 'Chile': 13,
    'Australia': 20, 'New Zealand': 23,
    'Morocco': 10, 'Egypt': 12, 'Kenya': 14, 'South Africa': 16,
  };

  let stats = $derived.by(() => {
    if (entries.length === 0) return null;

    const totalDays = entries.reduce((s, e) => s + e.days, 0);
    const countries = [...new Set(entries.map(e => e.location.country))];
    const cities    = [...new Set(entries.flatMap(e => e.location.cities))];

    // Continent days
    const contDays = {};
    for (const e of entries) {
      const cont = continentMap[e.location.country] ?? 'Other';
      contDays[cont] = (contDays[cont] ?? 0) + e.days;
    }
    const topContinent = Object.entries(contDays).sort((a, b) => b[1] - a[1])[0];

    // Longest trip
    const longest = [...entries].sort((a, b) => b.days - a.days)[0];

    // Date range
    const dates = entries.map(e => new Date(e.date));
    const firstDate = new Date(Math.min(...dates));
    const lastDate  = new Date(Math.max(...dates));
    const spanDays  = Math.round((lastDate - firstDate) / 86400000);
    const spanMonths = Math.round(spanDays / 30);

    // Flight hours estimate
    const flightTrips = entries.filter(e => e.transport === 'flight');
    const flightHrs = flightTrips.reduce((s, e) => s + (flightHoursMap[e.location.country] ?? 10), 0);

    // Solo vs friends
    const soloCount   = entries.filter(e => e.tripType === 'solo').length;
    const friendCount = entries.filter(e => e.tripType === 'friends').length;
    const familyCount = entries.filter(e => e.tripType === 'family').length;

    // Most visited country
    const countryCounts = {};
    for (const e of entries) countryCounts[e.location.country] = (countryCounts[e.location.country] ?? 0) + 1;
    const favCountry = Object.entries(countryCounts).sort((a, b) => b[1] - a[1])[0];

    const yearStart = firstDate.getFullYear();
    const yearEnd   = lastDate.getFullYear();

    return {
      totalDays, countries, cities, contDays, topContinent,
      longest, flightHrs, soloCount, friendCount, familyCount,
      favCountry, spanMonths, yearStart, yearEnd,
    };
  });

  async function download() {
    if (!cardEl) return;
    downloading = true;
    try {
      const dataUrl = await toPng(cardEl, { pixelRatio: 3 });
      const a = document.createElement('a');
      a.download = 'my-journey.png';
      a.href = dataUrl;
      a.click();
    } finally {
      downloading = false;
    }
  }

  function fmtYear(y1, y2) {
    return y1 === y2 ? `${y1}` : `${y1} – ${y2}`;
  }
</script>

<!-- Overlay -->
<div class="overlay" role="dialog" aria-modal="true">
  <div class="overlay-inner">

    <!-- Controls -->
    <div class="controls">
      <button class="ctrl-btn" onclick={onClose}>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
          <path d="M18 6 6 18M6 6l12 12"/>
        </svg>
        Close
      </button>
      <button class="ctrl-btn ctrl-btn--primary" onclick={download} disabled={downloading}>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/>
        </svg>
        {downloading ? 'Saving…' : 'Save as PNG'}
      </button>
    </div>

    <!-- The card (Instagram story 9:16) -->
    {#if stats}
    <div class="card-wrap">
      <div class="card" bind:this={cardEl}>

        <!-- Background layers -->
        <div class="bg-gradient"></div>
        <div class="bg-grid"></div>

        <!-- Header -->
        <div class="card-header">
          <span class="card-brand">MAP JOURNAL</span>
          <span class="card-year">{fmtYear(stats.yearStart, stats.yearEnd)}</span>
        </div>

        <!-- Hero stat -->
        <div class="hero">
          <p class="hero-num">{stats.totalDays}</p>
          <p class="hero-label">days of travel</p>
        </div>

        <!-- Stat grid -->
        <div class="stat-grid">
          <div class="stat-box">
            <p class="stat-num">{stats.countries.length}</p>
            <p class="stat-desc">countries</p>
          </div>
          <div class="stat-box">
            <p class="stat-num">{stats.cities.length}</p>
            <p class="stat-desc">cities</p>
          </div>
          <div class="stat-box">
            <p class="stat-num">{stats.flightHrs}h</p>
            <p class="stat-desc">in the air</p>
          </div>
          <div class="stat-box">
            <p class="stat-num">{Object.keys(stats.contDays).length}</p>
            <p class="stat-desc">continents</p>
          </div>
        </div>

        <!-- Fun facts -->
        <div class="facts">
          {#if stats.topContinent}
            <div class="fact">
              <span class="fact-icon">🌏</span>
              <span class="fact-text">Spent <strong>{stats.topContinent[1]} days</strong> in {stats.topContinent[0]}</span>
            </div>
          {/if}
          {#if stats.longest}
            <div class="fact">
              <span class="fact-icon">📍</span>
              <span class="fact-text">Longest stay: <strong>{stats.longest.days} days</strong> in {stats.longest.location.cities.join(', ')}</span>
            </div>
          {/if}
          {#if stats.flightHrs > 0}
            <div class="fact">
              <span class="fact-icon">✈️</span>
              <span class="fact-text">~<strong>{stats.flightHrs} hrs</strong> crossing skies</span>
            </div>
          {/if}
          {#if stats.favCountry && stats.favCountry[1] > 1}
            <div class="fact">
              <span class="fact-icon">❤️</span>
              <span class="fact-text">Kept coming back to <strong>{stats.favCountry[0]}</strong></span>
            </div>
          {/if}
          <div class="fact">
            <span class="fact-icon">{stats.soloCount >= stats.friendCount ? '🧳' : '👥'}</span>
            <span class="fact-text">{stats.soloCount} solo{stats.friendCount > 0 ? ` · ${stats.friendCount} with friends` : ''}{stats.familyCount > 0 ? ` · ${stats.familyCount} with family` : ''}</span>
          </div>
        </div>

        <!-- Continent bar -->
        {#if Object.keys(stats.contDays).length > 0}
          <div class="cont-section">
            <div class="cont-bar">
              {#each Object.entries(stats.contDays).sort((a,b)=>b[1]-a[1]) as [cont, days]}
                <div class="cont-seg" style="flex:{days}; background: var(--cont-{cont.replace('. ','').toLowerCase().replace(' ','-')}, #818cf8)"
                  title="{cont}: {days}d"></div>
              {/each}
            </div>
            <div class="cont-legend">
              {#each Object.entries(stats.contDays).sort((a,b)=>b[1]-a[1]) as [cont, days]}
                <span class="cont-item">
                  <span class="cont-dot" style="background: var(--cont-{cont.replace('. ','').toLowerCase().replace(' ','-')}, #818cf8)"></span>
                  {cont} {days}d
                </span>
              {/each}
            </div>
          </div>
        {/if}

        <!-- Footer -->
        <div class="card-footer">
          <span>mapjournal.app</span>
        </div>

      </div>
    </div>
    {/if}

  </div>
</div>

<style>
  /* ── Overlay ── */
  .overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.7);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    backdrop-filter: blur(4px);
  }
  .overlay-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    height: 100%;
    overflow-y: auto;
  }

  /* ── Controls ── */
  .controls {
    display: flex;
    gap: 10px;
    flex-shrink: 0;
  }
  .ctrl-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--sans);
    font-size: 13px;
    font-weight: 400;
    padding: 8px 18px;
    border-radius: 8px;
    border: 1px solid rgba(255,255,255,0.2);
    background: rgba(255,255,255,0.1);
    color: #fff;
    cursor: pointer;
    transition: background 0.15s;
  }
  .ctrl-btn:hover { background: rgba(255,255,255,0.18); }
  .ctrl-btn--primary {
    background: #7c3aed;
    border-color: #7c3aed;
  }
  .ctrl-btn--primary:hover { background: #6d28d9; }
  .ctrl-btn:disabled { opacity: 0.6; cursor: default; }

  /* ── Card wrap (scrollable preview) ── */
  .card-wrap {
    flex-shrink: 0;
  }

  /* ── Card itself (Instagram story 9:16 → 360×640 preview) ── */
  .card {
    width: 360px;
    min-height: 640px;
    border-radius: 20px;
    overflow: hidden;
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 32px 28px 24px;
    gap: 0;
    font-family: 'Bricolage Grotesque', system-ui, sans-serif;
    background: #0f0a1e;
    color: #fff;

    /* continent color vars */
    --cont-asia: #f87171;
    --cont-europe: #818cf8;
    --cont-africa: #fb923c;
    --cont-namerica: #4ade80;
    --cont-n-america: #4ade80;
    --cont-samerica: #fbbf24;
    --cont-s-america: #fbbf24;
    --cont-oceania: #c084fc;
  }

  /* Backgrounds */
  .bg-gradient {
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 60% 40% at 80% 10%, rgba(124,58,237,0.35) 0%, transparent 70%),
      radial-gradient(ellipse 50% 50% at 10% 80%, rgba(99,102,241,0.25) 0%, transparent 60%);
    pointer-events: none;
  }
  .bg-grid {
    position: absolute;
    inset: 0;
    background-image:
      linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
      linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
    background-size: 32px 32px;
    pointer-events: none;
  }

  /* Header */
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 36px;
    position: relative;
    z-index: 1;
  }
  .card-brand {
    font-size: 9px;
    font-weight: 500;
    letter-spacing: 0.22em;
    color: #a5b4fc;
  }
  .card-year {
    font-size: 11px;
    font-weight: 300;
    color: rgba(255,255,255,0.4);
    letter-spacing: 0.06em;
  }

  /* Hero */
  .hero {
    position: relative;
    z-index: 1;
    margin-bottom: 28px;
  }
  .hero-num {
    font-size: 88px;
    font-weight: 400;
    line-height: 1;
    letter-spacing: -4px;
    color: #fff;
  }
  .hero-label {
    font-size: 16px;
    font-weight: 300;
    color: #a5b4fc;
    letter-spacing: 0.04em;
    margin-top: 4px;
  }

  /* Stat grid */
  .stat-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    margin-bottom: 24px;
    position: relative;
    z-index: 1;
  }
  .stat-box {
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 10px;
    padding: 10px 8px;
    text-align: center;
  }
  .stat-num {
    font-size: 22px;
    font-weight: 400;
    color: #fff;
    letter-spacing: -0.5px;
    line-height: 1;
    margin-bottom: 4px;
  }
  .stat-desc {
    font-size: 9px;
    font-weight: 400;
    color: rgba(255,255,255,0.4);
    text-transform: uppercase;
    letter-spacing: 0.1em;
  }

  /* Facts */
  .facts {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 24px;
    position: relative;
    z-index: 1;
  }
  .fact {
    display: flex;
    align-items: center;
    gap: 10px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 10px;
    padding: 10px 14px;
  }
  .fact-icon { font-size: 16px; flex-shrink: 0; }
  .fact-text {
    font-size: 12px;
    font-weight: 300;
    color: rgba(255,255,255,0.7);
    line-height: 1.4;
  }
  .fact-text strong { color: #fff; font-weight: 400; }

  /* Continent bar */
  .cont-section {
    position: relative;
    z-index: 1;
    margin-bottom: 20px;
  }
  .cont-bar {
    display: flex;
    height: 6px;
    border-radius: 3px;
    overflow: hidden;
    gap: 2px;
    margin-bottom: 8px;
  }
  .cont-seg { border-radius: 3px; min-width: 4px; }
  .cont-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 12px;
  }
  .cont-item {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 9px;
    font-weight: 300;
    color: rgba(255,255,255,0.5);
    letter-spacing: 0.04em;
  }
  .cont-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex-shrink: 0;
  }

  /* Footer */
  .card-footer {
    margin-top: auto;
    padding-top: 16px;
    border-top: 1px solid rgba(255,255,255,0.08);
    font-size: 9px;
    font-weight: 300;
    color: rgba(255,255,255,0.25);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    position: relative;
    z-index: 1;
  }
</style>
