import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'

import { TrialPill } from '../TrialPill'
import { useBillingStore } from '@/store/billingStore'
import type { SubscriptionState, PlanBillingState } from '@/types/billing'

const FROZEN_NOW = new Date('2026-05-06T12:00:00Z')

function renderPill() {
  return render(
    <MemoryRouter>
      <TrialPill />
    </MemoryRouter>,
  )
}

function setBilling(opts: {
  subscription: SubscriptionState | null
  planBilling?: PlanBillingState | null
}) {
  useBillingStore.setState({
    subscription: opts.subscription,
    planBilling: opts.planBilling ?? null,
    planLimits: {},
    enabledFeatures: {},
    isLoading: false,
    error: null,
  })
}

function isoDaysFromNow(days: number): string {
  const d = new Date(FROZEN_NOW.getTime() + days * 24 * 60 * 60 * 1000)
  return d.toISOString()
}

describe('TrialPill', () => {
  beforeEach(() => {
    vi.useFakeTimers()
    vi.setSystemTime(FROZEN_NOW)
    useBillingStore.setState({
      subscription: null,
      planBilling: null,
      planLimits: {},
      enabledFeatures: {},
      isLoading: false,
      error: null,
    })
  })

  afterEach(() => {
    vi.useRealTimers()
  })

  it('renders Pro trial · Nd for pristine stage', () => {
    setBilling({
      subscription: {
        status: 'trialing',
        plan: 'pro',
        current_period_start: FROZEN_NOW.toISOString(),
        current_period_end: isoDaysFromNow(12),
        cancel_at_period_end: false,
        seat_limit: 5,
        has_pro_entitlement: true,
        is_paid: false,
      },
    })

    renderPill()

    const pill = screen.getByTestId('trial-pill')
    expect(pill).toHaveTextContent(/Pro trial · 12d/)
    // Pristine uses info tone tokens.
    expect(pill.className).toContain('text-info')
    expect(pill.className).toContain('bg-info-dim')
  })

  it('renders Trial expired CTA for expired stage', () => {
    setBilling({
      subscription: {
        status: 'trialing',
        plan: 'pro',
        current_period_start: isoDaysFromNow(-14),
        current_period_end: isoDaysFromNow(-1), // already past
        cancel_at_period_end: false,
        seat_limit: 5,
        has_pro_entitlement: false,
        is_paid: false,
      },
    })

    renderPill()

    const pill = screen.getByTestId('trial-pill')
    expect(pill).toHaveTextContent(/Trial expired — pick a plan/)
    // Clickable: rendered as anchor/link.
    expect(pill.tagName).toBe('A')
    expect(pill.getAttribute('href')).toBe('/account/billing/select-plan')
  })

  it('renders Complimentary Pro tag for complimentary subscription', () => {
    setBilling({
      subscription: {
        status: 'complimentary',
        plan: 'pro',
        current_period_start: null,
        current_period_end: null,
        cancel_at_period_end: false,
        seat_limit: null,
        has_pro_entitlement: true,
        is_paid: true,
      },
    })

    renderPill()

    const pill = screen.getByTestId('trial-pill')
    expect(pill).toHaveTextContent(/Complimentary Pro/)
    // Friendly tag, not clickable.
    expect(pill.tagName).toBe('SPAN')
    expect(pill.className).toContain('text-accent')
  })

  it('is hidden when subscription is null', () => {
    setBilling({ subscription: null })

    const { container } = renderPill()

    expect(screen.queryByTestId('trial-pill')).not.toBeInTheDocument()
    expect(container.firstChild).toBeNull()
  })

  it('past_due variant is clickable and links to /account/billing', () => {
    setBilling({
      subscription: {
        status: 'past_due',
        plan: 'pro',
        current_period_start: isoDaysFromNow(-30),
        current_period_end: isoDaysFromNow(-2),
        cancel_at_period_end: false,
        seat_limit: 5,
        has_pro_entitlement: false,
        is_paid: true,
      },
    })

    renderPill()

    const pill = screen.getByTestId('trial-pill')
    expect(pill).toHaveTextContent(/Payment failed — update card/)
    expect(pill.tagName).toBe('A')
    expect(pill.getAttribute('href')).toBe('/account/billing')
  })
})
