import { describe, it, expect } from 'vitest'
import { generateInternalLinks, generateAnchorText, getVerticalLabel } from '../linking'
import type { SeoPage } from '../types'

// =============================================================================
// Fixtures
// =============================================================================

const BASE_PAGE: SeoPage = {
  id: '00000000-0000-0000-0000-000000000000',
  organizationId: 'org-1',
  pageType: 'pillar',
  vertical: 'veterinary-clinics',
  city: null,
  state: null,
  useCase: null,
  slug: 'ai-automation/veterinary-clinics',
  title: 'AI Automation for Veterinary Clinics',
  metaDescription: null,
  content: null,
  faqItems: null,
  schemaMarkup: null,
  localData: null,
  internalLinks: null,
  status: 'published',
  publishedAt: new Date('2026-01-01'),
  refreshedAt: null,
  createdAt: new Date('2026-01-01'),
  updatedAt: new Date('2026-01-01')
}

function makePage(overrides: Partial<SeoPage> & { id: string; slug: string }): SeoPage {
  return { ...BASE_PAGE, ...overrides }
}

// Pillar pages for two verticals
const vetPillar = makePage({
  id: 'vet-pillar',
  pageType: 'pillar',
  vertical: 'veterinary-clinics',
  city: null,
  slug: 'ai-automation/veterinary-clinics',
  title: 'AI Automation for Veterinary Clinics'
})

const hvacPillar = makePage({
  id: 'hvac-pillar',
  pageType: 'pillar',
  vertical: 'hvac-contractors',
  city: null,
  slug: 'ai-automation/hvac-contractors',
  title: 'AI Automation for HVAC Contractors'
})

const autoPillar = makePage({
  id: 'auto-pillar',
  pageType: 'pillar',
  vertical: 'auto-repair',
  city: null,
  slug: 'ai-automation/auto-repair',
  title: 'AI Automation for Auto Repair Shops'
})

const pestPillar = makePage({
  id: 'pest-pillar',
  pageType: 'pillar',
  vertical: 'pest-control',
  city: null,
  slug: 'ai-automation/pest-control',
  title: 'AI Automation for Pest Control'
})

// Location pages
const vetIrvine = makePage({
  id: 'vet-irvine',
  pageType: 'location',
  vertical: 'veterinary-clinics',
  city: 'irvine',
  state: 'CA',
  slug: 'ai-automation/veterinary-clinics/irvine',
  title: 'AI Automation for Vet Clinics in Irvine'
})

const vetAnaheim = makePage({
  id: 'vet-anaheim',
  pageType: 'location',
  vertical: 'veterinary-clinics',
  city: 'anaheim',
  state: 'CA',
  slug: 'ai-automation/veterinary-clinics/anaheim',
  title: 'AI Automation for Vet Clinics in Anaheim'
})

const vetLosAngeles = makePage({
  id: 'vet-la',
  pageType: 'location',
  vertical: 'veterinary-clinics',
  city: 'los-angeles',
  state: 'CA',
  slug: 'ai-automation/veterinary-clinics/los-angeles',
  title: 'AI Automation for Vet Clinics in Los Angeles'
})

const vetSantaAna = makePage({
  id: 'vet-santa-ana',
  pageType: 'location',
  vertical: 'veterinary-clinics',
  city: 'santa-ana',
  state: 'CA',
  slug: 'ai-automation/veterinary-clinics/santa-ana',
  title: 'AI Automation for Vet Clinics in Santa Ana'
})

const vetSanDiego = makePage({
  id: 'vet-san-diego',
  pageType: 'location',
  vertical: 'veterinary-clinics',
  city: 'san-diego',
  state: 'CA',
  slug: 'ai-automation/veterinary-clinics/san-diego',
  title: 'AI Automation for Vet Clinics in San Diego'
})

const vetSanFrancisco = makePage({
  id: 'vet-sf',
  pageType: 'location',
  vertical: 'veterinary-clinics',
  city: 'san-francisco',
  state: 'CA',
  slug: 'ai-automation/veterinary-clinics/san-francisco',
  title: 'AI Automation for Vet Clinics in San Francisco'
})

// Cross-vertical location page in same city as vetIrvine
const hvacIrvine = makePage({
  id: 'hvac-irvine',
  pageType: 'location',
  vertical: 'hvac-contractors',
  city: 'irvine',
  state: 'CA',
  slug: 'ai-automation/hvac-contractors/irvine',
  title: 'AI Automation for HVAC Contractors in Irvine'
})

const autoIrvine = makePage({
  id: 'auto-irvine',
  pageType: 'location',
  vertical: 'auto-repair',
  city: 'irvine',
  state: 'CA',
  slug: 'ai-automation/auto-repair/irvine',
  title: 'AI Automation for Auto Repair Shops in Irvine'
})

