/**
 * Worksheet Cleanup Service
 *
 * API client for the worksheet cleanup endpoints:
 * - Handwriting detection
 * - Handwriting removal (inpainting)
 * - Layout reconstruction
 *
 * All processing happens on the local Mac Mini server.
 */

export interface CleanupCapabilities {
  opencv_available: boolean
  lama_available: boolean
  paddleocr_available: boolean
}

export interface DetectionResult {
  has_handwriting: boolean
  confidence: number
  handwriting_ratio: number
  detection_method: string
  mask_base64?: string
}

export interface PreviewResult {
  has_handwriting: boolean
  confidence: number
  handwriting_ratio: number
  image_width: number
  image_height: number
  estimated_times_ms: {
    detection: number
    inpainting: number
    reconstruction: number
    total: number
  }
  capabilities: {
    lama_available: boolean
  }
}

export interface PipelineResult {
  success: boolean
  handwriting_detected: boolean
  handwriting_removed: boolean
  layout_reconstructed: boolean
  cleaned_image_base64?: string
  fabric_json?: any
  metadata: {
    detection?: {
      confidence: number
      handwriting_ratio: number
      method: string
    }
    inpainting?: {
      method_used: string
      processing_time_ms: number
    }
    layout?: {
      element_count: number
      table_count: number
      page_width: number
      page_height: number
    }
  }
}

export type InpaintingMethod = 'auto' | 'opencv_telea' | 'opencv_ns' | 'lama'

export interface CleanupOptions {
  removeHandwriting: boolean
  reconstructLayout: boolean
  inpaintingMethod: InpaintingMethod
}

/**
 * Get the API base URL for the klausur-service
 */
function getApiUrl(): string {
  if (typeof window === 'undefined') return 'http://localhost:8086'
  const { hostname, protocol } = window.location
  return hostname === 'localhost' ? 'http://localhost:8086' : `${protocol}//${hostname}:8086`
}

/**
 * Get available cleanup capabilities on the server
 */
export async function getCapabilities(): Promise<CleanupCapabilities> {
  const response = await fetch(`${getApiUrl()}/api/v1/worksheet/capabilities`)

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

  return response.json()
}

/**
 * Quick preview of cleanup without full processing
 */
export async function previewCleanup(file: File): Promise<PreviewResult> {
  const formData = new FormData()
  formData.append('image', file)

  const response = await fetch(`${getApiUrl()}/api/v1/worksheet/preview-cleanup`, {
    method: 'POST',
    body: formData
  })

  if (!response.ok) {
    const error = await response.json().catch(() => ({ detail: 'Unknown error' }))
    throw new Error(error.detail || `HTTP ${response.status}`)
  }

  return response.json()
}

/**
 * Detect handwriting in an image
 */
export async function detectHandwriting(
  file: File,
  options: { returnMask?: boolean; minConfidence?: number } = {}
): Promise<DetectionResult> {
  const formData = new FormData()
  formData.append('image', file)
  formData.append('return_mask', String(options.returnMask ?? true))
  formData.append('min_confidence', String(options.minConfidence ?? 0.3))

  const response = await fetch(`${getApiUrl()}/api/v1/worksheet/detect-handwriting`, {
    method: 'POST',
    body: formData
  })

  if (!response.ok) {
    const error = await response.json().catch(() => ({ detail: 'Unknown error' }))
    throw new Error(error.detail || `HTTP ${response.status}`)
  }

  return response.json()
}

/**
 * Get the handwriting detection mask as an image blob
 */
export async function getHandwritingMask(file: File): Promise<Blob> {
  const formData = new FormData()
  formData.append('image', file)

  const response = await fetch(`${getApiUrl()}/api/v1/worksheet/detect-handwriting/mask`, {
    method: 'POST',
    body: formData
  })

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

  return response.blob()
}

/**
 * Remove handwriting from an image
 */
export async function removeHandwriting(
  file: File,
  options: {
    mask?: File
    method?: InpaintingMethod
    returnBase64?: boolean
  } = {}
): Promise<{ imageBlob?: Blob; imageBase64?: string; metadata: any }> {
  const formData = new FormData()
  formData.append('image', file)
  formData.append('method', options.method ?? 'auto')
  formData.append('return_base64', String(options.returnBase64 ?? false))

  if (options.mask) {
    formData.append('mask', options.mask)
  }

  const response = await fetch(`${getApiUrl()}/api/v1/worksheet/remove-handwriting`, {
    method: 'POST',
    body: formData
  })

  if (!response.ok) {
    const error = await response.json().catch(() => ({ detail: 'Unknown error' }))
    throw new Error(error.detail || `HTTP ${response.status}`)
  }

  if (options.returnBase64) {
    const data = await response.json()
    return {
      imageBase64: data.image_base64,
      metadata: data.metadata
    }
  } else {
    const imageBlob = await response.blob()
    const methodUsed = response.headers.get('X-Method-Used') || 'unknown'
    const processingTime = parseFloat(response.headers.get('X-Processing-Time-Ms') || '0')

    return {
      imageBlob,
      metadata: {
        method_used: methodUsed,
        processing_time_ms: processingTime
      }
    }
  }
}

/**
 * Run the full cleanup pipeline
 */
export async function runCleanupPipeline(
  file: File,
  options: CleanupOptions = {
    removeHandwriting: true,
    reconstructLayout: true,
    inpaintingMethod: 'auto'
  }
): Promise<PipelineResult> {
  const formData = new FormData()
  formData.append('image', file)
  formData.append('remove_handwriting', String(options.removeHandwriting))
  formData.append('reconstruct', String(options.reconstructLayout))
  formData.append('inpainting_method', options.inpaintingMethod)

  const response = await fetch(`${getApiUrl()}/api/v1/worksheet/cleanup-pipeline`, {
    method: 'POST',
    body: formData
  })

  if (!response.ok) {
    const error = await response.json().catch(() => ({ detail: 'Unknown error' }))
    throw new Error(error.detail || `HTTP ${response.status}`)
  }

  return response.json()
}

/**
 * Helper to convert base64 to blob
 */
export function base64ToBlob(base64: string, mimeType: string = 'image/png'): Blob {
  const byteCharacters = atob(base64)
  const byteArrays = []

  for (let offset = 0; offset < byteCharacters.length; offset += 512) {
    const slice = byteCharacters.slice(offset, offset + 512)
    const byteNumbers = new Array(slice.length)

    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i)
    }

    const byteArray = new Uint8Array(byteNumbers)
    byteArrays.push(byteArray)
  }

  return new Blob(byteArrays, { type: mimeType })
}

/**
 * Helper to create object URL from base64
 */
export function base64ToObjectUrl(base64: string, mimeType: string = 'image/png'): string {
  const blob = base64ToBlob(base64, mimeType)
  return URL.createObjectURL(blob)
}
