// Product, content, and auth data for the storefront CMS.

const IMG = (id, w = 800) => `https://images.unsplash.com/${id}?auto=format&fit=crop&w=${w}&q=80`;
const PEXVID = (id, file) => `https://videos.pexels.com/video-files/${id}/${id}-${file}.mp4`;
const PEXPOSTER = (id) => `https://images.pexels.com/videos/${id}/pexels-photo-${id}.jpeg?auto=compress&cs=tinysrgb&w=1400`;
// Reliable editorial fallback (the old local file 404'd on deploy). Editable in admin.
const LOCAL_EDITORIAL = IMG('photo-1469334031218-e382a71b716b', 900);

const SW = {
  blush: { name: 'Blush', hex: '#F6D6DA' },
  rose: { name: 'Rose', hex: '#B86A78' },
  ivory: { name: 'Ivory', hex: '#FFF8F5' },
  champagne: { name: 'Champagne', hex: '#F2E3DC' },
  deep: { name: 'Cocoa', hex: '#4A2D33' },
  sand: { name: 'Sand', hex: '#D8C3A8' },
  sage: { name: 'Sage', hex: '#B6C2A7' },
  black: { name: 'Onyx', hex: '#1A1414' },
};

const SIZES = ['XS', 'S', 'M', 'L', 'XL'];

