import { describe, it, expect } from 'vitest'
import {
  SEO_PAGE_TYPES,
  SEO_PAGE_STATUSES,
  SEO_VERTICALS,
  type SeoPage,
  type SeoMetrics,
  type SeoPageContent,
  type SeoFaqItem,
  type SeoInternalLink,
  type SeoLocalData,
  type SeoAiCitations,
  type SeoPageRow,
  type SeoPageInsert,
  type SeoMetricsRow,
  type SeoMetricsInsert
} from '../types'

// =============================================================================
// Constants
// =============================================================================

describe('SEO_PAGE_TYPES', () => {
  it('contains all 5 page types', () => {
    expect(SEO_PAGE_TYPES).toHaveLength(5)
    expect(SEO_PAGE_TYPES).toContain('location')
    expect(SEO_PAGE_TYPES).toContain('use-case')
    expect(SEO_PAGE_TYPES).toContain('comparison')
    expect(SEO_PAGE_TYPES).toContain('pillar')
    expect(SEO_PAGE_TYPES).toContain('cluster')
  })

  it('is readonly', () => {
    // Ensure the array is typed as readonly
    const types: readonly string[] = SEO_PAGE_TYPES
    expect(types).toBeDefined()
  })
})

describe('SEO_PAGE_STATUSES', () => {
  it('contains all 4 statuses', () => {
    expect(SEO_PAGE_STATUSES).toHaveLength(4)
    expect(SEO_PAGE_STATUSES).toContain('draft')
    expect(SEO_PAGE_STATUSES).toContain('review')
    expect(SEO_PAGE_STATUSES).toContain('published')
    expect(SEO_PAGE_STATUSES).toContain('stale')
  })
})

describe('SEO_VERTICALS', () => {
  it('contains all 9 verticals', () => {
    expect(SEO_VERTICALS).toHaveLength(9)
    expect(SEO_VERTICALS).toContain('veterinary-clinics')
    expect(SEO_VERTICALS).toContain('auto-repair')
    expect(SEO_VERTICALS).toContain('home-services')
    expect(SEO_VERTICALS).toContain('hvac-contractors')
    expect(SEO_VERTICALS).toContain('pest-control')
    expect(SEO_VERTICALS).toContain('commercial-cleaning')
    expect(SEO_VERTICALS).toContain('med-spas')
    expect(SEO_VERTICALS).toContain('hoa-property-management')
    expect(SEO_VERTICALS).toContain('security-companies')
  })
})

// =============================================================================
// Type Compatibility (compile-time checks exercised at runtime)
// =============================================================================

describe('SeoPage domain type', () => {
  const validPage: SeoPage = {
    id: '00000000-0000-0000-0000-000000000001',
    organizationId: '00000000-0000-0000-0000-000000000002',
    pageType: 'pillar',
    vertical: 'veterinary-clinics',
    city: null,
    state: null,
    useCase: null,
    slug: 'ai-automation/veterinary-clinics',
    title: 'AI Automation for Veterinary Clinics',
    metaDescription: 'Test description',
    content: {
      hero: 'AI automation helps veterinary clinics reduce no-shows.',
      solution: 'End-to-end AI workflow automation.'
    },
    faqItems: [{ question: 'How much?', answer: '$500-2000/mo' }],
    schemaMarkup: { '@context': 'https://schema.org', '@type': 'Service' },
    localData: null,
    internalLinks: [{ slug: 'ai-automation/veterinary-clinics/irvine', anchor_text: 'Irvine' }],
    status: 'published',
    publishedAt: new Date(),
    refreshedAt: null,
    createdAt: new Date(),
    updatedAt: new Date()
  }

  it('accepts a valid pillar page', () => {
    expect(validPage.pageType).toBe('pillar')
    expect(validPage.vertical).toBe('veterinary-clinics')
    expect(validPage.status).toBe('published')
  })

  it('accepts a location page with city/state', () => {
    const locationPage: SeoPage = {
      ...validPage,
      pageType: 'location',
      city: 'irvine',
      state: 'CA',
      slug: 'ai-automation/veterinary-clinics/irvine',
      localData: {
        business_count: 45,
        city_population: 310000,
        median_household_income: 113144
      }
    }
    expect(locationPage.city).toBe('irvine')
    expect(locationPage.localData?.business_count).toBe(45)
  })

  it('accepts a use-case page with useCase field', () => {
    const useCasePage: SeoPage = {
      ...validPage,
      pageType: 'use-case',
      useCase: 'ai-scheduling',
      slug: 'solutions/ai-scheduling/veterinary-clinics'
    }
    expect(useCasePage.useCase).toBe('ai-scheduling')
  })

  it('accepts all page type values', () => {
    for (const pageType of SEO_PAGE_TYPES) {
      const page: SeoPage = { ...validPage, pageType }
      expect(page.pageType).toBe(pageType)
    }
  })

  it('accepts all status values', () => {
    for (const status of SEO_PAGE_STATUSES) {
      const page: SeoPage = { ...validPage, status }
      expect(page.status).toBe(status)
    }
  })

  it('accepts all vertical values', () => {
    for (const vertical of SEO_VERTICALS) {
      const page: SeoPage = { ...validPage, vertical }
      expect(page.vertical).toBe(vertical)
    }
  })
})

