import { render, screen } from '@testing-library/react'
import { describe, it, expect } from 'vitest'
import CameraCard from './CameraCard'
import type { CameraStatus } from '../types'

function makeCamera(overrides: Partial<CameraStatus> = {}): CameraStatus {
  return {
    camera_id: 'cam-1',
    friendly_name: 'Front Camera',
    battery_pct: 85,
    video_remaining_sec: 3600,
    recording: false,
    mode: 'video',
    resolution: '1080p',
    fps: 30,
    online: true,
    last_seen: new Date().toISOString(),
    ...overrides,
  }
}

describe('CameraCard', () => {
  // ── Basic rendering ────────────────────────────────────────────────────

  it('renders camera name', () => {
    render(<CameraCard camera={makeCamera()} />)
    expect(screen.getByText('Front Camera')).toBeInTheDocument()
  })

  it('shows resolution and FPS', () => {
    render(<CameraCard camera={makeCamera()} />)
    expect(screen.getByText(/1080p/)).toBeInTheDocument()
    expect(screen.getByText(/30\s*FPS/)).toBeInTheDocument()
  })

  it('shows battery percentage', () => {
    render(<CameraCard camera={makeCamera({ battery_pct: 85 })} />)
    expect(screen.getByText('85%')).toBeInTheDocument()
  })

  it('shows N/A when battery is null', () => {
    render(<CameraCard camera={makeCamera({ battery_pct: null })} />)
    expect(screen.getByText('N/A')).toBeInTheDocument()
  })

  // ── Battery bar colors ─────────────────────────────────────────────────

  it('uses green bar for high battery (>=50%)', () => {
    const { container } = render(
      <CameraCard camera={makeCamera({ battery_pct: 85 })} />,
    )
    const bar = container.querySelector('[role="progressbar"] div')
    expect(bar?.className).toContain('bg-rig-success')
  })

  it('uses yellow bar for medium battery (15-49%)', () => {
    const { container } = render(
      <CameraCard camera={makeCamera({ battery_pct: 30 })} />,
    )
    const bar = container.querySelector('[role="progressbar"] div')
    expect(bar?.className).toContain('bg-rig-warning')
  })

  it('uses red bar for low battery (<15%)', () => {
    const { container } = render(
      <CameraCard camera={makeCamera({ battery_pct: 8 })} />,
    )
    const bar = container.querySelector('[role="progressbar"] div')
    expect(bar?.className).toContain('bg-rig-danger')
  })

  // ── Recording state ────────────────────────────────────────────────────

  it('shows REC badge when recording', () => {
    render(<CameraCard camera={makeCamera({ recording: true })} />)
    expect(screen.getByText('REC')).toBeInTheDocument()
  })

  it('shows IDLE badge when not recording', () => {
    render(<CameraCard camera={makeCamera({ recording: false })} />)
    expect(screen.getByText('IDLE')).toBeInTheDocument()
  })

  // ── Online / Offline badges ────────────────────────────────────────────

  it('shows Online badge when camera is online', () => {
    render(<CameraCard camera={makeCamera({ online: true })} />)
    expect(screen.getByText('Online')).toBeInTheDocument()
  })

  it('shows Offline badge when camera is offline', () => {
    render(<CameraCard camera={makeCamera({ online: false })} />)
    const offlineElements = screen.getAllByText('Offline')
    expect(offlineElements.length).toBeGreaterThanOrEqual(1)
  })

  // ── Video remaining ────────────────────────────────────────────────────

  it('shows video remaining time when available', () => {
    render(<CameraCard camera={makeCamera({ video_remaining_sec: 125 })} />)
    // formatTimeLeft(125) → "2m 5s left"
    expect(screen.getByText(/2m 5s left/)).toBeInTheDocument()
  })

  it('does not show video remaining when null', () => {
    render(<CameraCard camera={makeCamera({ video_remaining_sec: null })} />)
    // The Radio icon and time text should not be present
    expect(screen.queryByText(/m\s+\d+s left/)).not.toBeInTheDocument()
  })

  // ── Footer ─────────────────────────────────────────────────────────────

  it('shows Live + timestamp in footer when online', () => {
    render(<CameraCard camera={makeCamera({ online: true })} />)
    // Footer shows "Live" when online
    expect(screen.getByText('Live')).toBeInTheDocument()
  })

  it('shows Offline + timestamp in footer when offline', () => {
    render(<CameraCard camera={makeCamera({ online: false })} />)
    // Footer says "Offline" (the text appears both in the badge and footer)
    // When offline, the footer specifically shows "Offline" text
    const offlineElements = screen.getAllByText('Offline')
    // At least one should exist (badge + footer)
    expect(offlineElements.length).toBeGreaterThanOrEqual(1)
  })

  it('shows "unknown" when last_seen is malformed', () => {
    render(
      <CameraCard camera={makeCamera({ last_seen: 'not-a-date' })} />,
    )
    expect(screen.getByText('unknown')).toBeInTheDocument()
  })

  it('shows "unknown" when last_seen is in the future', () => {
    const future = new Date(Date.now() + 86400000).toISOString() // +1 day
    render(<CameraCard camera={makeCamera({ last_seen: future })} />)
    expect(screen.getByText('unknown')).toBeInTheDocument()
  })

  // ── Edge cases ──────────────────────────────────────────────────────────

  it('clamps negative battery_pct to 0%', () => {
    render(<CameraCard camera={makeCamera({ battery_pct: -5 })} />)
    expect(screen.getByText('0%')).toBeInTheDocument()
  })

  it('shows exact boundary: 15% battery → yellow bar', () => {
    const { container } = render(
      <CameraCard camera={makeCamera({ battery_pct: 15 })} />,
    )
    const bar = container.querySelector('[role="progressbar"] div')
    expect(bar?.className).toContain('bg-rig-warning')
  })

  it('shows exact boundary: 50% battery → green bar', () => {
    const { container } = render(
      <CameraCard camera={makeCamera({ battery_pct: 50 })} />,
    )
    const bar = container.querySelector('[role="progressbar"] div')
    expect(bar?.className).toContain('bg-rig-success')
  })
})
