import { describe, it, expect, vi } from 'vitest'
import { render, screen } from '@testing-library/react'

import {
  STORE_TEMPLATES,
  getStoreTemplate,
  resolvePaletteVars,
} from '@/lib/storefront/templates'

const EXPECTED_IDS = [
  'modern-retail', 'african-premium', 'minimal-business', 'luxury',
  'bold-commerce', 'local-market', 'tech-store', 'fashion-boutique',
  'coffee-food', 'beauty-wellness', 'furniture-interiors',
  'construction-industrial', 'agriculture-farm', 'professional-services',
  'marketplace-style', 'storytelling', 'mobile-first', 'startup-modern',
  'community-trust', 'signature-premium',
]

describe('storefront template registry', () => {
  it('contains exactly the 20 approved unique template ids', () => {
    expect(STORE_TEMPLATES).toHaveLength(20)
    expect(new Set(STORE_TEMPLATES.map(t => t.id)).size).toBe(20)
    expect(STORE_TEMPLATES.map(t => t.id).sort()).toEqual([...EXPECTED_IDS].sort())
  })

  it('every template declares tokens, palette, version, sections and bestFor', () => {
    const validSections = ['promo','hero','categories','featured','products','about','story',
      'services','stats','gallery','testimonials','faq','trust','contact']
    for (const t of STORE_TEMPLATES) {
      expect(t.version).toBeTruthy()
      expect(t.required.length).toBeGreaterThan(0)
      expect(t.sections.length).toBeGreaterThan(0)
      expect(t.bestFor.length).toBeGreaterThan(0)
      expect(t.tokens.productGrid).toBeTruthy()
      expect(t.tokens.hero).toBeTruthy()
      expect(t.palette.primary).toMatch(/^#/)
      for (const s of [...t.optional, ...t.sections]) {
        expect(validSections).toContain(s)
      }
    }
  })

  it('brand colors override template palettes; unknown ids fall back safely', () => {
    const t = getStoreTemplate('tech-store')
    const vars = resolvePaletteVars(t, '#123456', '#F5A623')
    expect(vars['--store-primary']).toBe('#123456')
    expect(vars['--store-accent']).toBe('#F5A623')
    const fallback = resolvePaletteVars(t, null, null)
    expect(fallback['--store-primary']).toBe(t.palette.primary)
    expect(getStoreTemplate('nope').id).toBe('modern-retail')
  })
})

vi.mock('@/lib/cart', () => ({
  useCart: () => ({ addItem: vi.fn(), itemCount: 0 }),
}))

import { StorefrontRenderer } from '@/components/storefront/StorefrontRenderer'

const business = {
  slug: 'kigali-smart-supplies',
  name: 'Kigali Smart Supplies',
  description: 'Quality technology supplies for Kigali businesses.',
  logo_url: null,
  hero_title: 'Quality Technology',
  hero_subtitle: 'Fast delivery across Kigali.',
  brand_color: '#2563eb',
  address: 'KN 4 Ave, Kigali',
  whatsapp: '+250788000001',
  website_url: null,
}

const products = [
  { id: 'p1', name: 'Wireless Mouse', public_slug: 'wireless-mouse',
    category: 'Accessories', description: '2.4GHz wireless mouse.',
    unit_price: 15000, image_url: null, available_quantity: 12, status: 'available' },
  { id: 'p2', name: 'USB-C Hub', public_slug: 'usb-c-hub',
    category: 'Accessories', description: '7-in-1 hub.',
    unit_price: 32000, image_url: null, available_quantity: 3, status: 'available' },
]

describe('StorefrontRenderer — all 20 templates render real data', () => {
  it.each(STORE_TEMPLATES.map(t => [t.name, t]))(
    'renders %s',
    (_name, t) => {
      const { container } = render(
        <StorefrontRenderer
          template={t}
          business={business}
          content={{}}
          products={products}
          currency="RWF"
        />,
      )
      const root = container.querySelector('[data-store-template]')
      expect(root?.getAttribute('data-store-template')).toBe(t.id)
      expect(container.textContent).toContain('Kigali Smart Supplies')
      expect(container.textContent).toContain('Wireless Mouse')
      expect(container.textContent).toContain('Powered by IMBARAGA')
      expect(container.textContent).not.toContain('[Preview]')
      expect(screen.queryByText(/dashboard/i)).not.toBeInTheDocument()
    },
  )

  it('different templates produce different presentations', () => {
    const a = render(<StorefrontRenderer template={STORE_TEMPLATES[0]} business={business} content={{}} products={products} currency="RWF" />)
    const b = render(<StorefrontRenderer template={getStoreTemplate('luxury')} business={business} content={{}} products={products} currency="RWF" />)
    expect(a.container.querySelector('[data-store-template]')?.getAttribute('data-store-template')).toBe('modern-retail')
    expect(b.container.querySelector('[data-store-template]')?.getAttribute('data-store-template')).toBe('luxury')
  })

  it('missing optional content never breaks the customer page', () => {
    const storytelling = getStoreTemplate('storytelling')
    const { container } = render(
      <StorefrontRenderer template={storytelling} business={business} content={{}} products={[]} currency="RWF" />,
    )
    expect(container.textContent).toContain('Kigali Smart Supplies')
    expect(container.textContent).not.toContain('[Preview]')
  })

  it('admin previews show marked placeholders instead of invented data', () => {
    const coffee = getStoreTemplate('coffee-food')
    const { container } = render(
      <StorefrontRenderer template={coffee} business={business} content={{}} products={products} currency="RWF" previewMode />,
    )
    expect(container.textContent).toContain('[Preview]')
  })
})

describe('Gate 10B — real storefront design system', () => {
  it('every template resolves on-primary / muted / border composition vars', () => {
    for (const t of STORE_TEMPLATES) {
      const vars = resolvePaletteVars(t, '#123456', '#F5A623')
      expect(vars['--store-primary']).toBe('#123456')
      expect(String(vars['--store-on-primary'])).toMatch(/^(#|white|color-mix)/)
      expect(vars['--store-muted']).toBeTruthy()
      expect(vars['--store-border']).toBeTruthy()
    }
  })

  it('renders real business identity (nav wordmark, footer copyright) for all 20', () => {
    const year = String(new Date().getFullYear())
    for (const t of STORE_TEMPLATES) {
      const { container, unmount } = render(
        <StorefrontRenderer template={t} business={business} content={{}} products={products} currency="RWF" />,
      )
      expect(container.textContent).toContain('Kigali Smart Supplies')
      expect(container.textContent).toContain(`© ${year} Kigali Smart Supplies`)
      unmount()
    }
  })

  it('navigation derives from actually-available data (no dead links)', () => {
    // Full data: Home + Products + Categories + About + Contact
    const { container } = render(
      <StorefrontRenderer template={getStoreTemplate('modern-retail')} business={business} content={{}} products={products} currency="RWF" />,
    )
    const nav = container.querySelector('nav[aria-label="Main navigation"]')
    expect(nav?.textContent).toContain('Products')
    expect(nav?.textContent).toMatch(/Categor/)
    expect(nav?.textContent).toContain('About')
    expect(nav?.textContent).toContain('Contact')

    // Sparse business: only Home (+ Products when products exist); no About/Contact links
    const sparse = {
      slug: 'sparse', name: 'Sparse Shop', description: null,
      phone: null, email: null, logo_url: null, brand_color: null,
      address: null, whatsapp: null, website_url: null,
    }
    const bare = render(
      <StorefrontRenderer template={getStoreTemplate('minimal-business')} business={sparse} content={{}} products={[]} currency="USD" />,
    )
    const bareNav = bare.container.querySelector('nav[aria-label="Main navigation"]')
    expect(bareNav?.textContent).not.toContain('About')
    expect(bareNav?.textContent).not.toContain('Contact')
    expect(bareNav?.textContent).not.toContain('Our Story')
  })

  it('contact actions appear only for contact facts that exist', () => {
    const t = getStoreTemplate('local-market')
    const full = render(<StorefrontRenderer template={t} business={business} content={{}} products={products} currency="RWF" />)
    expect(full.container.textContent).toContain('WhatsApp') // action CTA from real data
    full.unmount()

    const noContact = { ...business, phone: null, whatsapp: null, email: null, address: null, website_url: null }
    const empty = render(<StorefrontRenderer template={t} business={noContact} content={{}} products={products} currency="RWF" />)
    expect(empty.container.textContent).not.toContain('+250788000001')
    expect(empty.container.textContent).not.toContain('WhatsApp')
  })

  it('logo fallback derives from the business name, never IMBARAGA chrome', () => {
    const { container } = render(
      <StorefrontRenderer template={getStoreTemplate('tech-store')} business={business} content={{}} products={products} currency="RWF" />,
    )
    const mark = container.querySelector('header span[aria-hidden]')
    expect(mark?.textContent).toBe('K')
  })

  it('mobile navigation drawer exists alongside desktop links', () => {
    const { container } = render(
      <StorefrontRenderer template={getStoreTemplate('mobile-first')} business={business} content={{}} products={products} currency="RWF" />,
    )
    expect(container.querySelector('button[aria-label="Open menu"]')).toBeTruthy()
    expect(container.querySelector('nav[aria-label="Main navigation"]')).toBeTruthy()
  })

  it('template-specific product card anatomies render', () => {
    const mk = (id: string) =>
      render(<StorefrontRenderer template={getStoreTemplate(id)} business={business} content={{}} products={products} currency="USD" />)

    // tech-store uses spec cards with stock counts
    const tech = mk('tech-store')
    expect(tech.container.textContent).toMatch(/in stock/i)
    tech.unmount()

    // local-market uses practical cards with availability pills
    const market = mk('local-market')
    expect(market.container.textContent).toMatch(/In stock/)
    market.unmount()

    // professional-services uses service-style cards
    const services = mk('professional-services')
    expect(services.container.textContent).toContain('Learn more')
    services.unmount()
  })

  it('footer carries opening hours and socials from config when provided', () => {
    const content = {
      opening_hours: 'Mon–Sat 8:00–18:00',
      social_links: [{ platform: 'Instagram', url: 'https://instagram.com/kigalismart' }],
    }
    const { container } = render(
      <StorefrontRenderer template={getStoreTemplate('fashion-boutique')} business={business} content={content} products={products} currency="RWF" />,
    )
    expect(container.textContent).toContain('Mon–Sat 8:00–18:00')
    expect(container.querySelector('a[aria-label="Instagram"]')?.getAttribute('href')).toBe('https://instagram.com/kigalismart')
  })
})

describe('Gate 10E — business ownership + containment', () => {
  it('Kigali storefront shows business name, not generic Storefront', () => {
    const { container } = render(
      <StorefrontRenderer template={getStoreTemplate('modern-retail')} business={business} content={{}} products={products} currency="RWF" />,
    )
    expect(container.textContent).toContain('Kigali Smart Supplies')
    // customer storefront should not use generic title as primary
    expect(container.textContent).not.toMatch(/^\s*Storefront\s*$/m)
    // header wordmark and footer both contain business name
    expect(container.querySelector('header')?.textContent).toContain('Kigali Smart Supplies')
    expect(container.textContent).toContain('©')
  })

  it('Demo Electronics Rwanda does not render Kigali identity', () => {
    const demoBusiness = { ...business, slug: 'demo-electronics-rwanda', name: 'Demo Electronics Rwanda', description: 'Audio gear', logo_url: null, address: 'KN 3 Rd, Kigali', whatsapp: '+250788000002' }
    const { container } = render(
      <StorefrontRenderer template={getStoreTemplate('modern-retail')} business={demoBusiness} content={{}} products={products} currency="USD" />,
    )
    expect(container.textContent).toContain('Demo Electronics Rwanda')
    expect(container.textContent).not.toContain('Kigali Smart Supplies')
  })

  it('storefront sections use consistent containment (max-w-7xl + gutters)', () => {
    const { container } = render(
      <StorefrontRenderer template={getStoreTemplate('signature-premium')} business={business} content={{ opening_hours: 'Mon–Sat 8:00–18:00', badges: ['Fast delivery'], social_links: [{ platform: 'Instagram', url: 'https://instagram.com/x' }] }} products={products} currency="RWF" />,
    )
    const html = container.innerHTML
    // storefront main now w-full with bg-[var(--store-background)], inner content max-w-7xl + gutters so width matches body
    expect(html).toContain('max-w-7xl')
    expect(html).toContain('px-4')
    expect(html).toContain('sm:px-6')
    expect(html).toContain('lg:px-8')
    // footer should be w-full full-bleed bg with inner max-w-7xl (no visible edge, bg matches body)
    const footer = container.querySelector('footer')
    expect(footer?.className).toContain('w-full')
    expect(footer?.innerHTML).toContain('max-w-7xl')
  })
})
