import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { createRouter, createMemoryHistory } from 'vue-router'
import EventStubView from '../EventStubView.vue'

function createTestRouter() {
  return createRouter({
    history: createMemoryHistory(),
    routes: [
      { path: '/', name: 'home', component: { template: '<div />' } },
      { path: '/events/:eventToken', name: 'event', component: EventStubView },
    ],
  })
}

async function mountWithToken(token = 'test-token-123') {
  const router = createTestRouter()
  await router.push(`/events/${token}`)
  await router.isReady()
  return mount(EventStubView, {
    global: { plugins: [router] },
  })
}

describe('EventStubView', () => {
  it('renders the event URL based on route param', async () => {
    const wrapper = await mountWithToken('abc-def')

    const linkText = wrapper.find('.stub__link').text()
    expect(linkText).toContain('/events/abc-def')
  })

  it('shows the correct share URL with origin', async () => {
    const wrapper = await mountWithToken('my-event-token')

    const linkText = wrapper.find('.stub__link').text()
    expect(linkText).toBe(`${window.location.origin}/events/my-event-token`)
  })

  it('has a copy button', async () => {
    const wrapper = await mountWithToken()

    const copyBtn = wrapper.find('.stub__copy')
    expect(copyBtn.exists()).toBe(true)
    expect(copyBtn.text()).toBe('Copy')
  })

  it('copies link to clipboard and shows confirmation', async () => {
    const writeTextMock = vi.fn<(text: string) => Promise<void>>().mockResolvedValue(undefined)
    Object.assign(navigator, {
      clipboard: { writeText: writeTextMock },
    })

    const wrapper = await mountWithToken('copy-test')

    await wrapper.find('.stub__copy').trigger('click')

    expect(writeTextMock).toHaveBeenCalledWith(
      `${window.location.origin}/events/copy-test`,
    )
    expect(wrapper.find('.stub__copy').text()).toBe('Copied!')
  })

  it('shows failure message when clipboard is unavailable', async () => {
    Object.assign(navigator, {
      clipboard: { writeText: vi.fn<(text: string) => Promise<void>>().mockRejectedValue(new Error('Not allowed')) },
    })

    const wrapper = await mountWithToken('fail-test')

    await wrapper.find('.stub__copy').trigger('click')

    expect(wrapper.find('.stub__copy').text()).toBe('Failed')
    expect(wrapper.find('.stub__copy').attributes('aria-label')).toBe(
      'Copy failed — select the link to copy manually',
    )
  })

  it('has a back link to home', async () => {
    const wrapper = await mountWithToken()

    const backLink = wrapper.find('.stub__back')
    expect(backLink.exists()).toBe(true)
    expect(backLink.attributes('aria-label')).toBe('Back to home')
    expect(backLink.attributes('href')).toBe('/')
  })
})