const pestIrvine = makePage({
  id: 'pest-irvine',
  pageType: 'location',
  vertical: 'pest-control',
  city: 'irvine',
  state: 'CA',
  slug: 'ai-automation/pest-control/irvine',
  title: 'AI Automation for Pest Control in Irvine'
})

// Cluster / use-case pages
const vetScheduling = makePage({
  id: 'vet-scheduling',
  pageType: 'cluster',
  vertical: 'veterinary-clinics',
  useCase: 'ai-scheduling',
  city: null,
  slug: 'solutions/ai-scheduling/veterinary-clinics',
  title: 'AI Scheduling for Vet Clinics'
})

const vetReminders = makePage({
  id: 'vet-reminders',
  pageType: 'use-case',
  vertical: 'veterinary-clinics',
  useCase: 'appointment-reminders',
  city: null,
  slug: 'solutions/appointment-reminders/veterinary-clinics',
  title: 'Appointment Reminders for Vet Clinics'
})

const vetIntake = makePage({
  id: 'vet-intake',
  pageType: 'cluster',
  vertical: 'veterinary-clinics',
  useCase: 'digital-intake',
  city: null,
  slug: 'solutions/digital-intake/veterinary-clinics',
  title: 'Digital Intake for Vet Clinics'
})

// =============================================================================
// Anchor Text
// =============================================================================

describe('getVerticalLabel', () => {
  it('returns known vertical labels', () => {
    expect(getVerticalLabel('veterinary-clinics')).toBe('Vet Clinics')
    expect(getVerticalLabel('hvac-contractors')).toBe('HVAC Contractors')
    expect(getVerticalLabel('hoa-property-management')).toBe('HOA & Property Management')
  })

  it('falls back to title-cased slug for unknown verticals', () => {
    expect(getVerticalLabel('new-vertical-type')).toBe('New Vertical Type')
  })
})

describe('generateAnchorText', () => {
  it('generates pillar anchor text', () => {
    expect(generateAnchorText(vetPillar)).toBe('AI Automation for Vet Clinics')
  })

  it('generates location anchor text with city', () => {
    expect(generateAnchorText(vetIrvine)).toBe('AI Automation for Vet Clinics in Irvine')
  })

  it('generates location anchor text with hyphenated city', () => {
    expect(generateAnchorText(vetLosAngeles)).toBe('AI Automation for Vet Clinics in Los Angeles')
  })

  it('generates cluster anchor text with use-case', () => {
    expect(generateAnchorText(vetScheduling)).toBe('Ai Scheduling for Vet Clinics')
  })

  it('falls back to page title when use-case is missing on cluster page', () => {
    const noUseCase = makePage({
      ...vetScheduling,
      id: 'no-use-case',
      useCase: null,
      slug: 'solutions/misc/veterinary-clinics',
      title: 'Misc Page Title'
    })
    expect(generateAnchorText(noUseCase)).toBe('Misc Page Title')
  })
})

// =============================================================================
// Pillar Page Linking
// =============================================================================

describe('generateInternalLinks — pillar page', () => {
  const allPages = [
    vetPillar,
    hvacPillar,
    autoPillar,
    pestPillar,
    vetIrvine,
    vetAnaheim,
    vetLosAngeles,
    vetScheduling,
    vetReminders,
    vetIntake,
    hvacIrvine
  ]

  it('links to all location pages for its vertical', () => {
    const links = generateInternalLinks(vetPillar, allPages)
    const slugs = links.map((l) => l.slug)

    expect(slugs).toContain(vetIrvine.slug)
    expect(slugs).toContain(vetAnaheim.slug)
    expect(slugs).toContain(vetLosAngeles.slug)
  })

  it('links to all cluster/use-case pages for its vertical', () => {
    const links = generateInternalLinks(vetPillar, allPages)
    const slugs = links.map((l) => l.slug)

    expect(slugs).toContain(vetScheduling.slug)
    expect(slugs).toContain(vetReminders.slug)
    expect(slugs).toContain(vetIntake.slug)
  })

  it('links to up to 3 other vertical pillar pages', () => {
    const links = generateInternalLinks(vetPillar, allPages)
    const otherPillarLinks = links.filter((l) => [hvacPillar.slug, autoPillar.slug, pestPillar.slug].includes(l.slug))
    expect(otherPillarLinks.length).toBeGreaterThanOrEqual(1)
    expect(otherPillarLinks.length).toBeLessThanOrEqual(3)
  })

  it('does not link to itself', () => {
    const links = generateInternalLinks(vetPillar, allPages)
    const slugs = links.map((l) => l.slug)
    expect(slugs).not.toContain(vetPillar.slug)
  })

  it('does not link to location pages from other verticals', () => {
    const links = generateInternalLinks(vetPillar, allPages)
    const slugs = links.map((l) => l.slug)
    expect(slugs).not.toContain(hvacIrvine.slug)
  })

  it('returns an empty list when there are no other pages', () => {
    const links = generateInternalLinks(vetPillar, [vetPillar])
    expect(links).toHaveLength(0)
  })
})

