/**
 * Incident CRUD, Risk Assessment, Notifications, Measures, Timeline, Statistics
 */

import {
  Incident,
  IncidentListResponse,
  IncidentFilters,
  IncidentCreateRequest,
  IncidentUpdateRequest,
  IncidentStatistics,
  IncidentMeasure,
  TimelineEntry,
  RiskAssessmentRequest,
  AuthorityNotification,
  DataSubjectNotification,
  IncidentSeverity,
  IncidentStatus,
  IncidentCategory,
} from './types'

import { INCIDENTS_API_BASE, fetchWithTimeout, getAuthHeaders } from './api-helpers'

// =============================================================================
// INCIDENT LIST & CRUD
// =============================================================================

/**
 * Alle Vorfaelle abrufen mit optionalen Filtern
 */
export async function fetchIncidents(filters?: IncidentFilters): Promise<IncidentListResponse> {
  const params = new URLSearchParams()

  if (filters) {
    if (filters.status) {
      const statuses = Array.isArray(filters.status) ? filters.status : [filters.status]
      statuses.forEach(s => params.append('status', s))
    }
    if (filters.severity) {
      const severities = Array.isArray(filters.severity) ? filters.severity : [filters.severity]
      severities.forEach(s => params.append('severity', s))
    }
    if (filters.category) {
      const categories = Array.isArray(filters.category) ? filters.category : [filters.category]
      categories.forEach(c => params.append('category', c))
    }
    if (filters.assignedTo) params.set('assignedTo', filters.assignedTo)
    if (filters.overdue !== undefined) params.set('overdue', String(filters.overdue))
    if (filters.search) params.set('search', filters.search)
    if (filters.dateFrom) params.set('dateFrom', filters.dateFrom)
    if (filters.dateTo) params.set('dateTo', filters.dateTo)
  }

  const queryString = params.toString()
  const url = `${INCIDENTS_API_BASE}/api/v1/incidents${queryString ? `?${queryString}` : ''}`

  return fetchWithTimeout<IncidentListResponse>(url)
}

/**
 * Einzelnen Vorfall per ID abrufen
 */
export async function fetchIncident(id: string): Promise<Incident> {
  return fetchWithTimeout<Incident>(`${INCIDENTS_API_BASE}/api/v1/incidents/${id}`)
}

/**
 * Neuen Vorfall erstellen
 */
export async function createIncident(request: IncidentCreateRequest): Promise<Incident> {
  return fetchWithTimeout<Incident>(`${INCIDENTS_API_BASE}/api/v1/incidents`, {
    method: 'POST',
    body: JSON.stringify(request)
  })
}

/**
 * Vorfall aktualisieren
 */
export async function updateIncident(id: string, update: IncidentUpdateRequest): Promise<Incident> {
  return fetchWithTimeout<Incident>(`${INCIDENTS_API_BASE}/api/v1/incidents/${id}`, {
    method: 'PUT',
    body: JSON.stringify(update)
  })
}

/**
 * Vorfall loeschen (Soft Delete)
 */
export async function deleteIncident(id: string): Promise<void> {
  await fetchWithTimeout<void>(`${INCIDENTS_API_BASE}/api/v1/incidents/${id}`, {
    method: 'DELETE'
  })
}

// =============================================================================
// RISK ASSESSMENT
// =============================================================================

/**
 * Risikobewertung fuer einen Vorfall durchfuehren (Art. 33 DSGVO)
 */
export async function submitRiskAssessment(
  incidentId: string,
  assessment: RiskAssessmentRequest
): Promise<Incident> {
  return fetchWithTimeout<Incident>(
    `${INCIDENTS_API_BASE}/api/v1/incidents/${incidentId}/risk-assessment`,
    {
      method: 'POST',
      body: JSON.stringify(assessment)
    }
  )
}

// =============================================================================
// AUTHORITY NOTIFICATION (Art. 33 DSGVO)
// =============================================================================

/**
 * Meldeformular fuer die Aufsichtsbehoerde generieren
 */
