// data.jsx — Catalog metadata + mapper for Deanna MiniTiendas (deanna.pro public APIs).
// Feed data comes from /api/explore; product thumbnails from /api/share/:slug → clippings.

const MOODS = [
  { id: 'serena',    label: 'Serena',    emoji: '🌿', color: '#C9DCC0' },
  { id: 'urbana',    label: 'Urbana',    emoji: '🏙️', color: '#B8C5B0' },
  { id: 'romantica', label: 'Romántica', emoji: '🌸', color: '#E4D8C9' },
  { id: 'aventura',  label: 'Aventura',  emoji: '🏕️', color: '#A8B89C' },
  { id: 'minimal',   label: 'Minimal',   emoji: '◻️', color: '#D9D9CF' },
  { id: 'vintage',   label: 'Vintage',   emoji: '📻', color: '#D4C5A0' },
  { id: 'cozy',      label: 'Cozy',      emoji: '☕', color: '#D8C9B5' },
  { id: 'tech',      label: 'Tech',      emoji: '⚡', color: '#B8C8C0' },
];

const CATEGORIES = [
  { id: 'moda',     label: 'Moda',         icon: '👗' },
  { id: 'hogar',    label: 'Hogar',        icon: '🏡' },
  { id: 'belleza',  label: 'Belleza',      icon: '🌷' },
  { id: 'tech',     label: 'Tecnología',   icon: '💻' },
  { id: 'outdoor',  label: 'Aire libre',   icon: '🥾' },
  { id: 'cocina',   label: 'Cocina',       icon: '🍳' },
];

// Cover gradient palettes — sage / matcha forward
const COVER_GRADIENTS = [
  'linear-gradient(135deg, #DCE8D4 0%, #A8C29A 100%)',
  'linear-gradient(160deg, #EDE7DA 0%, #C7B89A 100%)',
  'linear-gradient(135deg, #D4DECF 0%, #8DA585 100%)',
  'linear-gradient(150deg, #F0EBDD 0%, #C9D4BC 100%)',
  'linear-gradient(135deg, #E8DFD0 0%, #B5A788 100%)',
  'linear-gradient(160deg, #D9E4D2 0%, #8FA388 100%)',
];

/** Optional Unsplash placeholders for onboarding art only — not used for feeds. */
const IMG = {};

const STORES = [];

const TRENDING_SEARCHES = [
  'chaquetas de moto',
  'rutina skincare salvia',
  'escritorio minimalista',
  'cerámica artesanal',
  'denim japonés',
  'velas de soja',
  'jersey de punto otoño',
  'fragancias de bosque',
];

const DAILY_DROP = [];

const BOOK_IDS = [];

/**
 * Showcase: limit the feed to ministore DB ids (`/api/explore` payload `id` == `book.id`).
 * `extraShareSlugs`: `/share/` path segments — use when explore omits ids in-range (explore caps ~48).
 */
const SHOWCASE_BOOK_IDS_CONFIG = {
  enabled: true,
  minId: 21650,
  maxId: 21700,
  extraShareSlugs: [],
};

function showcaseBookIdInRange(bookId, cfg) {
  if (!cfg || !cfg.enabled) return true;
  const n = Number(bookId);
  if (!Number.isFinite(n)) return false;
  const lo = Number(cfg.minId);
  const hi = Number(cfg.maxId);
  const a = Number.isFinite(lo) ? lo : n;
  const b = Number.isFinite(hi) ? hi : n;
  const min = Math.min(a, b);
  const max = Math.max(a, b);
  return n >= min && n <= max;
}

/** Build a pseudo-explore row from `GET /api/share/:slug` so `mapApiStore` can ingest it. */
function exploreRowFromShareApi(slug, data) {
  const book = data && data.book;
  if (!book || book.id == null) return null;
  const clips = Array.isArray(data.clippings) ? data.clippings : [];
  let cover = book.thumbnail || '';
  for (let ci = 0; ci < clips.length && !cover; ci++) {
    const u = clipImageUrl(clips[ci]);
    if (u) cover = u;
  }
  return {
    id: book.id,
    name: (book.name || 'MiniTienda').trim(),
    thumbnail: cover,
    url: `/share/${slug}`,
    category_id: book.category_id,
    numViews: 0,
    clippingCount: clips.length,
    description: typeof book.description === 'string' ? book.description : '',
    isOwn: false,
  };
}