const DEFAULT_SITE_DATA = {
  settings: {
    brandName: 'House of Sheylas',
    brandMark: 'HOS',
    brandTagline: 'HOUSE OF SHEYLAS',
    tagline:
      'Quietly elegant pieces, curated for women who dress for themselves.',
    supportEmail: 'care@houseofsheylas.com',
    pressEmail: 'press@houseofsheylas.com',
    phone: '+1 (438) 555-0148',
    instagramHandle: '@houseofsheylas',
    instagramUrl: 'https://www.instagram.com/',
    tiktokUrl: 'https://www.tiktok.com/',
    facebookUrl: 'https://www.facebook.com/',
    pinterestUrl: 'https://www.pinterest.com/',
    copyright:
      '© 2026 House of Sheylas. Curated with care in Paris.',
    footerLocation: 'Paris',
    newsletterCode: 'HOUSE10',
    newsletterReplyTo: 'care@houseofsheylas.com',
    adminUsername: 'admin',
    adminPassword: 'admin123',
  },
  navigation: [
    { id: 'home', label: 'Home', href: '#home', public: true },
    { id: 'shop', label: 'Shop', href: '#shop', public: true },
    { id: 'collections', label: 'Collections', href: '#collections', public: true },
    { id: 'about', label: 'About', href: '#about', public: true },
    { id: 'contact', label: 'Contact', href: '#contact', public: true },
  ],
  pages: [
    { id: 'home', title: 'Home', status: 'live', href: '#home' },
    { id: 'shop', title: 'Shop', status: 'live', href: '#shop' },
    { id: 'collections', title: 'Collections', status: 'live', href: '#collections' },
    { id: 'about', title: 'About', status: 'live', href: '#about' },
    { id: 'contact', title: 'Contact', status: 'live', href: '#contact' },
  ],
  hero: {
    eyebrow: 'Summer · Édition 2026',
    title: 'Soft elegance',
    accent: 'for every woman.',
    description:
      'A curated edit of feminine pieces — selected to make you feel confident, graceful and unforgettable.',
    metaLeft: 'Boutique · Paris · Est. 2025',
    metaRight: 'N°08 · Summer',
    primaryCtaLabel: 'Shop new collection',
    primaryCtaHref: '#shop/new',
    secondaryCtaLabel: 'View lookbook',
    secondaryCtaHref: '#collections',
    featuredProductId: 'na1',
    featuredLabel: 'Featured',
  },
  story: {
    eyebrow: 'Our story',
    title: 'For women who love',
    accent: 'elegance, confidence,',
    end: 'and timeless femininity.',
    body:
      'House of Sheylas is a curated boutique, bringing together feminine, elevated pieces — chosen with care for the women who wear them.',
    imagePrimary: IMG('photo-1496747611176-843222e1e57c', 900),
    imageSecondary: LOCAL_EDITORIAL,
    stats: [
      { label: 'Launched', value: 'Paris · 2025' },
      { label: 'Atelier', value: 'Small-batch pieces' },
      { label: 'Where we are', value: 'Paris · Canada · Tunisia' },
    ],
    ctaLabel: 'Discover the house',
    ctaHref: '#about',
  },
  newsletter: {
    eyebrow: 'Become a member',
    title: 'Join the',
    accent: 'House',
    description:
      'Get early access to new drops, private sales, and styling inspiration delivered with care to your inbox.',
    successTitle: 'Welcome home.',
  },
  about: {
    eyebrow: 'The House',
    title: 'Quietly made,',
    accent: 'always intentional.',
    subtitle:
      'House of Sheylas is an independent womenswear boutique — a curated edit of feminine, elevated pieces selected for women who dress for themselves.',
    values: [
      {
        id: '01',
        title: 'Curated selection',
        description: 'Every piece is hand-picked. We edit so you don’t have to.',
      },
      {
        id: '02',
        title: 'Elevated quality',
        description: 'Silk, linen, cashmere — fabrics that breathe, drape, and live with you.',
      },
      {
        id: '03',
        title: 'Feminine by design',
        description:
          'Soft silhouettes and refined details, chosen for how they make you feel.',
      },
      {
        id: '04',
        title: 'A quiet ethos',
        description: 'No trends, no noise. We select for the woman, not the season.',
      },
    ],
  },
  locations: [
    {
      city: 'Paris',
      role: 'Studio',
      note: 'Where it all began — 2025.',
    },
    {
      city: 'Canada',
      role: 'Operations',
      note: 'Serving our North American community.',
    },
    {
      city: 'Tunisia',
      role: 'Office',
      note: 'Part of our team, behind the scenes.',
    },
  ],
  services: [
    { id: 'shipping', title: 'Shipping & Returns', href: '#contact' },
    { id: 'tracking', title: 'Order Tracking', href: '#contact' },
    { id: 'size-guide', title: 'Size Guide', href: '#contact' },
    { id: 'care', title: 'Garment Care', href: '#contact' },
    { id: 'contact-us', title: 'Contact Us', href: '#contact' },
  ],
  contact: {
    eyebrow: 'Contact',
    title: 'We’d love to',
    accent: 'hear from you.',
    subtitle:
      'For styling questions, sizing help, press, or quiet hellos. We answer every message within two working days.',
    responseTime: 'We typically reply within 48h.',
    topics: [
      { id: 'general', label: 'General enquiry' },
      { id: 'styling', label: 'Styling help' },
      { id: 'order', label: 'Order question' },
      { id: 'press', label: 'Press' },
      { id: 'wholesale', label: 'Wholesale' },
    ],
    faqs: [
      {
        q: 'Where do you ship?',
        a: 'We ship worldwide from Paris. Rates calculated at checkout.',
      },
      {
        q: 'When will I be charged?',
        a: 'At checkout. Final taxes and duties calculated by destination.',
      },
      {
        q: 'Do you do exchanges?',
        a: 'Yes — within 14 days. Reach out to our care team to arrange one.',
      },
      {
        q: 'Sustainability?',
        a: 'We curate elevated pieces and favour natural fibres wherever we can. Read more on our About page.',
      },
    ],
  },
  collections: [
    {
      id: 'spring-bloom',
      name: 'Summer Edit',
      season: 'SS 2026',
      pieces: 32,
      img: IMG('photo-1490481651871-ab68de25d43d', 1000),
      accent: '#F6D6DA',
    },
    {
      id: 'soft-noir',
      name: 'Soft Noir',
      season: 'AW 2026',
      pieces: 18,
      img: IMG('photo-1539008835657-9e8e9680c956', 1000),
      accent: '#4A2D33',
    },
    {
      id: 'champagne',
      name: 'Champagne Hour',
      season: 'Resort',
      pieces: 24,
      img: IMG('photo-1518049362265-d5b2a6b00b37', 1000),
      accent: '#F2E3DC',
    },
    {
      id: 'atelier',
      name: 'Atelier Edit',
      season: 'Capsule',
      pieces: 12,
      img: LOCAL_EDITORIAL,
      accent: '#B86A78',
    },
  ],
  categories: [
    {
      id: 'dresses',
      name: 'Dresses',
      count: '48 pieces',
      img: IMG('photo-1539109136881-3be0616acf4b', 700),
      status: 'live',
      subcategories: [
        { id: 'new', name: 'New In', href: '#shop/new' },
        { id: 'bestsellers', name: 'Best Sellers', href: '#shop/bestsellers' },
      ],
    },
    {
      id: 'sets',
      name: 'Sets',
      count: '24 pieces',
      img: IMG('photo-1515886657613-9f3515b0c78f', 700),
      status: 'live',
      subcategories: [],
    },
    {
      id: 'tops',
      name: 'Tops',
      count: '36 pieces',
      img: IMG('photo-1551803091-e20673f15770', 700),
      status: 'live',
      subcategories: [],
    },
    {
      id: 'accessories',
      name: 'Accessories',
      count: '52 pieces',
      img: IMG('photo-1606760227091-3dd870d97f1d', 700),
      status: 'live',
      subcategories: [],
    },
  ],
  products: [
    {
      id: 'na1',
      name: 'Aurelie Silk Slip Dress',
      price: 248,
      category: 'dresses',
      img: IMG('photo-1566174053879-31528523f8ae', 700),
      tag: 'New',
      colors: [SW.blush, SW.champagne, SW.deep],
      description:
        'Cut from feather-light silk satin, this piece drapes effortlessly with a bias-cut silhouette that moves with you.',
      stock: 24,
      status: 'live',
      isNew: true,
      sizes: SIZES,
    },
    {
      id: 'na2',
      name: 'Mireille Pleated Skirt',
      price: 184,
      category: 'bottoms',
      img: IMG('photo-1581338834647-b0fb40704e21', 700),
      tag: 'New',
      colors: [SW.ivory, SW.rose, SW.sand],
      stock: 18,
      status: 'live',
      isNew: true,
      sizes: SIZES,
    },
    {
      id: 'na3',
      name: 'Celeste Linen Co-ord',
      price: 295,
      category: 'sets',
      img: IMG('photo-1572804013309-59a88b7e92f1', 700),
      tag: 'Just in',
      colors: [SW.champagne, SW.sage],
      stock: 12,
      status: 'live',
      isNew: true,
      sizes: SIZES,
    },
    {
      id: 'na4',
      name: 'Sienna Wrap Blouse',
      price: 148,
      category: 'tops',
      img: IMG('photo-1551163943-3f7053a3b8d8', 700),
      tag: 'New',
      colors: [SW.blush, SW.ivory, SW.rose],
      stock: 28,
      status: 'live',
      isNew: true,
      sizes: SIZES,
    },
    {
      id: 'na5',
      name: 'Romy Cropped Cardigan',
      price: 168,
      category: 'tops',
      img: IMG('photo-1518049362265-d5b2a6b00b37', 700),
      tag: 'Limited',
      colors: [SW.rose, SW.champagne, SW.deep],
      stock: 9,
      status: 'live',
      isNew: true,
      sizes: SIZES,
    },
    {
      id: 'na6',
      name: 'Eloise Mini Dress',
      price: 228,
      category: 'dresses',
      img: IMG('photo-1572804013427-4d7ca7268217', 700),
      tag: 'New',
      colors: [SW.ivory, SW.blush],
      stock: 16,
      status: 'live',
      isNew: true,
      sizes: SIZES,
    },
    {
      id: 'na7',
      name: 'Lila Wide-Leg Trousers',
      price: 198,
      category: 'bottoms',
      img: IMG('photo-1594633312681-425c7b97ccd1', 700),
      tag: 'New',
      colors: [SW.champagne, SW.deep, SW.black],
      stock: 21,
      status: 'live',
      isNew: true,
      sizes: SIZES,
    },
    {
      id: 'na8',
      name: 'Solene Knot Top',
      price: 124,
      category: 'tops',
      img: IMG('photo-1503342217505-b0a15ec3261c', 700),
      tag: 'Just in',
      colors: [SW.blush, SW.rose, SW.ivory],
      stock: 19,
      status: 'live',
      isNew: true,
      sizes: SIZES,
    },
    {
      id: 'bs1',
      name: 'Margaux Tailored Blazer',
      price: 325,
      category: 'tops',
      img: IMG('photo-1591047139829-d91aecb6caea', 800),
      badge: 'Bestseller',
      reviews: 412,
      colors: [SW.champagne, SW.deep, SW.black],
      stock: 14,
      status: 'live',
      isBest: true,
      sizes: SIZES,
    },
    {
      id: 'bs2',
      name: 'Adele Bias Maxi Dress',
      price: 368,
      category: 'dresses',
      img: IMG('photo-1539008835657-9e8e9680c956', 800),
      badge: 'Most loved',
      reviews: 587,
      colors: [SW.blush, SW.ivory, SW.rose],
      stock: 11,
      status: 'live',
      isBest: true,
      sizes: SIZES,
    },
    {
      id: 'bs3',
      name: 'Camille Cashmere Knit',
      price: 285,
      category: 'tops',
      img: IMG('photo-1583744946564-b52ac1c389c8', 800),
      badge: 'Restocked',
      reviews: 298,
      colors: [SW.champagne, SW.sand, SW.rose],
      stock: 22,
      status: 'live',
      isBest: true,
      sizes: SIZES,
    },
    {
      id: 'bs4',
      name: 'Juliette Pearl Cardigan',
      price: 248,
      category: 'tops',
      img: IMG('photo-1551488831-00ddcb6c6bd3', 800),
      badge: 'Bestseller',
      reviews: 341,
      colors: [SW.ivory, SW.blush],
      stock: 6,
      status: 'live',
      isBest: true,
      sizes: SIZES,
    },
    {
      id: 'ex1',
      name: 'Noor Pearl Earrings',
      price: 88,
      category: 'accessories',
      img: IMG('photo-1535632787350-4e68ef0ac584', 700),
      colors: [SW.ivory, SW.champagne],
      stock: 31,
      status: 'live',
      sizes: ['One size'],
    },
    {
      id: 'ex2',
      name: 'Ophelia Silk Scarf',
      price: 68,
      category: 'accessories',
      img: IMG('photo-1606760227091-3dd870d97f1d', 700),
      colors: [SW.blush, SW.rose],
      stock: 33,
      status: 'live',
      sizes: ['One size'],
    },
    {
      id: 'ex3',
      name: 'Quilted Mini Bag',
      price: 248,
      category: 'accessories',
      img: IMG('photo-1584917865442-de89df76afd3', 700),
      colors: [SW.champagne, SW.deep],
      stock: 8,
      status: 'live',
      sizes: ['One size'],
    },
  ],
  instagram: [
    IMG('photo-1485968579580-b6d095142e6e', 600),
    IMG('photo-1483985988355-763728e1935b', 600),
    LOCAL_EDITORIAL,
    IMG('photo-1503342217505-b0a15ec3261c', 600),
  ],
};