// =============================================================================
// Location Page Linking
// =============================================================================

describe('generateInternalLinks — location page', () => {
  const allPages = [
    vetPillar,
    hvacPillar,
    autoPillar,
    pestPillar,
    vetIrvine,
    vetAnaheim,
    vetLosAngeles,
    vetSantaAna,
    vetSanDiego,
    vetSanFrancisco,
    hvacIrvine,
    autoIrvine,
    pestIrvine,
    vetScheduling,
    vetReminders,
    vetIntake
  ]

  it('links back to its parent pillar page', () => {
    const links = generateInternalLinks(vetIrvine, allPages)
    const slugs = links.map((l) => l.slug)
    expect(slugs).toContain(vetPillar.slug)
  })

  it('links to 3–5 sibling location pages', () => {
    const links = generateInternalLinks(vetIrvine, allPages)
    const siblingLinks = links.filter((l) =>
      [vetAnaheim.slug, vetLosAngeles.slug, vetSantaAna.slug, vetSanDiego.slug, vetSanFrancisco.slug].includes(l.slug)
    )
    expect(siblingLinks.length).toBeGreaterThanOrEqual(3)
    expect(siblingLinks.length).toBeLessThanOrEqual(5)
  })

  it('does not link to itself', () => {
    const links = generateInternalLinks(vetIrvine, allPages)
    const slugs = links.map((l) => l.slug)
    expect(slugs).not.toContain(vetIrvine.slug)
  })

  it('links to cross-vertical pages in the same city', () => {
    const links = generateInternalLinks(vetIrvine, allPages)

    // hvac, auto, and pest all have Irvine pages — up to 3 should appear
    const crossVerticalSlugs = [hvacIrvine.slug, autoIrvine.slug, pestIrvine.slug]
    const crossLinks = links.filter((l) => crossVerticalSlugs.includes(l.slug))
    expect(crossLinks.length).toBeGreaterThanOrEqual(1)
    expect(crossLinks.length).toBeLessThanOrEqual(3)
  })

  it('does not link to cross-vertical pages in a different city', () => {
    // hvacIrvine is in Irvine, vetAnaheim is in Anaheim — no cross link expected for anaheim page to hvacIrvine
    const links = generateInternalLinks(vetAnaheim, allPages)
    const slugs = links.map((l) => l.slug)
    expect(slugs).not.toContain(hvacIrvine.slug)
  })

  it('links to 1–2 cluster pages', () => {
    const links = generateInternalLinks(vetIrvine, allPages)
    const clusterSlugs = [vetScheduling.slug, vetReminders.slug, vetIntake.slug]
    const clusterLinks = links.filter((l) => clusterSlugs.includes(l.slug))
    expect(clusterLinks.length).toBeGreaterThanOrEqual(1)
    expect(clusterLinks.length).toBeLessThanOrEqual(2)
  })

  it('respects sibling limit of 5', () => {
    // 5 sibling pages + many cross-vertical + clusters — ensure siblings are capped at 5
    const links = generateInternalLinks(vetIrvine, allPages)
    const siblingLinks = links.filter((l) =>
      [vetAnaheim.slug, vetLosAngeles.slug, vetSantaAna.slug, vetSanDiego.slug, vetSanFrancisco.slug].includes(l.slug)
    )
    expect(siblingLinks.length).toBeLessThanOrEqual(5)
  })
})

// =============================================================================
// Cluster / Use-case Page Linking
// =============================================================================

describe('generateInternalLinks — cluster/use-case page', () => {
  const allPages = [vetPillar, vetIrvine, vetAnaheim, vetLosAngeles, vetScheduling, vetReminders, vetIntake]

  it('links back to its parent pillar page', () => {
    const links = generateInternalLinks(vetScheduling, allPages)
    const slugs = links.map((l) => l.slug)
    expect(slugs).toContain(vetPillar.slug)
  })

  it('links to location pages for the same vertical', () => {
    const links = generateInternalLinks(vetScheduling, allPages)
    const locationSlugs = [vetIrvine.slug, vetAnaheim.slug, vetLosAngeles.slug]
    const locationLinks = links.filter((l) => locationSlugs.includes(l.slug))
    expect(locationLinks.length).toBeGreaterThanOrEqual(1)
    expect(locationLinks.length).toBeLessThanOrEqual(3)
  })

  it('links to related cluster pages (same vertical, different slug)', () => {
    const links = generateInternalLinks(vetScheduling, allPages)
    const slugs = links.map((l) => l.slug)

    expect(slugs).not.toContain(vetScheduling.slug)
    const relatedClusters = [vetReminders.slug, vetIntake.slug]
    const clusterLinks = links.filter((l) => relatedClusters.includes(l.slug))
    expect(clusterLinks.length).toBeGreaterThanOrEqual(1)
    expect(clusterLinks.length).toBeLessThanOrEqual(3)
  })

  it('does not link to itself', () => {
    const links = generateInternalLinks(vetScheduling, allPages)
    const slugs = links.map((l) => l.slug)
    expect(slugs).not.toContain(vetScheduling.slug)
  })

  it('works for use-case page type as well', () => {
    const links = generateInternalLinks(vetReminders, allPages)
    const slugs = links.map((l) => l.slug)
    expect(slugs).toContain(vetPillar.slug)
    expect(slugs).not.toContain(vetReminders.slug)
  })
})

