/**
 * Unity Bridge Tests
 *
 * Testet die Unity AI Bridge Integration:
 * - Struktur-Tests (Dateien existieren)
 * - API Route Tests (Handler-Verhalten)
 * - Content-Tests (korrekter Inhalt)
 */

import { existsSync, readFileSync } from 'fs'
import { join } from 'path'

const ROOT_DIR = join(__dirname, '..')
const APP_DIR = join(ROOT_DIR, 'app')
const COMPONENTS_DIR = join(ROOT_DIR, 'components')
const LIB_DIR = join(ROOT_DIR, 'lib')

// ==============================================
// Structure Tests
// ==============================================

describe('Unity Bridge Structure', () => {
  describe('Pages', () => {
    it('has dashboard page', () => {
      expect(existsSync(join(APP_DIR, 'admin', 'unity-bridge', 'page.tsx'))).toBe(true)
    })

    it('has wizard page', () => {
      expect(existsSync(join(APP_DIR, 'admin', 'unity-bridge', 'wizard', 'page.tsx'))).toBe(true)
    })
  })

  describe('API Route', () => {
    it('has unity-bridge API route', () => {
      expect(existsSync(join(APP_DIR, 'api', 'admin', 'unity-bridge', 'route.ts'))).toBe(true)
    })
  })
})

// ==============================================
// API Route Content Tests
// ==============================================

describe('Unity Bridge API Route', () => {
  const apiPath = join(APP_DIR, 'api', 'admin', 'unity-bridge', 'route.ts')
  let content: string

  beforeAll(() => {
    content = readFileSync(apiPath, 'utf-8')
  })

  describe('GET Handler', () => {
    it('has GET export', () => {
      expect(content).toContain('export async function GET')
    })

    it('supports status action', () => {
      expect(content).toContain("status: '/status'")
    })

    it('supports compile action', () => {
      expect(content).toContain("compile: '/compile'")
    })

    it('supports logs action', () => {
      expect(content).toContain("logs:")
      expect(content).toContain('/logs')
    })

    it('supports errors action', () => {
      expect(content).toContain("errors: '/logs/errors'")
    })

    it('supports warnings action', () => {
      expect(content).toContain("warnings: '/logs/warnings'")
    })

    it('supports scene action', () => {
      expect(content).toContain("scene: '/scene'")
    })

    it('supports play action', () => {
      expect(content).toContain("play: '/play'")
    })

    it('supports stop action', () => {
      expect(content).toContain("stop: '/stop'")
    })

    it('supports quicksetup action', () => {
      expect(content).toContain("quicksetup: '/quicksetup'")
    })

    it('supports object endpoint with name parameter', () => {
      expect(content).toContain('object')
      expect(content).toContain('objectName')
    })

    it('handles connection errors gracefully', () => {
      expect(content).toContain('offline')
      expect(content).toContain('503')
    })

    it('uses correct Unity Bridge URL', () => {
      expect(content).toContain('UNITY_BRIDGE_URL')
      expect(content).toContain('http://localhost:8090')
    })

    it('has timeout for requests', () => {
      expect(content).toContain('AbortSignal.timeout')
      expect(content).toContain('3000')
    })
  })

  describe('POST Handler', () => {
    it('has POST export', () => {
      expect(content).toContain('export async function POST')
    })

    it('supports diagnose action', () => {
      expect(content).toContain("action === 'diagnose'")
      expect(content).toContain('/diagnose')
    })

    it('supports execute action', () => {
      expect(content).toContain("action === 'execute'")
      expect(content).toContain('/execute')
    })

    it('supports clear-logs action', () => {
      expect(content).toContain("action === 'clear-logs'")
      expect(content).toContain('/logs/clear')
    })

    it('validates POST body for execute', () => {
      expect(content).toContain('Invalid JSON body')
      expect(content).toContain('Missing "action" field')
    })

    it('has longer timeout for diagnose', () => {
      expect(content).toContain('10000')
    })
  })

  describe('Error Handling', () => {
    it('returns 400 for unknown actions', () => {
      expect(content).toContain('400')
      expect(content).toContain('Unknown action')
    })

    it('returns 503 when bridge offline', () => {
      expect(content).toContain('503')
      expect(content).toContain('offline: true')
    })

    it('distinguishes timeout from connection refused', () => {
      expect(content).toContain('timeout')
      expect(content).toContain('aborted')
    })
  })

  describe('Type Definitions', () => {
    it('has BridgeStatus interface', () => {
      expect(content).toContain('interface BridgeStatus')
    })

    it('has LogEntry interface', () => {
      expect(content).toContain('interface LogEntry')
    })

    it('has LogsResponse interface', () => {
      expect(content).toContain('interface LogsResponse')
    })

    it('has DiagnoseResponse interface', () => {
      expect(content).toContain('interface DiagnoseResponse')
    })
  })
})