const SITE_DATA_KEY = 'roudaina.siteData.v1';
const ADMIN_SESSION_KEY = 'roudaina.admin.session.v1';

const deepClone = (value) => JSON.parse(JSON.stringify(value));
const slugify = (value) => String(value || '')
  .toLowerCase()
  .normalize('NFD')
  .replace(/[\u0300-\u036f]/g, '')
  .replace(/[^a-z0-9]+/g, '-')
  .replace(/^-+|-+$/g, '');

function normalizeSiteData(raw) {
  const site = deepClone(raw || DEFAULT_SITE_DATA);
  site.categories = (site.categories || []).map((category) => ({
    ...category,
    status: category.status || 'live',
    subcategories: (category.subcategories || []).map((sub) => ({
      ...sub,
      href: sub.href || `#shop/${sub.id}`,
    })),
  }));
  site.products = (site.products || []).map((product) => ({
    status: 'live',
    stock: 0,
    description:
      'Cut from feather-light silk satin, this piece drapes effortlessly with a bias-cut silhouette that moves with you.',
    sizes: SIZES,
    slug: product.slug || slugify(product.name || product.id),
    ...product,
  }));
  return site;
}

const defaultSiteData = normalizeSiteData(DEFAULT_SITE_DATA);

function mapApiToSiteData(api) {
  const s = api.settings || {};
  // Strip leftover placeholder branding ("Roudaina") and any production-house wording
  // ("couture", "maison") — House of Sheylas is a curated boutique that sells, not produces.
  const clean = (value, fallback) =>
    (!value || /roudaina|couture|maison/i.test(value)) ? fallback : value;
  const D = defaultSiteData.settings;
  return {
    settings: {
      brandName:        clean(s.brand_name,    D.brandName),
      brandMark:        /roudaina/i.test(s.brand_mark || '') ? D.brandMark : (s.brand_mark || D.brandMark),
      brandTagline:     clean(s.brand_tagline,  D.brandTagline),
      tagline:          clean(s.tagline,        D.tagline),
      supportEmail:     /roudaina/i.test(s.support_email || '') ? D.supportEmail : (s.support_email || D.supportEmail),
      pressEmail:       /roudaina/i.test(s.press_email || '')   ? D.pressEmail   : (s.press_email || D.pressEmail),
      phone:            s.phone             || D.phone,
      instagramHandle:  /roudaina/i.test(s.instagram_handle || '') ? D.instagramHandle : (s.instagram_handle || D.instagramHandle),
      instagramUrl:     /roudaina/i.test(s.instagram_url || '') ? D.instagramUrl : (s.instagram_url || D.instagramUrl),
      tiktokUrl:        s.tiktok_url        || D.tiktokUrl,
      facebookUrl:      s.facebook_url      || D.facebookUrl,
      pinterestUrl:     s.pinterest_url     || D.pinterestUrl,
      newsletterCode:   D.newsletterCode,
      newsletterReplyTo: D.newsletterReplyTo,
      adminUsername:    D.adminUsername,
      adminPassword:    D.adminPassword,
      // Multi-currency (product prices are stored in baseCurrency; convert for display)
      baseCurrency:      s.base_currency || 'CAD',
      currencyRates:     (s.currency_rates && typeof s.currency_rates === 'object' && Object.keys(s.currency_rates).length) ? s.currency_rates : { USD: 0.73, EUR: 0.68, TND: 2.30 },
      enabledCurrencies: (Array.isArray(s.enabled_currencies) && s.enabled_currencies.length) ? s.enabled_currencies : ['CAD', 'EUR', 'USD', 'TND'],
    },
    homepage: (s.homepage_content && typeof s.homepage_content === 'object') ? s.homepage_content : {},
    hero: {
      eyebrow:     s.hero_eyebrow     || defaultSiteData.hero.eyebrow,
      title:       s.hero_title       || defaultSiteData.hero.title,
      accent:      s.hero_accent      || defaultSiteData.hero.accent,
      description: s.hero_description || defaultSiteData.hero.description,
    },
    story: {
      title:          s.story_title          || defaultSiteData.story.title,
      accent:         s.story_accent         || defaultSiteData.story.accent,
      end:            s.story_end            || defaultSiteData.story.end,
      body:           s.story_body           || defaultSiteData.story.body,
      imagePrimary:   defaultSiteData.story.imagePrimary,
      imageSecondary: defaultSiteData.story.imageSecondary,
    },
    categories:  (api.categories  || []).map(c => ({ ...c, subcategories: [] })),
    products:    (api.products     || []).map(p => ({ ...p, sizes: p.sizes || SIZES })),
    collections:  api.collections  || defaultSiteData.collections,
    newArrivals:  api.newArrivals  || [],
    bestSellers:  api.bestSellers  || [],
    services:     api.services     || defaultSiteData.services,
    faqs:         api.faqs         || defaultSiteData.faqs,
    locations:    api.locations    || defaultSiteData.locations,
    pages: (api.pages || []).map(p => ({
      id: p.slug, title: p.title, href: `#${p.slug}`, status: p.status,
    })),
    instagram:  defaultSiteData.instagram,
    newsletter: defaultSiteData.newsletter,
    about:      defaultSiteData.about,
    contact:    defaultSiteData.contact,
    navigation: defaultSiteData.navigation,
  };
}

