/**
 * Whistleblower API Client — CRUD, Workflow, Messaging, Attachments, Statistics
 *
 * API client for Hinweisgeberschutzgesetz (HinSchG) compliant
 * Whistleblower/Hinweisgebersystem management
 */

import {
  WhistleblowerReport,
  WhistleblowerStatistics,
  ReportListResponse,
  ReportFilters,
  PublicReportSubmission,
  ReportUpdateRequest,
  AnonymousMessage,
  WhistleblowerMeasure,
  FileAttachment,
} from './types'

// =============================================================================
// CONFIGURATION
// =============================================================================

// Use compliance backend proxy (Python) instead of Go SDK
const WB_API_BASE = '/api/sdk/v1/compliance'
const API_TIMEOUT = 30000

// =============================================================================
// HELPER FUNCTIONS
// =============================================================================

function getTenantId(): string {
  if (typeof window !== 'undefined') {
    return localStorage.getItem('bp_tenant_id') || 'default-tenant'
  }
  return 'default-tenant'
}

function getAuthHeaders(): HeadersInit {
  const headers: HeadersInit = {
    'Content-Type': 'application/json',
    'X-Tenant-ID': getTenantId()
  }

  if (typeof window !== 'undefined') {
    const token = localStorage.getItem('authToken')
    if (token) {
      headers['Authorization'] = `Bearer ${token}`
    }
    const userId = localStorage.getItem('bp_user_id')
    if (userId) {
      headers['X-User-ID'] = userId
    }
  }

  return headers
}

async function fetchWithTimeout<T>(
  url: string,
  options: RequestInit = {},
  timeout: number = API_TIMEOUT
): Promise<T> {
  const controller = new AbortController()
  const timeoutId = setTimeout(() => controller.abort(), timeout)

  try {
    const response = await fetch(url, {
      ...options,
      signal: controller.signal,
      headers: {
        ...getAuthHeaders(),
        ...options.headers
      }
    })

    if (!response.ok) {
      const errorBody = await response.text()
      let errorMessage = `HTTP ${response.status}: ${response.statusText}`
      try {
        const errorJson = JSON.parse(errorBody)
        errorMessage = errorJson.error || errorJson.message || errorMessage
      } catch {
        // Keep the HTTP status message
      }
      throw new Error(errorMessage)
    }

    const contentType = response.headers.get('content-type')
    if (contentType && contentType.includes('application/json')) {
      return response.json()
    }

    return {} as T
  } finally {
    clearTimeout(timeoutId)
  }
}

// =============================================================================
// ADMIN CRUD - Reports
// =============================================================================

export async function fetchReports(filters?: ReportFilters): Promise<ReportListResponse> {
  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.category) {
      const categories = Array.isArray(filters.category) ? filters.category : [filters.category]
      categories.forEach(c => params.append('category', c))
    }
    if (filters.priority) params.set('priority', filters.priority)
    if (filters.assignedTo) params.set('assignedTo', filters.assignedTo)
    if (filters.isAnonymous !== undefined) params.set('isAnonymous', String(filters.isAnonymous))
    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 = `${WB_API_BASE}/whistleblower/reports${queryString ? `?${queryString}` : ''}`

  return fetchWithTimeout<ReportListResponse>(url)
}

export async function fetchReport(id: string): Promise<WhistleblowerReport> {
  return fetchWithTimeout<WhistleblowerReport>(
    `${WB_API_BASE}/whistleblower/reports/${id}`
  )
}

export async function updateReport(id: string, update: ReportUpdateRequest): Promise<WhistleblowerReport> {
  return fetchWithTimeout<WhistleblowerReport>(
    `${WB_API_BASE}/whistleblower/reports/${id}`,
    { method: 'PUT', body: JSON.stringify(update) }
  )
}

export async function deleteReport(id: string): Promise<void> {
  await fetchWithTimeout<void>(
    `${WB_API_BASE}/whistleblower/reports/${id}`,
    { method: 'DELETE' }
  )
}

// =============================================================================
// PUBLIC ENDPOINTS
// =============================================================================

