// Content store for Malfino.de.
//
// Starts COMPLETELY EMPTY, categories and coloring pages are created by the admin.
// • In production (CapRover) it hydrates from and writes through to the backend API
//   (/api/categories, /api/images) so all visitors share the same live catalogue.
// • In the local preview (no backend) it persists to localStorage so the admin can
//   build the catalogue and the dashboard/counters reflect the real, current data.
//
// The public arrays window.CATEGORIES / window.COLORINGS are recomputed from the store
// and an `aw:data-changed` event is fired on every change so the UI re-renders.

const _CATS_KEY = 'aw.cats';
const _IMGS_KEY = 'aw.imgs';

const _loadLS = (k) => { try { const v = JSON.parse(localStorage.getItem(k) || '[]'); return Array.isArray(v) ? v : []; } catch { return []; } };
const _saveLS = (k, v) => { try { localStorage.setItem(k, JSON.stringify(v)); } catch {} };

// Raw stores (no demo seed → empty until the admin adds content).
let _cats = _loadLS(_CATS_KEY);   // [{ slug, name, art, tone, description, coverImage, parent }]
let _imgs = _loadLS(_IMGS_KEY);   // [{ id, slug, title, art, category, tags, difficulty, previewUrl, pdfUrl, downloads, prints, points, isNew, status }]

// Tone helpers map color names → tailwind classes
const TONE_CLASSES = {
  mint:  { bg: 'bg-mint',  ring: 'ring-mint',  soft: 'bg-mint/30',  text: 'text-emerald-800' },
  sky:   { bg: 'bg-sky',   ring: 'ring-sky',   soft: 'bg-sky/30',   text: 'text-sky-800' },
  sun:   { bg: 'bg-sun',   ring: 'ring-sun',   soft: 'bg-sun/40',   text: 'text-amber-800' },
  coral: { bg: 'bg-coral', ring: 'ring-coral', soft: 'bg-coral/20', text: 'text-rose-800' },
  lilac: { bg: 'bg-lilac', ring: 'ring-lilac', soft: 'bg-lilac/40', text: 'text-violet-800' },
};

// Count only "active" images toward a category's public count.
const _activeImgs = () => _imgs.filter(x => x.status !== 'inaktiv');
const _countFor = (slug) => _activeImgs().filter(x => x.category === slug).length;

// Recompute the public arrays exposed on window.
function _recompute() {
  window.COLORINGS = _imgs;
  window.CATEGORIES = _cats.map(c => ({ ...c, count: _countFor(c.slug) }));
}
function _persist() {
  _saveLS(_CATS_KEY, _cats);
  _saveLS(_IMGS_KEY, _imgs);
  _recompute();
  window.dispatchEvent(new CustomEvent('aw:data-changed'));
}
_recompute(); // initial (empty unless localStorage already has content)

// ---------- Lookups ----------
const findCategory = (slug) => window.CATEGORIES.find(c => c.slug === slug);
const coloringsByCategory = (slug) => _activeImgs().filter(c => c.category === slug);
const findColoring = (slug) => _imgs.find(c => c.slug === slug);

// Kept for backwards-compatibility with existing callers.
const getCategoriesWithOverrides = () => window.CATEGORIES;
const loadCategoryOverrides = () => ({});

// ---------- Mutations (local-first, with best-effort backend write-through) ----------
const _slugify = (s) => (s || '').toString().toLowerCase()
  .replace(/[äÄ]/g, 'ae').replace(/[öÖ]/g, 'oe').replace(/[üÜ]/g, 'ue').replace(/ß/g, 'ss')
  .replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');

const createCategory = (data) => {
  const slug = data.slug || _slugify(data.name);
  if (!slug || _cats.some(c => c.slug === slug)) return null;
  const cat = {
    slug, name: data.name || slug, art: data.art || 'mandala', tone: data.tone || 'mint',
    description: data.description || '', coverImage: data.coverImage || '', parent: data.parent || '',
  };
  _cats = [..._cats, cat];
  _persist();
  _apiWrite('POST', '/api/categories', {
    slug, name: cat.name, art: cat.art, tone: cat.tone,
    description: cat.description, cover_image: cat.coverImage, parent_slug: cat.parent || null,
  });
  return cat;
};
const updateCategory = (slug, partial) => {
  _cats = _cats.map(c => c.slug === slug ? { ...c, ...partial } : c);
  _persist();
  const c = _cats.find(x => x.slug === slug);
  if (c) _apiWrite('POST', '/api/categories', {
    slug: c.slug, name: c.name, art: c.art, tone: c.tone,
    description: c.description, cover_image: c.coverImage, parent_slug: c.parent || null,
  });
};
// Back-compat alias used by older admin code (cover image saves etc.)
const saveCategoryOverride = (slug, partial) => updateCategory(slug, partial);

const deleteCategoryGlobal = (slug) => {
  _cats = _cats.filter(c => c.slug !== slug);
  _persist();
  _apiWrite('DELETE', '/api/categories/' + encodeURIComponent(slug));
};

