import { NextRequest, NextResponse } from 'next/server'
import type { WoodpeckerWebhookPayload, ExtractedError, BacklogSource } from '@/types/infrastructure-modules'

// =============================================================================
// Configuration
// =============================================================================

// Webhook secret for verification (optional but recommended)
const WEBHOOK_SECRET = process.env.WOODPECKER_WEBHOOK_SECRET || ''

// Internal API URL for log extraction
const LOG_EXTRACT_URL = process.env.NEXT_PUBLIC_APP_URL
  ? `${process.env.NEXT_PUBLIC_APP_URL}/api/infrastructure/log-extract/extract`
  : 'http://localhost:3002/api/infrastructure/log-extract/extract'

// Test service API URL for backlog insertion
const TEST_SERVICE_URL = process.env.TEST_SERVICE_URL || 'http://localhost:8002'

// =============================================================================
// Helper Functions
// =============================================================================

/**
 * Verify webhook signature (if secret is configured)
 */
function verifySignature(request: NextRequest, body: string): boolean {
  if (!WEBHOOK_SECRET) return true // Skip verification if no secret configured

  const signature = request.headers.get('X-Woodpecker-Signature')
  if (!signature) return false

  // Simple HMAC verification (Woodpecker uses SHA256)
  const crypto = require('crypto')
  const expectedSignature = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(body)
    .digest('hex')

  return signature === `sha256=${expectedSignature}`
}

/**
 * Map error category to backlog priority
 */
function categoryToPriority(category: string): 'critical' | 'high' | 'medium' | 'low' {
  switch (category) {
    case 'security_warning':
      return 'critical'
    case 'build_error':
      return 'high'
    case 'license_violation':
      return 'high'
    case 'test_failure':
      return 'medium'
    case 'dependency_issue':
      return 'low'
    default:
      return 'medium'
  }
}

/**
 * Map error category to error_type for backlog
 */
function categoryToErrorType(category: string): string {
  switch (category) {
    case 'security_warning':
      return 'security'
    case 'build_error':
      return 'build'
    case 'license_violation':
      return 'license'
    case 'test_failure':
      return 'test'
    case 'dependency_issue':
      return 'dependency'
    default:
      return 'unknown'
  }
}

/**
 * Insert extracted errors into backlog
 */
async function insertIntoBacklog(
  errors: ExtractedError[],
  pipelineNumber: number,
  source: BacklogSource
): Promise<{ inserted: number; failed: number }> {
  let inserted = 0
  let failed = 0

  for (const error of errors) {
    try {
      // Create backlog item
      const backlogItem = {
        test_name: error.message.substring(0, 200), // Truncate long messages
        test_file: error.file_path || null,
        service: error.service || 'unknown',
        framework: `ci_cd_pipeline_${pipelineNumber}`,
        error_message: error.message,
        error_type: categoryToErrorType(error.category),
        status: 'open',
        priority: categoryToPriority(error.category),
        fix_suggestion: error.suggested_fix || null,
        notes: `Auto-generated from pipeline #${pipelineNumber}, step: ${error.step}, line: ${error.line}`,
        source, // Custom field to track origin
      }

      // Try to insert into test service backlog
      const response = await fetch(`${TEST_SERVICE_URL}/api/v1/backlog`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(backlogItem),
      })

      if (response.ok) {
        inserted++
      } else {
        console.warn(`Failed to insert backlog item: ${response.status}`)
        failed++
      }
    } catch (insertError) {
      console.error('Backlog insertion error:', insertError)
      failed++
    }
  }

  return { inserted, failed }
}

// =============================================================================
// API Handler
// =============================================================================