export async function submitPublicReport(
  data: PublicReportSubmission
): Promise<{ report: WhistleblowerReport; accessKey: string }> {
  const response = await fetch(
    `${WB_API_BASE}/whistleblower/submit`,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    }
  )

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`)
  }

  return response.json()
}

export async function fetchReportByAccessKey(
  accessKey: string
): Promise<WhistleblowerReport> {
  const response = await fetch(
    `${WB_API_BASE}/whistleblower/check/${accessKey}`,
    { method: 'GET', headers: { 'Content-Type': 'application/json' } }
  )

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`)
  }

  return response.json()
}

// =============================================================================
// WORKFLOW ACTIONS
// =============================================================================

export async function acknowledgeReport(id: string): Promise<WhistleblowerReport> {
  return fetchWithTimeout<WhistleblowerReport>(
    `${WB_API_BASE}/whistleblower/reports/${id}/acknowledge`,
    { method: 'POST' }
  )
}

export async function startInvestigation(id: string): Promise<WhistleblowerReport> {
  return fetchWithTimeout<WhistleblowerReport>(
    `${WB_API_BASE}/whistleblower/reports/${id}/investigate`,
    { method: 'POST' }
  )
}

export async function addMeasure(
  id: string,
  measure: Omit<WhistleblowerMeasure, 'id' | 'reportId' | 'completedAt'>
): Promise<WhistleblowerMeasure> {
  return fetchWithTimeout<WhistleblowerMeasure>(
    `${WB_API_BASE}/whistleblower/reports/${id}/measures`,
    { method: 'POST', body: JSON.stringify(measure) }
  )
}

export async function closeReport(
  id: string,
  resolution: { reason: string; notes: string }
): Promise<WhistleblowerReport> {
  return fetchWithTimeout<WhistleblowerReport>(
    `${WB_API_BASE}/whistleblower/reports/${id}/close`,
    { method: 'POST', body: JSON.stringify(resolution) }
  )
}

// =============================================================================
// ANONYMOUS MESSAGING
// =============================================================================

export async function sendMessage(
  reportId: string,
  message: string,
  role: 'reporter' | 'ombudsperson'
): Promise<AnonymousMessage> {
  return fetchWithTimeout<AnonymousMessage>(
    `${WB_API_BASE}/whistleblower/reports/${reportId}/messages`,
    { method: 'POST', body: JSON.stringify({ senderRole: role, message }) }
  )
}

export async function fetchMessages(reportId: string): Promise<AnonymousMessage[]> {
  return fetchWithTimeout<AnonymousMessage[]>(
    `${WB_API_BASE}/whistleblower/reports/${reportId}/messages`
  )
}

// =============================================================================
// ATTACHMENTS
// =============================================================================

export async function uploadAttachment(
  reportId: string,
  file: File
): Promise<FileAttachment> {
  const formData = new FormData()
  formData.append('file', file)

  const controller = new AbortController()
  const timeoutId = setTimeout(() => controller.abort(), 60000)

  try {
    const headers: HeadersInit = {
      'X-Tenant-ID': getTenantId()
    }
    if (typeof window !== 'undefined') {
      const token = localStorage.getItem('authToken')
      if (token) {
        headers['Authorization'] = `Bearer ${token}`
      }
    }

    const response = await fetch(
      `${WB_API_BASE}/whistleblower/reports/${reportId}/attachments`,
      {
        method: 'POST',
        headers,
        body: formData,
        signal: controller.signal
      }
    )

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

    return response.json()
  } finally {
    clearTimeout(timeoutId)
  }
}

export async function deleteAttachment(id: string): Promise<void> {
  await fetchWithTimeout<void>(
    `${WB_API_BASE}/whistleblower/attachments/${id}`,
    { method: 'DELETE' }
  )
}

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

export async function fetchWhistleblowerStatistics(): Promise<WhistleblowerStatistics> {
  return fetchWithTimeout<WhistleblowerStatistics>(
    `${WB_API_BASE}/whistleblower/reports/stats`
  )
}
