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

vi.mock('@/components/ui/Toast', () => ({
  useToast: () => ({ toast: vi.fn() }),
}))

vi.mock('@/lib/api/agent', () => ({
  getMe: vi.fn(),
  getStoreSettings: vi.fn(),
  selectStoreTemplate: vi.fn(),
  updateStoreContent: vi.fn(),
  publishStore: vi.fn(),
}))

import { getMe, getStoreSettings, selectStoreTemplate } from '@/lib/api/agent'
import StorePage from '@/app/dashboard/store/page'

function meData(role: 'admin' | 'stock_keeper' | null) {
  return {
    success: true as const,
    data: {
      user_id: 'u-1', email: 'demo@imbaraga.rw', full_name: 'Admin A',
      status: 'active', business_id: 'b-1',
      business_name: 'Kigali Smart Supplies',
      business_slug: 'kigali-smart-supplies', role,
    },
  }
}

const settingsResult = {
  success: true as const,
  data: {
    template_id: 'modern-retail',
    published: true,
    config: {},
    slug: 'kigali-smart-supplies',
    readiness: {
      template_id: 'modern-retail',
      template_known: true,
      ready_to_publish: false,
      missing_required: ['Business logo'],
      required_checks: [
        { key: 'name', label: 'Business name', met: true },
        { key: 'logo', label: 'Business logo', met: false },
      ],
      optional_content: [{ key: 'testimonials', label: 'Testimonials', present: false }],
      catalog_stats: { published_products: 2, categories: 1, products_with_images: 0 },
    },
  },
}

beforeEach(() => {
  vi.clearAllMocks()
})

describe('Dashboard StorePage (template library)', () => {
  it('admin sees current template, readiness gaps and the full library', async () => {
    vi.mocked(getMe).mockResolvedValue(meData('admin') as never)
    vi.mocked(getStoreSettings).mockResolvedValue(settingsResult as never)
    render(<StorePage />)
    expect(await screen.findByText(/Your Storefront/i, {}, { timeout: 12000 })).toBeInTheDocument()
    expect(screen.getAllByText(/Modern Retail/).length).toBeGreaterThan(0)
    // readiness gap surfaced honestly
    expect(screen.getByText(/1 more item/i)).toBeInTheDocument()
    expect(screen.getAllByText(/Business logo/).length).toBeGreaterThan(0)
    // all 20 library cards
    for (const name of ['Tech Store', 'Luxury', 'Signature Premium', 'Local Market']) {
      expect(screen.getAllByText(new RegExp(name, 'i')).length).toBeGreaterThan(0)
    }
    const previews = screen.getAllByRole('link', { name: /^preview$/i })
    expect(previews.length).toBeGreaterThanOrEqual(20)
    expect(previews[0].getAttribute('href')).toContain('/shop/kigali-smart-supplies?preview=')
  }, 15000)

  it('keeper cannot access the store manager', async () => {
    vi.mocked(getMe).mockResolvedValue(meData('stock_keeper') as never)
    render(<StorePage />)
    expect(await screen.findByText(/admin access required/i)).toBeInTheDocument()
    expect(getStoreSettings).not.toHaveBeenCalled()
  })

  it('Use Template persists selection via API and refreshes settings', async () => {
    vi.mocked(getMe).mockResolvedValue(meData('admin') as never)
    vi.mocked(getStoreSettings).mockResolvedValue(settingsResult as never)
    vi.mocked(selectStoreTemplate).mockResolvedValue({
      success: true,
      data: { template_id: 'tech-store', previous_template: 'modern-retail', changed: true, published: true },
    } as never)
    render(<StorePage />)
    const useButtons = await screen.findAllByRole('button', { name: /use template/i })
    fireEvent.click(useButtons[0])
    await waitFor(() => expect(selectStoreTemplate).toHaveBeenCalled())
    const calledId = vi.mocked(selectStoreTemplate).mock.calls[0][0]
    expect(calledId).toMatch(
      /^(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)$/,
    )
  })
})