export async function generateAuthorityForm(incidentId: string): Promise<Blob> {
  const response = await fetch(
    `${INCIDENTS_API_BASE}/api/v1/incidents/${incidentId}/authority-form/pdf`,
    {
      headers: getAuthHeaders()
    }
  )

  if (!response.ok) {
    throw new Error(`PDF-Generierung fehlgeschlagen: ${response.statusText}`)
  }

  return response.blob()
}

/**
 * Meldung an die Aufsichtsbehoerde einreichen (Art. 33 DSGVO)
 */
export async function submitAuthorityNotification(
  incidentId: string,
  data: Partial<AuthorityNotification>
): Promise<Incident> {
  return fetchWithTimeout<Incident>(
    `${INCIDENTS_API_BASE}/api/v1/incidents/${incidentId}/authority-notification`,
    {
      method: 'POST',
      body: JSON.stringify(data)
    }
  )
}

// =============================================================================
// DATA SUBJECT NOTIFICATION (Art. 34 DSGVO)
// =============================================================================

/**
 * Betroffene Personen benachrichtigen (Art. 34 DSGVO)
 */
export async function sendDataSubjectNotification(
  incidentId: string,
  data: Partial<DataSubjectNotification>
): Promise<Incident> {
  return fetchWithTimeout<Incident>(
    `${INCIDENTS_API_BASE}/api/v1/incidents/${incidentId}/data-subject-notification`,
    {
      method: 'POST',
      body: JSON.stringify(data)
    }
  )
}

// =============================================================================
// MEASURES (Massnahmen)
// =============================================================================

/**
 * Massnahme hinzufuegen (Sofort-, Korrektur- oder Praeventionsmassnahme)
 */
export async function addMeasure(
  incidentId: string,
  measure: Omit<IncidentMeasure, 'id' | 'incidentId'>
): Promise<Incident> {
  return fetchWithTimeout<Incident>(
    `${INCIDENTS_API_BASE}/api/v1/incidents/${incidentId}/measures`,
    {
      method: 'POST',
      body: JSON.stringify(measure)
    }
  )
}

/**
 * Massnahme aktualisieren
 */
export async function updateMeasure(
  measureId: string,
  update: Partial<IncidentMeasure>
): Promise<IncidentMeasure> {
  return fetchWithTimeout<IncidentMeasure>(
    `${INCIDENTS_API_BASE}/api/v1/measures/${measureId}`,
    {
      method: 'PUT',
      body: JSON.stringify(update)
    }
  )
}

/**
 * Massnahme als abgeschlossen markieren
 */
export async function completeMeasure(measureId: string): Promise<IncidentMeasure> {
  return fetchWithTimeout<IncidentMeasure>(
    `${INCIDENTS_API_BASE}/api/v1/measures/${measureId}/complete`,
    {
      method: 'POST'
    }
  )
}

// =============================================================================
// TIMELINE
// =============================================================================

/**
 * Zeitleisteneintrag hinzufuegen
 */
export async function addTimelineEntry(
  incidentId: string,
  entry: Omit<TimelineEntry, 'id' | 'incidentId'>
): Promise<Incident> {
  return fetchWithTimeout<Incident>(
    `${INCIDENTS_API_BASE}/api/v1/incidents/${incidentId}/timeline`,
    {
      method: 'POST',
      body: JSON.stringify(entry)
    }
  )
}

// =============================================================================
// CLOSE INCIDENT
// =============================================================================

/**
 * Vorfall abschliessen mit Lessons Learned
 */
export async function closeIncident(
  incidentId: string,
  lessonsLearned: string
): Promise<Incident> {
  return fetchWithTimeout<Incident>(
    `${INCIDENTS_API_BASE}/api/v1/incidents/${incidentId}/close`,
    {
      method: 'POST',
      body: JSON.stringify({ lessonsLearned })
    }
  )
}

// =============================================================================
// STATISTICS
// =============================================================================

/**
 * Vorfall-Statistiken abrufen
 */
export async function fetchIncidentStatistics(): Promise<IncidentStatistics> {
  return fetchWithTimeout<IncidentStatistics>(
    `${INCIDENTS_API_BASE}/api/v1/incidents/statistics`
  )
}