describe('SeoMetrics domain type', () => {
  const validMetrics: SeoMetrics = {
    id: '00000000-0000-0000-0000-000000000003',
    organizationId: '00000000-0000-0000-0000-000000000002',
    seoPageId: '00000000-0000-0000-0000-000000000001',
    period: '2026-03-22',
    impressions: 150,
    clicks: 12,
    ctr: 0.08,
    avgPosition: 8.3,
    ctaClicks: 5,
    formSubmissions: 2,
    scroll25: 100,
    scroll50: 75,
    scroll75: 40,
    scroll100: 20,
    aiCitations: { chatgpt: 2, perplexity: 1, google_aio: 3, gemini: 0, copilot: 1 },
    qualityScore: 85,
    wordCount: 1200,
    faqCount: 6,
    dataPointCount: 4,
    readability: 8.5,
    createdAt: new Date()
  }

  it('accepts valid metrics with all fields', () => {
    expect(validMetrics.period).toBe('2026-03-22')
    expect(validMetrics.clicks).toBe(12)
    expect(validMetrics.aiCitations?.chatgpt).toBe(2)
  })

  it('accepts metrics with nullable fields as null', () => {
    const sparseMetrics: SeoMetrics = {
      ...validMetrics,
      impressions: null,
      clicks: null,
      ctr: null,
      avgPosition: null,
      ctaClicks: null,
      formSubmissions: null,
      scroll25: null,
      scroll50: null,
      scroll75: null,
      scroll100: null,
      aiCitations: null,
      qualityScore: null,
      wordCount: null,
      faqCount: null,
      dataPointCount: null,
      readability: null
    }
    expect(sparseMetrics.impressions).toBeNull()
    expect(sparseMetrics.aiCitations).toBeNull()
  })
})

// =============================================================================
// Supporting Types
// =============================================================================

describe('SeoPageContent', () => {
  it('requires hero field', () => {
    const content: SeoPageContent = { hero: 'AI automation helps...' }
    expect(content.hero).toBeDefined()
  })

  it('accepts all optional fields', () => {
    const content: SeoPageContent = {
      hero: 'AI automation helps...',
      market_context: 'The U.S. market...',
      local_challenges: 'High rents...',
      solution: 'Elevasis provides...',
      problem: 'Average clinic receives 50 calls/day...',
      how_it_works: [{ step: 1, title: 'Request', description: 'Client requests appointment' }],
      use_cases: [{ title: 'Scheduling', description: 'AI handles booking' }],
      results: '60-70% reduction in calls',
      methodology: 'Based on aggregated data',
      baseline_assumptions: { avg_daily_calls: 50 },
      typical_results: { phone_time_saved_hrs_month: 50 },
      cta: 'Book a free consultation'
    }
    expect(content.use_cases).toHaveLength(1)
    expect(content.how_it_works?.[0]?.step).toBe(1)
  })
})

describe('SeoFaqItem', () => {
  it('has question and answer', () => {
    const faq: SeoFaqItem = { question: 'How much?', answer: '$500-2000/mo' }
    expect(faq.question).toBeDefined()
    expect(faq.answer).toBeDefined()
  })
})

describe('SeoInternalLink', () => {
  it('has slug and anchor_text', () => {
    const link: SeoInternalLink = { slug: 'ai-automation/veterinary-clinics', anchor_text: 'Vet Clinics' }
    expect(link.slug).toBeDefined()
    expect(link.anchor_text).toBeDefined()
  })
})