// ==============================================
// Dashboard Page Tests
// ==============================================

describe('Unity Bridge Dashboard Page', () => {
  const dashboardPath = join(APP_DIR, 'admin', 'unity-bridge', 'page.tsx')
  let content: string

  beforeAll(() => {
    content = readFileSync(dashboardPath, 'utf-8')
  })

  it('is a client component', () => {
    expect(content).toContain("'use client'")
  })

  it('uses AdminLayout', () => {
    expect(content).toContain('AdminLayout')
    expect(content).toContain("title=\"Unity AI Bridge\"")
  })

  it('has status polling', () => {
    expect(content).toContain('setInterval')
    expect(content).toContain('5000') // 5 second interval
  })

  it('has log polling', () => {
    expect(content).toContain('10000') // 10 second interval
  })

  it('has status badge component', () => {
    expect(content).toContain('StatusBadge')
  })

  it('has stat cards', () => {
    expect(content).toContain('StatCard')
  })

  it('has console log panel', () => {
    expect(content).toContain('ConsoleLogPanel')
  })

  it('has diagnostic panel', () => {
    expect(content).toContain('DiagnosticPanel')
  })

  it('has quick action buttons', () => {
    expect(content).toContain('Play')
    expect(content).toContain('Stop')
    expect(content).toContain('Quick Setup')
    expect(content).toContain('Diagnose')
  })

  it('links to wizard', () => {
    expect(content).toContain('/admin/unity-bridge/wizard')
    expect(content).toContain('Wizard')
  })

  it('handles offline state', () => {
    expect(content).toContain('offline')
    expect(content).toContain('Offline')
  })

  it('shows error and warning counts', () => {
    expect(content).toContain('errors')
    expect(content).toContain('warnings')
  })

  it('shows scene information', () => {
    expect(content).toContain('scene')
  })

  it('shows play mode status', () => {
    expect(content).toContain('is_playing')
  })
})

// ==============================================
// Wizard Page Tests
// ==============================================

