import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

import Billing from '@/pages/Billing'

// ── Mock data ──────────────────────────────────────────────────

const mockPlans = [
  {
    id: 'plan-free', name: 'free', display_name: '免费版',
    description: '基础功能', price_cents: 0, currency: 'CNY',
    interval: 'month',
    features: {}, limits: { max_relay_requests_monthly: 100, max_hand_executions_monthly: 10, max_pipeline_runs_monthly: 5 },
    is_default: true, sort_order: 0, status: 'active',
    created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z',
  },
  {
    id: 'plan-pro', name: 'pro', display_name: '专业版',
    description: '高级功能', price_cents: 9900, currency: 'CNY',
    interval: 'month',
    features: {}, limits: { max_relay_requests_monthly: 1000, max_hand_executions_monthly: 100, max_pipeline_runs_monthly: 50 },
    is_default: false, sort_order: 1, status: 'active',
    created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z',
  },
  {
    id: 'plan-team', name: 'team', display_name: '团队版',
    description: '团队协作', price_cents: 29900, currency: 'CNY',
    interval: 'month',
    features: {}, limits: { max_relay_requests_monthly: 10000, max_hand_executions_monthly: 500, max_pipeline_runs_monthly: 200 },
    is_default: false, sort_order: 2, status: 'active',
    created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z',
  },
]

const mockSubscription = {
  plan: mockPlans[0],
  subscription: null,
  usage: {
    id: 'usage-001', account_id: 'acc-001',
    period_start: '2026-04-01T00:00:00Z', period_end: '2026-04-30T23:59:59Z',
    input_tokens: 5000, output_tokens: 12000,
    relay_requests: 42, hand_executions: 3, pipeline_runs: 1,
    max_input_tokens: null, max_output_tokens: null,
    max_relay_requests: 100, max_hand_executions: 10, max_pipeline_runs: 5,
    created_at: '2026-04-01T00:00:00Z', updated_at: '2026-04-07T12:00:00Z',
  },
}

const server = setupServer()

beforeEach(() => {
  server.listen({ onUnhandledRequest: 'bypass' })
})

afterEach(() => {
  server.close()
})

function renderWithProviders(ui: React.ReactElement) {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  })
  return render(
    <QueryClientProvider client={queryClient}>
      {ui}
    </QueryClientProvider>,
  )
}

function setupBillingHandlers(overrides: Record<string, unknown> = {}) {
  server.use(
    http.get('*/api/v1/billing/plans', () => {
      return HttpResponse.json(overrides.plans ?? mockPlans)
    }),
    http.get('*/api/v1/billing/subscription', () => {
      return HttpResponse.json(overrides.subscription ?? mockSubscription)
    }),
  )
}

describe('Billing', () => {
  it('renders page title', () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)
    expect(screen.getByText('计费管理')).toBeInTheDocument()
  })

  it('shows loading state', async () => {
    server.use(
      http.get('*/api/v1/billing/plans', async () => {
        await new Promise(resolve => setTimeout(resolve, 500))
        return HttpResponse.json(mockPlans)
      }),
      http.get('*/api/v1/billing/subscription', async () => {
        await new Promise(resolve => setTimeout(resolve, 500))
        return HttpResponse.json(mockSubscription)
      }),
    )
    renderWithProviders(<Billing />)
    expect(document.querySelector('.ant-spin')).toBeTruthy()
  })

  it('displays all three plan cards', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      expect(screen.getByText('免费版')).toBeInTheDocument()
    })
    expect(screen.getByText('专业版')).toBeInTheDocument()
    expect(screen.getByText('团队版')).toBeInTheDocument()
  })

  it('displays plan prices', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      // Free plan: ¥0
      expect(screen.getByText('¥0')).toBeInTheDocument()
    })
    // Pro plan: ¥99, Team plan: ¥299
    expect(screen.getByText('¥99')).toBeInTheDocument()
    expect(screen.getByText('¥299')).toBeInTheDocument()
  })

  it('displays per-month interval', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      // All plans are monthly, so "/月" should appear multiple times
      const monthLabels = screen.getAllByText('/月')
      expect(monthLabels.length).toBeGreaterThanOrEqual(3)
    })
  })

  it('displays plan limits', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      // Free plan limits
      expect(screen.getByText('中转请求: 100 次/月')).toBeInTheDocument()
    })
    expect(screen.getByText('Hand 执行: 10 次/月')).toBeInTheDocument()
    expect(screen.getByText('Pipeline 运行: 5 次/月')).toBeInTheDocument()
  })

  it('shows 当前计划 badge on free plan', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      // "当前计划" appears on the badge AND the disabled button for free plan
      const allCurrentPlan = screen.getAllByText('当前计划')
      expect(allCurrentPlan.length).toBeGreaterThanOrEqual(1)
    })
  })

  it('renders pro and team plan cards with buttons', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      expect(screen.getByText('专业版')).toBeInTheDocument()
    })
    // Non-current plans should have clickable buttons (not disabled "当前计划")
    expect(screen.getByText('团队版')).toBeInTheDocument()
    // Free plan is current → its button shows "当前计划" and is disabled
    const allButtons = screen.getAllByRole('button')
    const disabledButtons = allButtons.filter(btn => btn.hasAttribute('disabled'))
    expect(disabledButtons.length).toBeGreaterThanOrEqual(1) // at least free plan button
  })

  it('shows 当前用量 section', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      expect(screen.getByText('当前用量')).toBeInTheDocument()
    })
  })

  it('displays usage bars with correct values', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      // relay_requests: 42 / 100
      expect(screen.getByText('中转请求')).toBeInTheDocument()
    })
    expect(screen.getByText('Hand 执行')).toBeInTheDocument()
    expect(screen.getByText('Pipeline 运行')).toBeInTheDocument()
  })

  it('shows error state on plans API failure', async () => {
    server.use(
      http.get('*/api/v1/billing/plans', () => {
        return HttpResponse.json(
          { error: 'internal_error', message: '数据库错误' },
          { status: 500 },
        )
      }),
      http.get('*/api/v1/billing/subscription', () => {
        return HttpResponse.json(mockSubscription)
      }),
    )
    renderWithProviders(<Billing />)

    await waitFor(() => {
      expect(screen.getByText('加载失败')).toBeInTheDocument()
    })
  })

  it('renders without subscription data', async () => {
    setupBillingHandlers({
      subscription: {
        plan: null,
        subscription: null,
        usage: null,
      },
    })
    renderWithProviders(<Billing />)

    await waitFor(() => {
      expect(screen.getByText('免费版')).toBeInTheDocument()
    })
    // No usage section when usage is null
    expect(screen.queryByText('当前用量')).not.toBeInTheDocument()
  })

  it('shows 选择计划 heading', async () => {
    setupBillingHandlers()
    renderWithProviders(<Billing />)

    await waitFor(() => {
      expect(screen.getByText('选择计划')).toBeInTheDocument()
    })
  })
})