let HERO_VIDEOS = [
  {
    id: 'walk',
    label: 'Walking to camera',
    src: PEXVID('12719017', 'uhd_1440_2560_60fps'),
    poster: PEXPOSTER('12719017'),
  },
  {
    id: 'turn',
    label: 'Turning away',
    src: PEXVID('12719021', 'uhd_1440_2560_60fps'),
    poster: PEXPOSTER('12719021'),
  },
  {
    id: 'garden',
    label: 'Garden walkway',
    src: PEXVID('12719019', 'uhd_1440_2560_60fps'),
    poster: PEXPOSTER('12719019'),
  },
];
let HERO_VIDEO = HERO_VIDEOS[0].src;
let HERO_VIDEO_POSTER = HERO_VIDEOS[0].poster;
let HERO_MAIN = IMG('photo-1490481651871-ab68de25d43d', 1400);
let HERO_ACCENT = IMG('photo-1469334031218-e382a71b716b', 900);
let STORY_IMG_1 = IMG('photo-1496747611176-843222e1e57c', 900);
let STORY_IMG_2 = LOCAL_EDITORIAL;
let SITE_SETTINGS = defaultSiteData.settings;
let PAGE_CONTENT = defaultSiteData.pages;
let HERO_SECTION = defaultSiteData.hero;
let BRAND_STORY_SECTION = defaultSiteData.story;
let NEWSLETTER_SECTION = defaultSiteData.newsletter;
let ABOUT_CONTENT = defaultSiteData.about;
let CONTACT_CONTENT = defaultSiteData.contact;
let LOCATIONS = defaultSiteData.locations;
let SERVICES = defaultSiteData.services;
let CATEGORIES = defaultSiteData.categories;
let COLLECTIONS = defaultSiteData.collections;
let INSTAGRAM = defaultSiteData.instagram;
let ALL_PRODUCTS = defaultSiteData.products;
let NEW_ARRIVALS = ALL_PRODUCTS.filter((product) => product.isNew);
let BEST_SELLERS = ALL_PRODUCTS.filter((product) => product.isBest);
let EXTRA = ALL_PRODUCTS.filter((product) => !product.isNew && !product.isBest);
let COPY = {
  description:
    'Cut from feather-light silk satin, this piece drapes effortlessly with a bias-cut silhouette that moves with you. Adjustable straps and a softly cowled neckline make it as elegant for evenings out as it is layered beneath knits.',
  fabric: '100% mulberry silk · Dry clean only',
  fit: "True to size · Model is 5'9\" wearing size S",
  shipping: 'Worldwide shipping · Calculated at checkout',
};

