import { describe, it } from 'node:test'
import assert from 'node:assert'
import { formatTable, formatInstance, formatError } from '../../format.js'
import chalk from 'chalk'

// Force colors in tests
chalk.level = 1

/**
 * Strip ANSI color codes for easier testing.
 * We'll install strip-ansi as a dev dependency.
 */
function clean(str) {
  // Simple ANSI stripping for tests
  return str.replace(/\u001b\[[0-9;]*m/g, '')
}

describe('formatTable', () => {
  it('formats data into a table', () => {
    const data = [
      { id: 'bid-1', type: 'gpu.a100.1x', status: 'RUNNING', region: 'us-west-2' },
      { id: 'bid-2', type: 'gpu.h100.2x', status: 'PENDING', region: 'us-east-1' }
    ]
    
    const result = formatTable(data, ['id', 'type', 'status', 'region'])
    const cleaned = clean(result)
    
    // Verify table structure
    assert(cleaned.includes('ID'))
    assert(cleaned.includes('TYPE'))
    assert(cleaned.includes('STATUS'))
    assert(cleaned.includes('REGION'))
    
    // Verify data
    assert(cleaned.includes('bid-1'))
    assert(cleaned.includes('gpu.a100.1x'))
    assert(cleaned.includes('RUNNING'))
    assert(cleaned.includes('us-west-2'))
  })

  it('handles empty data', () => {
    const result = formatTable([], ['id', 'type'])
    const cleaned = clean(result)
    
    assert.equal(cleaned, 'No results')
  })

  it('handles missing values with N/A', () => {
    const data = [
      { id: 'bid-1', type: null, status: undefined, region: '' }
    ]
    
    const result = formatTable(data, ['id', 'type', 'status', 'region'])
    const cleaned = clean(result)
    
    assert(cleaned.includes('bid-1'))
    assert(cleaned.includes('N/A'))
  })

  it('applies semantic coloring for status', () => {
    const data = [
      { status: 'RUNNING' },
      { status: 'PENDING' },
      { status: 'TERMINATED' }
    ]
    
    const result = formatTable(data, ['status'])
    
    // Check that ANSI codes are present (colors applied)
    assert(result.includes('\u001b['))
    
    // Verify the actual status values are present
    const cleaned = clean(result)
    assert(cleaned.includes('RUNNING'))
    assert(cleaned.includes('PENDING'))
    assert(cleaned.includes('TERMINATED'))
  })

  it('formats availability numbers', () => {
    const data = [
      { available: 0 },
      { available: 5 },
      { available: 15 }
    ]
    
    const result = formatTable(data, ['available'])
    const cleaned = clean(result)
    
    assert(cleaned.includes('0'))
    assert(cleaned.includes('5'))
    assert(cleaned.includes('15'))
  })

  it('formats price with dollar sign', () => {
    const data = [
      { price: '$25.60' },
      { price: '$51.20' }
    ]
    
    const result = formatTable(data, ['price'])
    const cleaned = clean(result)
    
    assert(cleaned.includes('$25.60'))
    assert(cleaned.includes('$51.20'))
  })

  it('colors instance types appropriately', () => {
    const data = [
      { type: 'gpu.a100.1x' },
      { type: 'gpu.h100.2x' },
      { type: 'cpu.large' }
    ]
    
    const result = formatTable(data, ['type'])
    
    // Verify ANSI codes present
    assert(result.includes('\u001b['))
    
    const cleaned = clean(result)
    assert(cleaned.includes('gpu.a100.1x'))
    assert(cleaned.includes('gpu.h100.2x'))
    assert(cleaned.includes('cpu.large'))
  })
})

describe('formatInstance', () => {
  it('formats running instance details', () => {
    const instance = {
      id: 'bid-123',
      type: 'gpu.a100.1x',
      status: 'RUNNING',
      region: 'us-west-2',
      ip: '54.123.45.67',
      created: '2024-01-01T00:00:00Z'
    }
    
    const result = formatInstance(instance)
    const cleaned = clean(result)
    
    assert(cleaned.includes('Instance: bid-123'))
    assert(cleaned.includes('Type: gpu.a100.1x'))
    assert(cleaned.includes('Status: RUNNING'))
    assert(cleaned.includes('IP: 54.123.45.67'))
    assert(cleaned.includes('SSH: ubuntu@54.123.45.67'))
    assert(cleaned.includes('Region: us-west-2'))
  })

  it('formats provisioning instance with progress', () => {
    const instance = {
      id: 'bid-123',
      type: 'gpu.a100.1x',
      status: 'PROVISIONING',
      region: 'us-west-2',
      created: '2024-01-01T00:00:00Z'
    }
    
    const result = formatInstance(instance)
    const cleaned = clean(result)
    
    assert(cleaned.includes('Instance: bid-123'))
    assert(cleaned.includes('Status: PROVISIONING'))
    assert(cleaned.includes('Progress:'))
    assert(cleaned.includes('█'))  // Progress bar
    assert(cleaned.includes('░'))  // Empty progress
    assert(cleaned.includes('Elapsed:'))
    assert(cleaned.includes('Estimated remaining:'))
  })

  it('formats pending instance without IP', () => {
    const instance = {
      id: 'bid-123',
      type: 'gpu.a100.1x',
      status: 'PENDING',
      region: 'us-west-2',
      ip: null,
      created: '2024-01-01T00:00:00Z'
    }
    
    const result = formatInstance(instance)
    const cleaned = clean(result)
    
    assert(cleaned.includes('Instance: bid-123'))
    assert(cleaned.includes('Status: PENDING'))
    assert(cleaned.includes('IP: Pending...'))
    assert(cleaned.includes('Created:'))
  })

  it('handles NOT_FOUND status', () => {
    const instance = {
      id: 'bid-123',
      status: 'NOT_FOUND'
    }
    
    const result = formatInstance(instance)
    const cleaned = clean(result)
    
    assert(cleaned.includes('Instance: bid-123'))
    assert(cleaned.includes('Status: NOT FOUND'))
  })

  it('displays checkmark for running status', () => {
    const instance = {
      id: 'bid-123',
      status: 'RUNNING',
      ip: '1.2.3.4'
    }
    
    const result = formatInstance(instance)
    const cleaned = clean(result)
    
    assert(cleaned.includes('RUNNING ✓'))
  })
})

describe('formatError', () => {
  it('formats simple error message', () => {
    const error = new Error('Something went wrong')
    const result = formatError(error)
    const cleaned = clean(result)
    
    assert.equal(cleaned, 'Error: Something went wrong')
  })

  it('extracts message from API response', () => {
    const error = {
      response: {
        body: {
          message: 'Invalid API key'
        }
      }
    }
    
    const result = formatError(error)
    const cleaned = clean(result)
    
    assert.equal(cleaned, 'Error: Invalid API key')
  })

  it('falls back to error.message when no response', () => {
    const error = {
      message: 'Network timeout'
    }
    
    const result = formatError(error)
    const cleaned = clean(result)
    
    assert.equal(cleaned, 'Error: Network timeout')
  })

  it('applies red color to errors', () => {
    const error = new Error('Test error')
    const result = formatError(error)
    
    // Verify ANSI red color code is present
    assert(result.includes('\u001b['))
    assert(clean(result).includes('Error: Test error'))
  })
})