/**
 * POST /api/webhooks/woodpecker
 *
 * Webhook endpoint fuer Woodpecker CI/CD Events.
 *
 * Bei Pipeline-Failure:
 * 1. Extrahiert Logs mit /api/infrastructure/logs/extract
 * 2. Parsed Fehler nach Kategorie
 * 3. Traegt automatisch in Backlog ein
 *
 * Request Body (Woodpecker Webhook Format):
 * - event: 'pipeline_success' | 'pipeline_failure' | 'pipeline_started'
 * - repo_id: number
 * - pipeline_number: number
 * - branch?: string
 * - commit?: string
 * - author?: string
 * - message?: string
 */
export async function POST(request: NextRequest) {
  try {
    const bodyText = await request.text()

    // Verify webhook signature
    if (!verifySignature(request, bodyText)) {
      return NextResponse.json(
        { error: 'Invalid webhook signature' },
        { status: 401 }
      )
    }

    const payload: WoodpeckerWebhookPayload = JSON.parse(bodyText)

    // Log all events for debugging
    console.log(`Woodpecker webhook: ${payload.event} for pipeline #${payload.pipeline_number}`)

    // Only process pipeline_failure events
    if (payload.event !== 'pipeline_failure') {
      return NextResponse.json({
        status: 'ignored',
        message: `Event ${payload.event} wird nicht verarbeitet`,
        pipeline_number: payload.pipeline_number,
      })
    }

    // 1. Extract logs from failed pipeline
    console.log(`Extracting logs for failed pipeline #${payload.pipeline_number}`)

    const extractResponse = await fetch(LOG_EXTRACT_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        pipeline_number: payload.pipeline_number,
        repo_id: String(payload.repo_id),
      }),
    })

    if (!extractResponse.ok) {
      const errorText = await extractResponse.text()
      console.error('Log extraction failed:', errorText)
      return NextResponse.json({
        status: 'error',
        message: 'Log-Extraktion fehlgeschlagen',
        pipeline_number: payload.pipeline_number,
      }, { status: 500 })
    }

    const extractionResult = await extractResponse.json()
    const errors: ExtractedError[] = extractionResult.errors || []

    console.log(`Extracted ${errors.length} errors from pipeline #${payload.pipeline_number}`)

    // 2. Insert errors into backlog
    if (errors.length > 0) {
      const backlogResult = await insertIntoBacklog(
        errors,
        payload.pipeline_number,
        'ci_cd'
      )

      console.log(`Backlog: ${backlogResult.inserted} inserted, ${backlogResult.failed} failed`)

      return NextResponse.json({
        status: 'processed',
        pipeline_number: payload.pipeline_number,
        branch: payload.branch,
        commit: payload.commit,
        errors_found: errors.length,
        backlog_inserted: backlogResult.inserted,
        backlog_failed: backlogResult.failed,
        categories: {
          test_failure: errors.filter(e => e.category === 'test_failure').length,
          build_error: errors.filter(e => e.category === 'build_error').length,
          security_warning: errors.filter(e => e.category === 'security_warning').length,
          license_violation: errors.filter(e => e.category === 'license_violation').length,
          dependency_issue: errors.filter(e => e.category === 'dependency_issue').length,
        },
      })
    }

    return NextResponse.json({
      status: 'processed',
      pipeline_number: payload.pipeline_number,
      message: 'Keine Fehler extrahiert',
      errors_found: 0,
    })

  } catch (error) {
    console.error('Webhook processing error:', error)
    return NextResponse.json(
      { error: 'Webhook-Verarbeitung fehlgeschlagen' },
      { status: 500 }
    )
  }
}

/**
 * GET /api/webhooks/woodpecker
 *
 * Health check endpoint
 */
export async function GET() {
  return NextResponse.json({
    status: 'ready',
    endpoint: '/api/webhooks/woodpecker',
    events: ['pipeline_failure'],
    description: 'Woodpecker CI/CD Webhook Handler',
    configured: {
      webhook_secret: WEBHOOK_SECRET ? 'yes' : 'no',
      log_extract_url: LOG_EXTRACT_URL,
      test_service_url: TEST_SERVICE_URL,
    },
  })
}