function syncSiteGlobals(site) {
  SITE_SETTINGS = site.settings;
  PAGE_CONTENT = site.pages;
  HERO_SECTION = site.hero;
  BRAND_STORY_SECTION = site.story;
  NEWSLETTER_SECTION = site.newsletter;
  ABOUT_CONTENT = site.about;
  CONTACT_CONTENT = site.contact;
  LOCATIONS = site.locations;
  SERVICES = site.services;
  CATEGORIES = site.categories;
  COLLECTIONS = site.collections;
  INSTAGRAM = site.instagram;
  ALL_PRODUCTS = site.products;
  NEW_ARRIVALS = ALL_PRODUCTS.filter((product) => product.isNew);
  BEST_SELLERS = ALL_PRODUCTS.filter((product) => product.isBest);
  EXTRA = ALL_PRODUCTS.filter((product) => !product.isNew && !product.isBest);
  STORY_IMG_1 = site.story.imagePrimary || STORY_IMG_1;
  STORY_IMG_2 = site.story.imageSecondary || STORY_IMG_2;

  Object.assign(window, {
    IMG,
    SW,
    SIZES,
    HERO_MAIN,
    HERO_ACCENT,
    HERO_VIDEO,
    HERO_VIDEO_POSTER,
    HERO_VIDEOS,
    STORY_IMG_1,
    STORY_IMG_2,
    SITE_SETTINGS,
    PAGE_CONTENT,
    HERO_SECTION,
    BRAND_STORY_SECTION,
    NEWSLETTER_SECTION,
    ABOUT_CONTENT,
    CONTACT_CONTENT,
    LOCATIONS,
    SERVICES,
    CATEGORIES,
    COLLECTIONS,
    INSTAGRAM,
    ALL_PRODUCTS,
    NEW_ARRIVALS,
    BEST_SELLERS,
    EXTRA,
    COPY,
  });
}

