/**
 * Tests for TibberPrices component.
 *
 * Coverage:
 * 1. Loading state.
 * 2. Empty state (no active contract / no kind).
 * 3. Renders tibber chart when tibber kind data is available.
 * 4. Shows tariff table for manual kind.
 */

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { screen, waitFor } from '@testing-library/react'
import { renderWithProviders } from '../test-utils'

// ---------------------------------------------------------------------------
// Mock apiClient
// ---------------------------------------------------------------------------

const mockGet = vi.fn()

vi.mock('../api/client', () => ({
  default: {
    GET: (...args: unknown[]) => mockGet(...args),
    POST: vi.fn(),
    PATCH: vi.fn(),
    DELETE: vi.fn(),
  },
  ApiError: class ApiError extends Error {
    status: number
    body: unknown
    constructor(status: number, body: unknown) {
      super(`API error ${status}`)
      this.name = 'ApiError'
      this.status = status
      this.body = body
    }
  },
  registerLoginRedirect: vi.fn(),
}))

// ---------------------------------------------------------------------------
// Import component
// ---------------------------------------------------------------------------

import { TibberPrices } from './TibberPrices'

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

describe('TibberPrices', () => {
  beforeEach(() => vi.clearAllMocks())

  it('renders loading state initially', () => {
    mockGet.mockImplementation(() => new Promise(() => {}))

    renderWithProviders(<TibberPrices />)

    expect(screen.getByTestId('prices-loading')).toBeInTheDocument()
  })

  it('renders "no active contract" when kind is missing/null', async () => {
    mockGet.mockResolvedValue({
      data: {
        kind: null,
        currency: 'EUR',
        points: [],
        tariff: null,
      },
    })

    renderWithProviders(<TibberPrices />)

    await waitFor(() => {
      expect(screen.getByTestId('prices-no-contract')).toBeInTheDocument()
    })
  })

  it('renders error state when fetch fails', async () => {
    mockGet.mockRejectedValue(new Error('Network error'))

    renderWithProviders(<TibberPrices />)

    await waitFor(() => {
      expect(screen.getByTestId('prices-error')).toBeInTheDocument()
    })
  })

  it('renders tibber chart when tibber data is available', async () => {
    mockGet.mockResolvedValue({
      data: {
        kind: 'tibber',
        currency: 'EUR',
        points: [
          { starts_at: '2026-06-22T10:00:00Z', buy: 0.133, sell: 0.09, level: 'NORMAL' },
          { starts_at: '2026-06-22T10:15:00Z', buy: 0.140, sell: 0.092, level: 'NORMAL' },
        ],
        tariff: null,
      },
    })

    renderWithProviders(<TibberPrices />)

    await waitFor(() => {
      expect(screen.getByTestId('tibber-chart')).toBeInTheDocument()
    })

    // Check badge shows kind
    expect(screen.getByText('tibber')).toBeInTheDocument()
  })

  it('shows tariff table for manual kind', async () => {
    mockGet.mockResolvedValue({
      data: {
        kind: 'manual',
        currency: 'EUR',
        points: [],
        tariff: {
          buy_dal: 0.127,
          buy_normal: 0.133,
          sell_dal: 0.09,
          sell_normal: 0.09,
        },
      },
    })

    renderWithProviders(<TibberPrices />)

    await waitFor(() => {
      expect(screen.getByTestId('manual-tariff-table')).toBeInTheDocument()
    })

    expect(screen.getByTestId('tariff-buy-normal')).toHaveTextContent('0.1330')
    expect(screen.getByTestId('tariff-buy-dal')).toHaveTextContent('0.1270')
    expect(screen.getByTestId('tariff-sell-normal')).toHaveTextContent('0.0900')
    expect(screen.getByTestId('tariff-sell-dal')).toHaveTextContent('0.0900')
  })
})
