// app-data.jsx — the data layer.
// Provides a Supabase client, a React context (artworks + editable text), and
// the built-in defaults used as a fallback whenever Supabase is not configured
// or unreachable. The whole public site reads from here.

const { createContext: _createContext, useContext: _useContext,
        useState: _ad_us, useEffect: _ad_ue } = React;

// ─────────────── Default editable text ───────────────
// Every key here can be overridden by a row in the `content` table. Keep the
// defaults equal to the original copy so the site looks identical with no DB.
const DEFAULT_CONTENT = {
  // Brand / nav
  'brand.markInitial': 'A',
  'brand.first': 'Atiye',
  'brand.last': 'Farahani',
  'nav.studioStatus': 'Studio open · Toronto',

  // Hero
  'hero.eyebrow': 'Oil paintings · 2022 — present',
  'hero.titleLine1': 'Painting the ',
  'hero.titleEm': 'quiet',
  'hero.titleLine3': 'parts of a day.',
  'hero.portraitImage': 'assets/artist.jpg',
  'hero.portraitCaption': '— in the studio,\nthis spring.',
  'hero.aboutKicker': 'About the studio',
  'hero.lede': 'Atiye Farahani is a painter working in oil, acrylic & watercolour. Her work moves between figures, flowers, and the animals she loves — soft rooms, softer light, the warmth of a held breath.',
  'hero.ctaPrimary': 'Wander the gallery',
  'hero.ctaSecondary': 'Commission a painting',
  'hero.commissionNote': 'Taking 2 commissions this season.',

  // Series strip
  'series.kicker': 'Four series, in progress',
  'series.titlePre': 'Small rooms, ',
  'series.titleEm': 'slow hours',
  'series.titlePost': ', studies of the people I love.',
  'series.descFigures': 'Bodies in interior light — rose, indigo, gold.',
  'series.descFlorals': 'Peonies, hellebores, blossoms dissolving into weather.',
  'series.descCompanions': 'The cats of the studio, at rest and at play.',
  'series.descLandscape': 'Mist, still water, a single quiet tree.',

  // Featured
  'featured.kicker': '— currently available',
  'featured.title': 'Four paintings looking for a wall.',
  'featured.more': 'See all available',

  // Home commission CTA
  'homeCommission.big': 'A painting, just for you.',
  'homeCommission.body': "I take a small number of private commissions each season — portraits, still lifes, and quiet pieces on linen or panel. Let me know what you'd like to hold, and we'll find the shape of it together.",
  'homeCommission.cta': 'Start a commission',
  'homeCommission.image': 'paintings/commission-wip.jpg',
  'homeCommission.caption': 'above · a piece in progress,\nfrom photo to canvas.',

  // Gallery
  'gallery.titlePre': 'Everything, ',
  'gallery.titleEm': 'on the wall.',
  'gallery.lede': "Browse the full body of work, from 2023 to the present. Tap any piece to see its story, dimensions, and whether it's still looking for a home.",

  // Shop
  'shop.titlePre': 'Paintings ',
  'shop.titleEm': 'looking for a home.',
  'shop.lede': 'Each piece is one of one — oil on linen or panel, signed on the back, and shipped rolled or crated from Toronto. Framing available on request.',
  'shop.note': 'free shipping on originals over €1,000.',

  // Commission page
  'commission.kicker': 'Currently accepting · 2 openings this season',
  'commission.titlePre': "Let's paint ",
  'commission.titleEm': 'something of yours.',
  'commission.lede': "Tell me about the painting you'd like to live with. I'll reply within a few days with a small proposal — a sketch, a sample palette, and an honest timeline. Once we agree, I start painting, and send you quiet progress photos along the way.",
  'commission.signature': '— Atiye',
  'commission.timelineTitle': 'How a commission goes',

  // Footer
  'footer.script': 'Atiye',
  'footer.sub': 'Oil paintings, made slowly, from a small studio in Toronto.',
  'footer.instagram': 'https://instagram.com/farahaniatiye_art',
  'footer.arena': '#',
  'footer.email': 'info@atiyefarahani.com',
  'footer.letterText': 'A quiet email, every few months, when new work is ready.',
  'footer.copyright': '© 2026 Atiye Farahani',
  'footer.tagline': 'made with care',
  'footer.reserved': 'All paintings reserved to the artist.',
};