function getProduct(id) {
  const requested = String(id || '');
  return ALL_PRODUCTS.find((product) =>
    product.id === requested ||
    product.slug === requested ||
    slugify(product.name) === requested
  ) || ALL_PRODUCTS[0];
}

function getCollection(id) {
  return COLLECTIONS.find((collection) => collection.id === id) || COLLECTIONS[0];
}

syncSiteGlobals(defaultSiteData);

const SiteDataCtx = createContext(null);

function loadSiteData() {
  try {
    const raw = localStorage.getItem(SITE_DATA_KEY);
    return raw ? normalizeSiteData(JSON.parse(raw)) : defaultSiteData;
  } catch {
    return defaultSiteData;
  }
}

function SiteDataProvider({ children }) {
  const [siteData, setSiteData] = useState(loadSiteData);

  // Fetch live Supabase data on mount — replaces localStorage/defaults with real content
  useEffect(() => {
    fetch('/api/site-data')
      .then(r => r.json())
      .then(api => {
        if (api.ok && !api.fallback) {
          setSiteData(normalizeSiteData(mapApiToSiteData(api)));
        }
      })
      .catch(() => {});
  }, []);

  useEffect(() => {
    syncSiteGlobals(siteData);
    try {
      localStorage.setItem(SITE_DATA_KEY, JSON.stringify(siteData));
    } catch {}
  }, [siteData]);

  const updateSiteData = useCallback((updater) => {
    setSiteData((current) => normalizeSiteData(typeof updater === 'function' ? updater(current) : updater));
  }, []);

  const resetSiteData = useCallback(() => {
    setSiteData(deepClone(defaultSiteData));
  }, []);

  const value = useMemo(
    () => ({
      siteData,
      updateSiteData,
      resetSiteData,
      defaultSiteData,
    }),
    [siteData, updateSiteData, resetSiteData]
  );

  return <SiteDataCtx.Provider value={value}>{children}</SiteDataCtx.Provider>;
}