describe('SeoLocalData', () => {
  it('accepts known fields', () => {
    const data: SeoLocalData = {
      business_count: 450,
      metro: 'Los Angeles-Long Beach-Anaheim MSA',
      median_household_income: 100485,
      source: 'U.S. Census Bureau ACS 2024'
    }
    expect(data.business_count).toBe(450)
    expect(data.metro).toBe('Los Angeles-Long Beach-Anaheim MSA')
  })

  it('accepts arbitrary string/number fields via index signature', () => {
    const data: SeoLocalData = {
      business_count: 450,
      custom_stat: 42,
      custom_label: 'something'
    }
    expect(data.custom_stat).toBe(42)
    expect(data.custom_label).toBe('something')
  })
})

describe('SeoAiCitations', () => {
  it('accepts all platform fields', () => {
    const citations: SeoAiCitations = {
      chatgpt: 3,
      perplexity: 1,
      google_aio: 5,
      gemini: 0,
      copilot: 2
    }
    expect(citations.chatgpt).toBe(3)
    expect(citations.copilot).toBe(2)
  })

  it('accepts partial data', () => {
    const citations: SeoAiCitations = { perplexity: 1 }
    expect(citations.perplexity).toBe(1)
    expect(citations.chatgpt).toBeUndefined()
  })
})

// =============================================================================
// Subpath Export
// =============================================================================

describe('@repo/core/seo subpath export', () => {
  it('re-exports all constants', async () => {
    const seo = await import('../index')
    expect(seo.SEO_PAGE_TYPES).toBeDefined()
    expect(seo.SEO_PAGE_STATUSES).toBeDefined()
    expect(seo.SEO_VERTICALS).toBeDefined()
  })
})

// =============================================================================
// Database Row Type Compatibility
// =============================================================================

describe('SeoPageRow compatibility', () => {
  it('matches database schema shape', () => {
    // Simulate a row as it would come from Supabase
    const row: SeoPageRow = {
      id: '00000000-0000-0000-0000-000000000001',
      organization_id: '00000000-0000-0000-0000-000000000002',
      page_type: 'pillar',
      vertical: 'veterinary-clinics',
      city: null,
      state: null,
      use_case: null,
      slug: 'ai-automation/veterinary-clinics',
      title: 'AI Automation for Veterinary Clinics',
      meta_description: null,
      content: null,
      faq_items: null,
      schema_markup: null,
      local_data: null,
      internal_links: null,
      status: 'draft',
      published_at: null,
      refreshed_at: null,
      created_at: '2026-03-22T00:00:00Z',
      updated_at: '2026-03-22T00:00:00Z'
    }
    expect(row.organization_id).toBeDefined()
    expect(row.page_type).toBe('pillar')
  })
})

describe('SeoPageInsert compatibility', () => {
  it('requires only mandatory fields', () => {
    const insert: SeoPageInsert = {
      organization_id: '00000000-0000-0000-0000-000000000002',
      page_type: 'location',
      vertical: 'hvac-contractors',
      slug: 'ai-automation/hvac-contractors/los-angeles',
      title: 'AI Automation for HVAC Contractors in Los Angeles'
    }
    expect(insert.organization_id).toBeDefined()
    expect(insert.slug).toBeDefined()
    // Optional fields should be absent
    expect(insert.city).toBeUndefined()
    expect(insert.content).toBeUndefined()
  })
})

describe('SeoMetricsRow compatibility', () => {
  it('matches database schema shape', () => {
    const row: SeoMetricsRow = {
      id: '00000000-0000-0000-0000-000000000003',
      organization_id: '00000000-0000-0000-0000-000000000002',
      seo_page_id: '00000000-0000-0000-0000-000000000001',
      period: '2026-03-22',
      impressions: null,
      clicks: null,
      ctr: null,
      avg_position: null,
      cta_clicks: null,
      form_submissions: null,
      scroll_25: null,
      scroll_50: null,
      scroll_75: null,
      scroll_100: null,
      ai_citations: null,
      quality_score: null,
      word_count: null,
      faq_count: null,
      data_point_count: null,
      readability: null,
      created_at: '2026-03-22T00:00:00Z'
    }
    expect(row.seo_page_id).toBeDefined()
    expect(row.period).toBe('2026-03-22')
  })
})

describe('SeoMetricsInsert compatibility', () => {
  it('requires only mandatory fields', () => {
    const insert: SeoMetricsInsert = {
      organization_id: '00000000-0000-0000-0000-000000000002',
      seo_page_id: '00000000-0000-0000-0000-000000000001',
      period: '2026-03-22'
    }
    expect(insert.organization_id).toBeDefined()
    expect(insert.seo_page_id).toBeDefined()
    expect(insert.period).toBe('2026-03-22')
    // Optional fields should be absent
    expect(insert.clicks).toBeUndefined()
    expect(insert.ai_citations).toBeUndefined()
  })
})