// ─────────────── Supabase client (lazy singleton) ───────────────
let _supabase = null;
function getSupabase() {
  const cfg = window.ATIYE_CONFIG || {};
  if (!cfg.SUPABASE_URL || !cfg.SUPABASE_ANON_KEY) return null;     // not configured → fallback mode
  if (!window.supabase || !window.supabase.createClient) return null; // library not loaded
  if (!_supabase) {
    _supabase = window.supabase.createClient(cfg.SUPABASE_URL, cfg.SUPABASE_ANON_KEY);
  }
  return _supabase;
}

// Resolve an artwork's stored image reference to a usable <img src>.
// Storage uploads are stored as absolute URLs; legacy/seed rows use repo-relative paths.
function resolveImage(image_path) {
  if (!image_path) return null;
  if (/^https?:\/\//i.test(image_path) || image_path.startsWith('data:')) return image_path;
  return image_path; // repo-relative, e.g. "paintings/peonies.jpg"
}

// Map a DB row to the shape the UI components expect.
function rowToPainting(r) {
  return {
    id: r.slug || r.id,
    title: r.title,
    series: r.series,
    image: resolveImage(r.image_path),
    palette: r.palette || 'abstract-blush',
    year: r.year,
    size: r.size,
    medium: r.medium,
    price: r.price,
    available: !!r.available,
    tags: r.tags || [],
    note: r.note || '',
  };
}

// ─────────────── Loaders ───────────────
async function loadArtworks() {
  const sb = getSupabase();
  if (!sb) return null; // signal: use fallback
  const { data, error } = await sb
    .from('artworks')
    .select('*')
    .order('sort_order', { ascending: true })
    .order('year', { ascending: false });
  if (error) { console.warn('[atiye] artworks load failed, using fallback:', error.message); return null; }
  return (data || []).map(rowToPainting);
}

async function loadContent() {
  const sb = getSupabase();
  if (!sb) return {};
  const { data, error } = await sb.from('content').select('key,value');
  if (error) { console.warn('[atiye] content load failed, using defaults:', error.message); return {}; }
  const map = {};
  (data || []).forEach(row => { if (row.value != null && row.value !== '') map[row.key] = row.value; });
  return map;
}

// ─────────────── React context ───────────────
const DataContext = _createContext(null);

function DataProvider({ children }) {
  const [paintings, setPaintings] = _ad_us(() => window.DEFAULT_PAINTINGS || []);
  const [content, setContent]     = _ad_us(DEFAULT_CONTENT);
  const [loaded, setLoaded]       = _ad_us(false);

  _ad_ue(() => {
    let alive = true;
    (async () => {
      const [arts, cont] = await Promise.all([loadArtworks(), loadContent()]);
      if (!alive) return;
      if (arts && arts.length) setPaintings(arts);
      setContent({ ...DEFAULT_CONTENT, ...cont });
      setLoaded(true);
    })();
    return () => { alive = false; };
  }, []);

  const c = (key) => (content[key] != null ? content[key] : (DEFAULT_CONTENT[key] || ''));
  return (
    <DataContext.Provider value={{ paintings, content, c, loaded }}>
      {children}
    </DataContext.Provider>
  );
}

function useData() {
  const ctx = _useContext(DataContext);
  // Safe fallback if a component is rendered outside the provider.
  if (!ctx) return { paintings: window.DEFAULT_PAINTINGS || [], content: DEFAULT_CONTENT, c: (k) => DEFAULT_CONTENT[k] || '', loaded: false };
  return ctx;
}

// Render text that may contain newlines, inserting <br/> between lines.
function MultiLine({ text }) {
  const parts = String(text || '').split('\n');
  return parts.map((p, i) => (
    <React.Fragment key={i}>{p}{i < parts.length - 1 ? <br /> : null}</React.Fragment>
  ));
}

Object.assign(window, {
  DEFAULT_CONTENT, getSupabase, resolveImage, rowToPainting,
  loadArtworks, loadContent, DataProvider, useData, MultiLine,
});