function useSiteData() {
  const value = useContext(SiteDataCtx);
  if (!value) throw new Error('useSiteData must be used within SiteDataProvider');
  return value;
}

const AdminAuthCtx = createContext(null);

function AdminAuthProvider({ children }) {
  const { siteData } = useSiteData();
  const [authenticated, setAuthenticated] = useState(() => {
    try {
      return localStorage.getItem(ADMIN_SESSION_KEY) === 'true';
    } catch {
      return false;
    }
  });

  const login = useCallback(
    (username, password) => {
      const ok =
        username === siteData.settings.adminUsername &&
        password === siteData.settings.adminPassword;
      if (ok) {
        setAuthenticated(true);
        try {
          localStorage.setItem(ADMIN_SESSION_KEY, 'true');
        } catch {}
        return { ok: true };
      }
      return { ok: false, error: 'Invalid username or password.' };
    },
    [siteData.settings.adminPassword, siteData.settings.adminUsername]
  );

  const logout = useCallback(() => {
    setAuthenticated(false);
    try {
      localStorage.removeItem(ADMIN_SESSION_KEY);
    } catch {}
  }, []);

  return (
    <AdminAuthCtx.Provider value={{ authenticated, login, logout }}>
      {children}
    </AdminAuthCtx.Provider>
  );
}

function useAdminAuth() {
  const value = useContext(AdminAuthCtx);
  if (!value) throw new Error('useAdminAuth must be used within AdminAuthProvider');
  return value;
}

Object.assign(window, {
  IMG,
  SW,
  SIZES,
  COPY,
  SiteDataProvider,
  useSiteData,
  AdminAuthProvider,
  useAdminAuth,
  ADMIN_SESSION_KEY,
  SITE_SETTINGS,
  PAGE_CONTENT,
  HERO_SECTION,
  BRAND_STORY_SECTION,
  NEWSLETTER_SECTION,
  ABOUT_CONTENT,
  CONTACT_CONTENT,
  LOCATIONS,
  SERVICES,
  CATEGORIES,
  COLLECTIONS,
  INSTAGRAM,
  ALL_PRODUCTS,
  NEW_ARRIVALS,
  BEST_SELLERS,
  EXTRA,
  getProduct,
  getCollection,
  HERO_MAIN,
  HERO_ACCENT,
  HERO_VIDEOS,
  HERO_VIDEO,
  HERO_VIDEO_POSTER,
  STORY_IMG_1,
  STORY_IMG_2,
});