// =============================================================================
// SDK PROXY FUNCTION (mit Fallback auf Mock-Daten)
// =============================================================================

/**
 * Fetch Incident-Liste via SDK-Proxy mit Fallback auf Mock-Daten
 */
export async function fetchSDKIncidentList(): Promise<{ incidents: Incident[]; statistics: IncidentStatistics }> {
  try {
    const res = await fetch('/api/sdk/v1/incidents', {
      headers: getAuthHeaders()
    })
    if (!res.ok) {
      throw new Error(`HTTP ${res.status}`)
    }
    const data = await res.json()
    const incidents: Incident[] = data.incidents || []

    const statistics = computeStatistics(incidents)
    return { incidents, statistics }
  } catch (error) {
    console.warn('SDK-Backend nicht erreichbar, verwende Mock-Daten:', error)
    // Import mock data lazily to keep this file lean
    const { createMockIncidents, createMockStatistics } = await import('./api-mock')
    const incidents = createMockIncidents()
    const statistics = createMockStatistics()
    return { incidents, statistics }
  }
}

/**
 * Statistiken lokal aus Incident-Liste berechnen
 */
function computeStatistics(incidents: Incident[]): IncidentStatistics {
  const countBy = <K extends string>(items: { [key: string]: unknown }[], field: string): Record<K, number> => {
    const result: Record<string, number> = {}
    items.forEach(item => {
      const key = String(item[field])
      result[key] = (result[key] || 0) + 1
    })
    return result as Record<K, number>
  }

  const statusCounts = countBy<IncidentStatus>(incidents as unknown as { [key: string]: unknown }[], 'status')
  const severityCounts = countBy<IncidentSeverity>(incidents as unknown as { [key: string]: unknown }[], 'severity')
  const categoryCounts = countBy<IncidentCategory>(incidents as unknown as { [key: string]: unknown }[], 'category')

  const openIncidents = incidents.filter(i => i.status !== 'closed').length
  const notificationsPending = incidents.filter(i =>
    i.authorityNotification !== null &&
    i.authorityNotification.status === 'pending' &&
    i.status !== 'closed'
  ).length

  let totalResponseHours = 0
  let respondedCount = 0
  incidents.forEach(i => {
    if (i.riskAssessment && i.riskAssessment.assessedAt) {
      const detected = new Date(i.detectedAt).getTime()
      const assessed = new Date(i.riskAssessment.assessedAt).getTime()
      totalResponseHours += (assessed - detected) / (1000 * 60 * 60)
      respondedCount++
    }
  })

  return {
    totalIncidents: incidents.length,
    openIncidents,
    notificationsPending,
    averageResponseTimeHours: respondedCount > 0 ? Math.round(totalResponseHours / respondedCount * 10) / 10 : 0,
    bySeverity: {
      low: severityCounts['low'] || 0,
      medium: severityCounts['medium'] || 0,
      high: severityCounts['high'] || 0,
      critical: severityCounts['critical'] || 0
    },
    byCategory: {
      data_breach: categoryCounts['data_breach'] || 0,
      unauthorized_access: categoryCounts['unauthorized_access'] || 0,
      data_loss: categoryCounts['data_loss'] || 0,
      system_compromise: categoryCounts['system_compromise'] || 0,
      phishing: categoryCounts['phishing'] || 0,
      ransomware: categoryCounts['ransomware'] || 0,
      insider_threat: categoryCounts['insider_threat'] || 0,
      physical_breach: categoryCounts['physical_breach'] || 0,
      other: categoryCounts['other'] || 0
    },
    byStatus: {
      detected: statusCounts['detected'] || 0,
      assessment: statusCounts['assessment'] || 0,
      containment: statusCounts['containment'] || 0,
      notification_required: statusCounts['notification_required'] || 0,
      notification_sent: statusCounts['notification_sent'] || 0,
      remediation: statusCounts['remediation'] || 0,
      closed: statusCounts['closed'] || 0
    }
  }
}