const createColoring = (data) => {
  const slug = data.slug || _slugify(data.title);
  if (!slug) return null;
  const img = {
    id: data.id || Date.now(),
    slug, title: data.title || slug, art: data.art || 'mandala',
    category: data.category, tags: data.tags || [], difficulty: data.difficulty || 'Einfach',
    previewUrl: data.previewUrl || '', pdfUrl: data.pdfUrl || '',
    downloads: 0, prints: 0, points: 0, isNew: data.isNew !== false,
    status: data.status || 'aktiv',
    metaTitle: data.metaTitle || '', metaDesc: data.metaDesc || '',
  };
  _imgs = [..._imgs, img];
  _persist();
  _apiWrite('POST', '/api/images', {
    slug, title: img.title, art: img.art, category_slug: img.category, tags: img.tags,
    difficulty: img.difficulty, preview_url: img.previewUrl, pdf_url: img.pdfUrl,
    is_new: img.isNew, status: img.status, meta_title: img.metaTitle, meta_desc: img.metaDesc,
  });
  return img;
};
const updateColoring = (id, partial) => {
  _imgs = _imgs.map(c => c.id === id ? { ...c, ...partial } : c);
  _persist();
};
const deleteImageGlobal = (id) => {
  const img = _imgs.find(c => c.id === id);
  _imgs = _imgs.filter(c => c.id !== id);
  _persist();
  if (img) _apiWrite('DELETE', '/api/images/' + encodeURIComponent(img.id));
};
const deleteImagesByCategory = (slug) => {
  _imgs = _imgs.filter(c => c.category !== slug);
  _persist();
};
const moveImagesToCategory = (fromSlug, toSlug) => {
  _imgs = _imgs.map(c => c.category === fromSlug ? { ...c, category: toSlug } : c);
  _persist();
};

// Public-facing categories: those with at least 1 active image, most-popular first.
const getPublicCategories = () => {
  const totals = {};
  _activeImgs().forEach(c => { totals[c.category] = (totals[c.category] || 0) + (c.points || 0); });
  return window.CATEGORIES
    .filter(c => c.count > 0)
    .sort((a, b) => (totals[b.slug] || 0) - (totals[a.slug] || 0));
};

// ---------- Backend integration ----------
const _toLocalCat = (r) => ({
  slug: r.slug, name: r.name, art: r.art || 'mandala', tone: r.tone || 'mint',
  description: r.description || '', coverImage: r.cover_image || '', parent: r.parent_slug || '',
});
const _toLocalImg = (r) => ({
  id: r.id, slug: r.slug, title: r.title, art: r.art || 'mandala', category: r.category_slug,
  tags: r.tags || [], difficulty: r.difficulty || 'Einfach',
  previewUrl: r.preview_url || '', pdfUrl: r.pdf_url || '',
  downloads: r.downloads || 0, prints: r.prints || 0, points: r.points || 0,
  isNew: r.is_new !== false, status: r.status || 'aktiv',
  metaTitle: r.meta_title || '', metaDesc: r.meta_desc || '',
});

// Fire-and-forget write to the backend (only does anything when a backend is present).
function _apiWrite(method, path, body) {
  try {
    fetch(path, {
      method,
      headers: body ? { 'Content-Type': 'application/json' } : undefined,
      body: body ? JSON.stringify(body) : undefined,
      credentials: 'same-origin',
    }).catch(() => {});
  } catch {}
}

// Pull the live catalogue from the backend. No-op (silent) when there is no backend.
async function hydrateFromBackend() {
  try {
    const [cRes, iRes] = await Promise.all([
      fetch('/api/categories', { headers: { 'Accept': 'application/json' } }),
      fetch('/api/images', { headers: { 'Accept': 'application/json' } }),
    ]);
    if (!cRes.ok || !iRes.ok) return false;
    const cats = await cRes.json();
    const imgs = await iRes.json();
    if (!Array.isArray(cats) || !Array.isArray(imgs)) return false;
    _cats = cats.map(_toLocalCat);
    _imgs = imgs.map(_toLocalImg);
    _persist();
    return true;
  } catch { return false; }
}

// Bereich (user role) options for profile
const BEREICH_OPTIONS = [
  { value: 'familie',     label: 'Eltern / Familie',     emoji: '👨‍👩‍👧' },
  { value: 'kita',        label: 'Kita / Erzieher:in',   emoji: '🧸' },
  { value: 'schule',      label: 'Schule / Lehrer:in',   emoji: '🎒' },
  { value: 'hort',        label: 'Hort / Tagespflege',   emoji: '🏡' },
  { value: 'therapie',    label: 'Therapie / Logopädie', emoji: '🩺' },
  { value: 'kreativ',     label: 'Kreative:r Erwachsene:r', emoji: '🎨' },
  { value: 'sonstiges',   label: 'Sonstiges',            emoji: '✨' },
];

// Avatar palette (for profile bubble)
const AVATAR_PALETTE = [
  { bg: '#A8D5F2', fg: '#1F2A44' }, // sky
  { bg: '#FFE7A1', fg: '#1F2A44' }, // sun
  { bg: '#FF8A7A', fg: '#FFFFFF' }, // coral
  { bg: '#BFE7C9', fg: '#1F2A44' }, // mint
  { bg: '#D8C7F0', fg: '#1F2A44' }, // lilac
];

Object.assign(window, {
  TONE_CLASSES, BEREICH_OPTIONS, AVATAR_PALETTE,
  findCategory, coloringsByCategory, findColoring,
  saveCategoryOverride, loadCategoryOverrides, getCategoriesWithOverrides,
  createCategory, updateCategory, deleteCategoryGlobal,
  createColoring, updateColoring, deleteImageGlobal, deleteImagesByCategory, moveImagesToCategory,
  getPublicCategories, hydrateFromBackend,
});