// =============================================================================
// Comparison / Other Page Types
// =============================================================================

describe('generateInternalLinks — comparison page', () => {
  it('returns an empty list (no hub-and-spoke rules defined)', () => {
    const compPage = makePage({
      id: 'comp-1',
      pageType: 'comparison',
      slug: 'compare/veterinary-clinics',
      vertical: 'veterinary-clinics',
      city: null,
      title: 'Compare AI Automation for Vet Clinics'
    })
    const links = generateInternalLinks(compPage, [vetPillar, vetIrvine, vetScheduling])
    expect(links).toHaveLength(0)
  })
})

// =============================================================================
// Link Count Limits
// =============================================================================

describe('link count limits', () => {
  it('pillar page respects OTHER_VERTICALS limit of 3', () => {
    // 6 other verticals — only 3 should be picked
    const manyPillars = [
      vetPillar,
      hvacPillar,
      autoPillar,
      pestPillar,
      makePage({
        id: 'clean-pillar',
        pageType: 'pillar',
        vertical: 'commercial-cleaning',
        city: null,
        slug: 'ai-automation/commercial-cleaning',
        title: 'AI Automation for Commercial Cleaning'
      }),
      makePage({
        id: 'spa-pillar',
        pageType: 'pillar',
        vertical: 'med-spas',
        city: null,
        slug: 'ai-automation/med-spas',
        title: 'AI Automation for Med Spas'
      }),
      makePage({
        id: 'hoa-pillar',
        pageType: 'pillar',
        vertical: 'hoa-property-management',
        city: null,
        slug: 'ai-automation/hoa-property-management',
        title: 'AI Automation for HOA'
      })
    ]
    const links = generateInternalLinks(vetPillar, manyPillars)
    const otherPillarLinks = links.filter((l) => l.slug !== vetPillar.slug)
    expect(otherPillarLinks.length).toBeLessThanOrEqual(3)
  })

  it('location page sibling count does not exceed 5', () => {
    // Create 10 sibling pages
    const manySiblings: SeoPage[] = Array.from({ length: 10 }, (_, i) =>
      makePage({
        id: `vet-city-${i}`,
        pageType: 'location',
        vertical: 'veterinary-clinics',
        city: `city-${i}`,
        state: 'CA',
        slug: `ai-automation/veterinary-clinics/city-${i}`,
        title: `AI Automation for Vet Clinics in City ${i}`
      })
    )

    const targetPage = manySiblings[0]!
    const links = generateInternalLinks(targetPage, [vetPillar, ...manySiblings])
    const siblingLinks = links.filter((l) => l.slug !== vetPillar.slug && l.slug !== targetPage.slug)
    expect(siblingLinks.length).toBeLessThanOrEqual(5)
  })

  it('cluster page location links do not exceed 3', () => {
    const manyLocations: SeoPage[] = Array.from({ length: 8 }, (_, i) =>
      makePage({
        id: `vet-loc-${i}`,
        pageType: 'location',
        vertical: 'veterinary-clinics',
        city: `city-${i}`,
        state: 'CA',
        slug: `ai-automation/veterinary-clinics/city-${i}`,
        title: `Vet Clinics in City ${i}`
      })
    )

    const links = generateInternalLinks(vetScheduling, [vetPillar, ...manyLocations, vetScheduling])
    const locationLinks = links.filter((l) => manyLocations.some((loc) => loc.slug === l.slug))
    expect(locationLinks.length).toBeLessThanOrEqual(3)
  })
})

// =============================================================================
// Determinism
// =============================================================================

describe('determinism', () => {
  it('generates the same links for the same input on multiple calls', () => {
    const allPages = [
      vetPillar,
      hvacPillar,
      autoPillar,
      vetIrvine,
      vetAnaheim,
      vetLosAngeles,
      vetScheduling,
      vetReminders
    ]
    const first = generateInternalLinks(vetIrvine, allPages)
    const second = generateInternalLinks(vetIrvine, allPages)
    expect(first).toEqual(second)
  })
})