async function fetchExploreRowsFromShareSlugs(slugs, apiBase) {
  if (!Array.isArray(slugs) || slugs.length === 0) return [];
  const root = typeof apiBase === 'string' ? apiBase.replace(/\/+$/, '') : '';
  const headers = {};
  const k = typeof window.__DEANNA_API_KEY__ === 'string' && window.__DEANNA_API_KEY__.trim();
  if (k) headers.Authorization = `Bearer ${k}`;
  const out = [];
  const SIZE = 8;
  for (let i = 0; i < slugs.length; i += SIZE) {
    const batch = await Promise.all(
      slugs.slice(i, i + SIZE).map(async (raw) => {
        const slug = typeof raw === 'string' ? raw.trim() : '';
        if (!slug) return null;
        try {
          const r = await fetch(`${root}/api/share/${encodeURIComponent(slug)}`, { headers });
          if (!r.ok) return null;
          const payload = await r.json().catch(() => ({}));
          return exploreRowFromShareApi(slug, payload);
        } catch {
          return null;
        }
      }),
    );
    batch.forEach((row) => {
      if (row) out.push(row);
    });
  }
  return out;
}

function shareSlugFromUrl(url) {
  if (!url || typeof url !== 'string') return null;
  const m = url.match(/\/share\/([^/?#]+)/);
  return m ? decodeURIComponent(m[1]) : null;
}

const CATEGORY_LABEL = {
  moda: 'Moda',
  hogar: 'Hogar',
  belleza: 'Belleza',
  tech: 'Tecnología',
  outdoor: 'Aire libre',
  cocina: 'Cocina',
};

/** Rough map from explore payload category_id → app category bucket. */
const CATEGORY_ID_BUCKET = {
  19: 'moda',
  26: 'tech',
  30: 'hogar',
  39: 'hogar',
};

function categoryFromExplore(s) {
  const slugBucket = mapApiStoreHelpers.catFromSlug(s.category_slug || s.categories_slug);
  if (slugBucket) return slugBucket;
  const cid = s.category_id;
  if (cid != null && CATEGORY_ID_BUCKET[cid]) return CATEGORY_ID_BUCKET[cid];
  return 'moda';
}

const findStore = (id) =>
  STORES.find((s) => s.id === id || String(s.bookId) === String(id));

function formatCreated(iso) {
  if (!iso) return '';
  try {
    const d = new Date(iso);
    return d.toLocaleDateString('es', { day: 'numeric', month: 'short', year: 'numeric' });
  } catch { return ''; }
}

function clipImageUrl(c) {
  if (!c) return '';
  if (c.thumbnail) return c.thumbnail;
  if (c.type === 'image' && c.url && /\.(jpg|jpeg|png|webp|gif)(\?|$)/i.test(c.url)) return c.url;
  return '';
}

function mapClippingToProduct(c, idx) {
  const caption = (c.caption || c.textContent || '').trim();
  let name = caption;
  if (name.length > 72) name = `${name.slice(0, 70)}…`;
  if (!name) name = c.type === 'video' ? `Clip en vídeo #${idx + 1}` : `Pieza ${idx + 1}`;
  const amazon = !!c.isAmazon;
  const brandGuess = amazon ? 'Amazon' : 'Curado';
  return {
    id: String(c.id != null ? c.id : idx),
    name,
    brand: brandGuess,
    price: amazon ? '' : '',
    img: clipImageUrl(c),
    clipUrl: c.url || '',
    clipType: c.type || '',
    isAmazon: amazon,
    rawClip: c,
  };
}


/** Normalize related-store ids once the feed list is known. */
function applyRelatedAndAssign(storesArr) {
  if (!storesArr.length) return;
  storesArr.forEach((s) => {
    const others = storesArr.filter((o) => o.id !== s.id);
    const sameCat = others.filter((o) => o.category === s.category);
    const pool = sameCat.length ? sameCat : others;
    s.related = pool.slice(0, 12).map((o) => o.id);
  });
}

/**
 * Tweaks Prod (deanna.pro): use '' on http(s) pages so `/api/*` stays same-origin
 * — local `dev-server.py`, LAN, and Vercel rewrites proxy to deanna.pro. Tweaks Dev
 * keeps full `http://localhost:3000`; `file:` keeps absolute URL (may still hit CORS).
 */
function resolveDeannaApiBase() {
  const raw = typeof window.__DEANNA_ENDPOINT__ === 'string'
    ? window.__DEANNA_ENDPOINT__.trim().replace(/\/+$/, '')
    : 'https://deanna.pro';
  try {
    const targetsProd = /^https:\/\/deanna\.pro$/i.test(raw);
    if (!targetsProd) return raw;
    const proto = typeof location !== 'undefined' ? String(location.protocol || '') : '';
    if (proto === 'http:' || proto === 'https:') return '';
    return raw;
  } catch (_) {
    return raw;
  }
}

async function hydrateStoreProducts(slugOrStore) {
  const slug = typeof slugOrStore === 'string'
    ? slugOrStore : (slugOrStore && slugOrStore.shareSlug);
  if (!slug) return [];
  const base = resolveDeannaApiBase();
  const headers = {};
  const k = typeof window.__DEANNA_API_KEY__ === 'string' && window.__DEANNA_API_KEY__.trim();
  if (k) headers['Authorization'] = `Bearer ${k}`;
  try {
    const r = await fetch(`${base}/api/share/${encodeURIComponent(slug)}`, { headers });
    const data = r.ok ? await r.json().catch(() => ({})) : {};
    const list = Array.isArray(data.clippings) ? data.clippings : [];
    return list.map((c, i) => mapClippingToProduct(c, i));
  } catch {
    return [];
  }
}

function mergeProductsIntoGlobalStore(bookIdNum, slug, products) {
  const s = window.STORES.find((st) =>
    String(st.bookId) === String(bookIdNum) || (slug && st.shareSlug === slug));
  if (!s) return false;
  const list = Array.isArray(products) ? products : [];
  s.productsLoaded = true;
  s.products = list;
  if (list.length && !s.cover) {
    const withImg = list.find((p) => p.img);
    if (withImg) s.cover = withImg.img;
  }
  window.dispatchEvent(new CustomEvent('deanna:stores-patch'));
  return true;
}

/** Reserved mapApiStore internals for category_slug (if API adds it). */
const mapApiStoreHelpers = {
  catFromSlug(slug) {
    if (!slug) return null;
    const u = slug.toLowerCase();
    const CAT_MAP = {
      moda: 'moda', ropa: 'moda', fashion: 'moda', clothing: 'moda',
      hogar: 'hogar', home: 'hogar', casa: 'hogar', decoracion: 'hogar', deco: 'hogar',
      belleza: 'belleza', beauty: 'belleza', cuidado: 'belleza', skincare: 'belleza',
      tech: 'tech', tecnologia: 'tech', electronica: 'tech', gadgets: 'tech',
      outdoor: 'outdoor', deporte: 'outdoor', sport: 'outdoor', viaje: 'outdoor',
      cocina: 'cocina', kitchen: 'cocina', alimentacion: 'cocina', gastronomia: 'cocina',
    };
    return CAT_MAP[u] || null;
  },
};

// Maps a MiniStoreSummary from /api/explore or /api/my-ministores.
function mapApiStore(s, idx) {
  const MOOD_FOR_CAT = {
    moda: 'urbana', hogar: 'serena', belleza: 'serena',
    tech: 'tech', outdoor: 'aventura', cocina: 'cozy',
  };
  const cat = categoryFromExplore(s);
  const shareSlug =
    shareSlugFromUrl(s.url) || (s.slug && typeof s.slug === 'string' ? s.slug : null);
  const storeId = shareSlug || String(s.id);
  const creatorName = (s.creator && s.creator.name) ? s.creator.name : '';
  const createdStr = formatCreated(s.created);
  const desc = ((s.description != null ? s.description : s.book_description) || '').trim();
  const catLabel = CATEGORY_LABEL[cat] || 'MiniTienda';
  const headlineBits = [];
  if (creatorName) headlineBits.push(`Por ${creatorName}`);
  if (createdStr) headlineBits.push(`actualizada ${createdStr}`);
  headlineBits.push(`· ${catLabel}`);
  if (s.category_id != null) headlineBits.push(`· cat. ${s.category_id}`);
  const vibeTail = `${s.numViews != null ? `${s.numViews} vistas` : ''}${s.numViews != null && s.clippingCount != null ? ' · ' : ''}${s.clippingCount != null ? `${s.clippingCount} clippings` : ''}`;
  return {
    id: storeId,
    shareSlug: shareSlug || storeId,
    bookId: s.id,
    title: (s.name || 'MiniTienda sin título').trim(),
    vibe: desc || vibeTail || 'MiniTienda pública desde deanna.pro',
    category: cat,
    mood: MOOD_FOR_CAT[cat] || 'serena',
    cover: s.thumbnail || '',
    gradient: COVER_GRADIENTS[idx % COVER_GRADIENTS.length],
    saves: s.numViews || 0,
    items: s.clippingCount != null ? s.clippingCount : 0,
    products: [],
    productsLoaded: false,
    related: [],
    headlineSubtitle: headlineBits.filter(Boolean).join(' '),
    creatorName,
    categoryId: s.category_id,
    created: s.created || '',
    isOwn: !!s.isOwn,
    sharePath: (s.url && s.url.startsWith('/')) ? s.url : (shareSlug ? `/share/${shareSlug}` : ''),
  };
}


Object.assign(window, {
  MOODS, CATEGORIES, COVER_GRADIENTS, IMG, STORES, BOOK_IDS,
  TRENDING_SEARCHES, DAILY_DROP, findStore, mapApiStore, shareSlugFromUrl,
  hydrateStoreProducts, mergeProductsIntoGlobalStore, clipImageUrl, applyRelatedAndAssign,
  mapClippingToProduct, resolveDeannaApiBase,
  SHOWCASE_BOOK_IDS_CONFIG, showcaseBookIdInRange, exploreRowFromShareApi,
  fetchExploreRowsFromShareSlugs,
})