describe('Unity Bridge Wizard Page', () => {
  const wizardPath = join(APP_DIR, 'admin', 'unity-bridge', 'wizard', 'page.tsx')
  let content: string

  beforeAll(() => {
    content = readFileSync(wizardPath, 'utf-8')
  })

  it('is a client component', () => {
    expect(content).toContain("'use client'")
  })

  it('uses AdminLayout', () => {
    expect(content).toContain('AdminLayout')
    expect(content).toContain("title=\"Unity AI Bridge Wizard\"")
  })

  it('uses wizard components', () => {
    expect(content).toContain('WizardStepper')
    expect(content).toContain('WizardNavigation')
    expect(content).toContain('EducationCard')
  })

  it('has 7 steps defined', () => {
    const stepMatches = content.match(/\{ id: '/g)
    expect(stepMatches).not.toBeNull()
    expect(stepMatches!.length).toBeGreaterThanOrEqual(7)
  })

  it('has welcome step', () => {
    expect(content).toContain("id: 'welcome'")
  })

  it('has what-is-bridge step', () => {
    expect(content).toContain("id: 'what-is-bridge'")
  })

  it('has start-server step', () => {
    expect(content).toContain("id: 'start-server'")
  })

  it('has api-endpoints step', () => {
    expect(content).toContain("id: 'api-endpoints'")
  })

  it('has live-demo step', () => {
    expect(content).toContain("id: 'live-demo'")
  })

  it('has claude-usage step', () => {
    expect(content).toContain("id: 'claude-usage'")
  })

  it('has troubleshooting step', () => {
    expect(content).toContain("id: 'troubleshooting'")
  })

  it('has LiveDemoPanel component', () => {
    expect(content).toContain('LiveDemoPanel')
  })

  it('has navigation back link', () => {
    expect(content).toContain('/admin/unity-bridge')
    expect(content).toContain('Zurueck')
  })

  it('has completion message', () => {
    expect(content).toContain('Wizard abgeschlossen')
  })

  describe('Education Content', () => {
    it('explains what the bridge is', () => {
      expect(content).toContain('Unity AI Bridge')
      expect(content).toContain('REST API')
      expect(content).toContain('Port 8090')
    })

    it('explains how to start the server', () => {
      expect(content).toContain('Server starten')
      expect(content).toContain('BreakpilotDrive')
      expect(content).toContain('AI Bridge')
    })

    it('documents API endpoints', () => {
      expect(content).toContain('/status')
      expect(content).toContain('/logs')
      expect(content).toContain('/scene')
      expect(content).toContain('/play')
      expect(content).toContain('/diagnose')
    })

    it('explains Claude integration', () => {
      expect(content).toContain('Claude')
      expect(content).toContain('UNITY_BRIDGE.md')
    })

    it('has troubleshooting tips', () => {
      expect(content).toContain('Connection refused')
      expect(content).toContain('Port 8090')
      expect(content).toContain('lsof')
    })
  })
})

// ==============================================
// Architecture Data Tests
// ==============================================

describe('Unity Bridge Architecture Data', () => {
  const architecturePath = join(LIB_DIR, 'architecture-data.ts')
  let content: string

  beforeAll(() => {
    content = readFileSync(architecturePath, 'utf-8')
  })

  it('has unity-bridge service definition', () => {
    expect(content).toContain("'unity-bridge':")
    expect(content).toContain("name: 'Unity AI Bridge'")
  })

  it('defines correct port', () => {
    expect(content).toContain('port: 8090')
  })

  it('has module architecture definition', () => {
    expect(content).toContain("displayName: 'Unity AI Bridge'")
  })

  it('has correct data flow', () => {
    expect(content).toContain('Admin Panel')
    expect(content).toContain('API Proxy')
    expect(content).toContain('Unity Bridge')
    expect(content).toContain('Unity Editor')
  })

  it('has wizard configuration', () => {
    expect(content).toContain("module: 'unity-bridge'")
    expect(content).toContain('steps: 7')
  })
})

// ==============================================
// Navigation Tests
// ==============================================

describe('Admin Layout Navigation', () => {
  const layoutPath = join(COMPONENTS_DIR, 'admin', 'AdminLayout.tsx')
  let content: string

  beforeAll(() => {
    content = readFileSync(layoutPath, 'utf-8')
  })

  it('has Unity Bridge navigation entry', () => {
    expect(content).toContain("name: 'Unity Bridge'")
    expect(content).toContain("href: '/admin/unity-bridge'")
  })

  it('has Unity Bridge description', () => {
    expect(content).toContain('Unity Editor Steuerung')
  })

  it('has Unity Bridge icon (lightning bolt)', () => {
    expect(content).toContain('M13 10V3L4 14h7v7l9-11h-7z')
  })
})

// ==============================================
// Streaming Tests
// ==============================================

describe('Unity Bridge Streaming', () => {
  describe('API Route Streaming Endpoints', () => {
    const apiPath = join(APP_DIR, 'api', 'admin', 'unity-bridge', 'route.ts')
    let content: string

    beforeAll(() => {
      content = readFileSync(apiPath, 'utf-8')
    })

    it('has streaming type definitions', () => {
      expect(content).toContain('interface StreamStatusResponse')
      expect(content).toContain('interface StreamFrameResponse')
    })

    it('supports stream-start action', () => {
      expect(content).toContain("'stream-start': '/stream/start'")
    })

    it('supports stream-stop action', () => {
      expect(content).toContain("'stream-stop': '/stream/stop'")
    })

    it('supports stream-frame action', () => {
      expect(content).toContain("'stream-frame': '/stream/frame'")
    })

    it('supports stream-status action', () => {
      expect(content).toContain("'stream-status': '/stream/status'")
    })

    it('handles screenshot endpoint specially', () => {
      expect(content).toContain("action === 'screenshot'")
      expect(content).toContain('/screenshot')
    })

    it('returns screenshot as binary image', () => {
      expect(content).toContain("'Content-Type': 'image/jpeg'")
      expect(content).toContain('arrayBuffer')
    })

    it('has no-cache headers for screenshot', () => {
      expect(content).toContain('no-cache')
      expect(content).toContain('must-revalidate')
    })

    it('has longer timeout for screenshot', () => {
      // Screenshot should have 5 second timeout
      expect(content).toContain('5000')
    })
  })

  describe('GameView Component', () => {
    const componentPath = join(COMPONENTS_DIR, 'admin', 'GameView.tsx')
    let content: string

    beforeAll(() => {
      content = readFileSync(componentPath, 'utf-8')
    })

    it('exists', () => {
      expect(existsSync(componentPath)).toBe(true)
    })

    it('is a client component', () => {
      expect(content).toContain("'use client'")
    })

    it('has streaming state management', () => {
      expect(content).toContain('isStreaming')
      expect(content).toContain('setIsStreaming')
    })

    it('has frame data state', () => {
      expect(content).toContain('frameData')
      expect(content).toContain('setFrameData')
    })

    it('has FPS tracking', () => {
      expect(content).toContain('fps')
      expect(content).toContain('setFps')
    })

    it('has start streaming function', () => {
      expect(content).toContain('startStreaming')
      expect(content).toContain('stream-start')
    })

    it('has stop streaming function', () => {
      expect(content).toContain('stopStreaming')
      expect(content).toContain('stream-stop')
    })

    it('has screenshot capture function', () => {
      expect(content).toContain('captureScreenshot')
      expect(content).toContain('screenshot')
    })

    it('fetches frames during streaming', () => {
      expect(content).toContain('fetchFrame')
      expect(content).toContain('stream-frame')
    })

    it('has streaming interval of 100ms (10 FPS)', () => {
      expect(content).toContain('100')
      expect(content).toContain('10 FPS')
    })

    it('calculates FPS every second', () => {
      expect(content).toContain('1000')
    })

    it('displays LIVE indicator when streaming', () => {
      expect(content).toContain('LIVE')
      expect(content).toContain('animate-pulse')
    })

    it('displays resolution info', () => {
      expect(content).toContain('Resolution')
      expect(content).toContain('1280x720')
    })

    it('displays quality info', () => {
      expect(content).toContain('Quality')
      expect(content).toContain('75%')
    })

    it('handles offline state', () => {
      expect(content).toContain('isUnityOnline')
      expect(content).toContain('Unity Bridge offline')
    })

    it('has screenshot button', () => {
      expect(content).toContain('Screenshot')
    })

    it('has stream toggle button', () => {
      expect(content).toContain('Stream')
      expect(content).toContain('Stop')
    })

    it('shows loading overlay', () => {
      expect(content).toContain('isLoading')
      expect(content).toContain('animate-spin')
    })

    it('uses aspect-video for game view', () => {
      expect(content).toContain('aspect-video')
    })

    it('shows frame as image', () => {
      expect(content).toContain('<img')
      expect(content).toContain('Unity Game View')
    })
  })

  describe('Dashboard Integration', () => {
    const dashboardPath = join(APP_DIR, 'admin', 'unity-bridge', 'page.tsx')
    let content: string

    beforeAll(() => {
      content = readFileSync(dashboardPath, 'utf-8')
    })

    it('imports GameView component', () => {
      expect(content).toContain("import GameView from '@/components/admin/GameView'")
    })

    it('renders GameView component', () => {
      expect(content).toContain('<GameView')
    })

    it('passes isUnityOnline prop', () => {
      expect(content).toContain('isUnityOnline')
    })

    it('passes isPlaying prop', () => {
      expect(content).toContain('isPlaying')
    })

    it('lists streaming endpoints in API info', () => {
      expect(content).toContain('/screenshot')
      expect(content).toContain('/stream/start')
      expect(content).toContain('/stream/frame')
    })
  })
})

// ==============================================
// Python Backend Proxy Tests
// ==============================================

describe('Unity Bridge Python Backend Proxy', () => {
  const apiPath = join(APP_DIR, 'api', 'admin', 'unity-bridge', 'route.ts')
  let content: string

  beforeAll(() => {
    content = readFileSync(apiPath, 'utf-8')
  })

  describe('Backend Configuration', () => {
    it('has BACKEND_URL constant', () => {
      expect(content).toContain('BACKEND_URL')
      expect(content).toContain('http://localhost:8000')
    })

    it('has BackendType type definition', () => {
      expect(content).toContain("type BackendType = 'unity' | 'python'")
    })

    it('has EndpointConfig interface', () => {
      expect(content).toContain('interface EndpointConfig')
    })

    it('has pythonEndpoints configuration', () => {
      expect(content).toContain('pythonEndpoints')
    })
  })

  describe('Unit API Endpoints', () => {
    it('supports units-list action', () => {
      expect(content).toContain("'units-list'")
      expect(content).toContain('/api/units/definitions')
    })

    it('supports units-get action with unit_id', () => {
      expect(content).toContain("action === 'units-get'")
      expect(content).toContain('unitId')
    })

    it('supports units-health action', () => {
      expect(content).toContain("'units-health'")
      expect(content).toContain('/api/units/health')
    })
  })

  describe('Analytics Endpoints', () => {
    it('supports analytics-overview action', () => {
      expect(content).toContain("'analytics-overview'")
      expect(content).toContain('/api/analytics/dashboard/overview')
    })

    it('supports analytics-misconceptions action', () => {
      expect(content).toContain("'analytics-misconceptions'")
      expect(content).toContain('/api/analytics/misconceptions')
    })

    it('supports analytics-learning-gain action with unit_id', () => {
      expect(content).toContain("action === 'analytics-learning-gain'")
      expect(content).toContain('/api/analytics/learning-gain')
    })

    it('supports analytics-stops action with unit_id', () => {
      expect(content).toContain("action === 'analytics-stops'")
      expect(content).toContain('/api/analytics/unit')
    })

    it('supports time_range parameter for analytics', () => {
      expect(content).toContain('time_range')
      expect(content).toContain('timeRange')
    })
  })

  describe('Teacher Dashboard Endpoints', () => {
    it('supports teacher-dashboard action', () => {
      expect(content).toContain("'teacher-dashboard'")
      expect(content).toContain('/api/teacher/dashboard')
    })

    it('supports teacher-units action', () => {
      expect(content).toContain("'teacher-units'")
      expect(content).toContain('/api/teacher/units/available')
    })
  })

  describe('Content Generation Endpoints', () => {
    it('supports content-h5p action', () => {
      expect(content).toContain("action === 'content-h5p'")
      expect(content).toContain('/h5p')
    })

    it('supports content-worksheet action', () => {
      expect(content).toContain("action === 'content-worksheet'")
      expect(content).toContain('/worksheet')
    })

    it('supports content-pdf action', () => {
      expect(content).toContain("action === 'content-pdf'")
      expect(content).toContain('/worksheet.pdf')
    })
  })

  describe('Helper Functions', () => {
    it('has handlePythonBackend function', () => {
      expect(content).toContain('async function handlePythonBackend')
    })

    it('has fetchFromPython function', () => {
      expect(content).toContain('async function fetchFromPython')
    })

    it('has fetchPdfFromPython function', () => {
      expect(content).toContain('async function fetchPdfFromPython')
    })

    it('fetchPdfFromPython returns PDF with correct headers', () => {
      expect(content).toContain("'Content-Type': 'application/pdf'")
      expect(content).toContain("'Content-Disposition': 'attachment")
    })

    it('has longer timeout for PDF generation', () => {
      expect(content).toContain('15000') // 15 seconds for PDF
    })
  })

  describe('Error Handling for Python Backend', () => {
    it('handles Python backend connection errors', () => {
      expect(content).toContain('Backend nicht erreichbar')
    })

    it('handles Python backend timeout', () => {
      expect(content).toContain('Backend timed out')
    })

    it('returns offline status for Python backend errors', () => {
      // Check that fetchFromPython returns offline: true
      expect(content).toContain('offline: true')
    })
  })
})

// ==============================================
// Tab System Tests
// ==============================================

describe('Unity Bridge Tab System', () => {
  const dashboardPath = join(APP_DIR, 'admin', 'unity-bridge', 'page.tsx')
  let content: string

  beforeAll(() => {
    content = readFileSync(dashboardPath, 'utf-8')
  })

  describe('Tab State Management', () => {
    it('has activeTab state', () => {
      expect(content).toContain('activeTab')
      expect(content).toContain('setActiveTab')
    })

    it('default tab is editor', () => {
      expect(content).toContain("useState<TabId>('editor')")
    })

    it('has TabId type definition', () => {
      expect(content).toContain('TabId')
      expect(content).toContain('editor')
      expect(content).toContain('units')
      expect(content).toContain('sessions')
      expect(content).toContain('analytics')
      expect(content).toContain('content')
    })
  })

  describe('Tab Navigation', () => {
    it('has 5 tabs', () => {
      expect(content).toContain('Editor')
      expect(content).toContain('Units')
      expect(content).toContain('Sessions')
      expect(content).toContain('Analytics')
      expect(content).toContain('Content')
    })

    it('tabs are clickable buttons', () => {
      expect(content).toContain('onClick={() => setActiveTab')
    })

    it('has active tab styling', () => {
      expect(content).toContain('activeTab ===')
    })
  })

  describe('Units Tab', () => {
    it('fetches units from backend', () => {
      expect(content).toContain('fetchUnits')
      expect(content).toContain('units-list')
    })

    it('has units state', () => {
      expect(content).toContain('units')
      expect(content).toContain('setUnits')
    })

    it('has UnitDefinition interface', () => {
      expect(content).toContain('interface UnitDefinition')
    })

    it('has unit_id field', () => {
      expect(content).toContain('unit_id')
    })

    it('has template field', () => {
      expect(content).toContain('template')
    })

    it('has learning_objectives field', () => {
      expect(content).toContain('learning_objectives')
    })

    it('has stops field', () => {
      expect(content).toContain('stops')
    })

    it('can fetch unit details', () => {
      expect(content).toContain('fetchUnitDetails')
      expect(content).toContain('units-get')
    })

    it('has selectedUnit state', () => {
      expect(content).toContain('selectedUnit')
      expect(content).toContain('setSelectedUnit')
    })
  })

  describe('Analytics Tab', () => {
    it('fetches analytics from backend', () => {
      expect(content).toContain('fetchAnalytics')
      expect(content).toContain('analytics-overview')
    })

    it('has analytics state', () => {
      expect(content).toContain('analytics')
      expect(content).toContain('setAnalytics')
    })

    it('has AnalyticsOverview interface', () => {
      expect(content).toContain('interface AnalyticsOverview')
    })

    it('has total_sessions field', () => {
      expect(content).toContain('total_sessions')
    })

    it('has unique_students field', () => {
      expect(content).toContain('unique_students')
    })

    it('has avg_completion_rate field', () => {
      expect(content).toContain('avg_completion_rate')
    })

    it('has avg_learning_gain field', () => {
      expect(content).toContain('avg_learning_gain')
    })

    it('has most_played_units field', () => {
      expect(content).toContain('most_played_units')
    })

    it('has struggling_concepts field', () => {
      expect(content).toContain('struggling_concepts')
    })
  })

  describe('Content Tab', () => {
    it('can generate H5P content', () => {
      expect(content).toContain('generateH5P')
      expect(content).toContain('content-h5p')
    })

    it('can generate worksheet', () => {
      expect(content).toContain('generateWorksheet')
      expect(content).toContain('content-worksheet')
    })

    it('can download PDF', () => {
      expect(content).toContain('downloadPdf')
      expect(content).toContain('content-pdf')
    })

    it('has generatedContent state', () => {
      expect(content).toContain('generatedContent')
      expect(content).toContain('setGeneratedContent')
    })

    it('has GeneratedContent interface', () => {
      expect(content).toContain('interface GeneratedContent')
    })
  })

  describe('Sessions Tab', () => {
    it('renders sessions tab content', () => {
      expect(content).toContain("activeTab === 'sessions'")
    })

    it('has sessions placeholder or content', () => {
      // Sessions tab exists in the tab switch
      expect(content).toContain('sessions')
    })
  })
})
