'use client'

import { useState, useEffect } from 'react'

export interface FailureMode {
  id: string
  component_type: string
  mode: string
  name_de: string
  name_en: string
  effect: string
  detection_hint: string
  default_severity: number
  default_occurrence: number
  default_detection: number
}

export interface Component {
  id: string
  name: string
  component_type: string
}

export interface FMEARow {
  component: Component
  failureMode: FailureMode
  severity: number
  occurrence: number
  detection: number
  rpz: number
  ap: 'H' | 'M' | 'L'
}

/** AIAG-VDA Action Priority (2019 Handbook) */
export function calculateAP(s: number, o: number, d: number): 'H' | 'M' | 'L' {
  if (s >= 9) return (o >= 4 || d >= 7) ? 'H' : (o >= 2 || d >= 5) ? 'M' : 'L'
  if (s >= 7) return (o >= 5 || d >= 8) ? 'H' : (o >= 3 || d >= 5) ? 'M' : 'L'
  if (s >= 5) return (o >= 7 || d >= 9) ? 'H' : (o >= 4 || d >= 7) ? 'M' : 'L'
  return (o >= 8 && d >= 9) ? 'H' : (o >= 6 || d >= 8) ? 'M' : 'L'
}

export function useFMEA(projectId: string) {
  const [rows, setRows] = useState<FMEARow[]>([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    loadData()
  }, [projectId]) // eslint-disable-line react-hooks/exhaustive-deps

  async function loadData() {
    try {
      // Load project components
      const compRes = await fetch(`/api/sdk/v1/iace/projects/${projectId}/components`)
      if (!compRes.ok) return
      const compJson = await compRes.json()
      const components: Component[] = (compJson.components || compJson || []).map(
        (c: Record<string, unknown>) => ({
          id: c.id as string,
          name: c.name as string,
          component_type: c.component_type as string || 'mechanical',
        })
      )

      // Load ALL failure modes, then match by component type + name keywords
      const allRes = await fetch('/api/sdk/v1/iace/failure-modes')
      let allFMs: FailureMode[] = []
      if (allRes.ok) {
        const json = await allRes.json()
        allFMs = json.failure_modes || []
      }

      // Derive the best FM component_type from component name keywords
      const nameToFMTypes: Record<string, string[]> = {
        sensor: ['sensor'], scanner: ['sensor'], kamera: ['sensor'],
        motor: ['actuator', 'electrical'], antrieb: ['actuator'],
        steuerung: ['controller'], sps: ['controller'], plc: ['controller'],
        software: ['software'], firmware: ['software'],
        ventil: ['actuator', 'mechanical'], greifer: ['actuator', 'mechanical'],
        roboter: ['actuator', 'mechanical'], hydraulik: ['actuator'],
        netzwerk: ['network'], ethernet: ['network'],
      }

      function getFMTypesForComp(comp: Component): string[] {
        const types = [comp.component_type]
        const nameLower = comp.name.toLowerCase()
        for (const [kw, fmTypes] of Object.entries(nameToFMTypes)) {
          if (nameLower.includes(kw)) types.push(...fmTypes)
        }
        return [...new Set(types)]
      }

      // Build FMEA rows: each component × its matching failure modes
      const fmeaRows: FMEARow[] = []
      for (const comp of components) {
        const compTypes = getFMTypesForComp(comp)
        const compFMs = allFMs.filter((fm) => compTypes.includes(fm.component_type))
        // Use matched FMs, or fallback to mechanical FMs
        const relevantFMs = compFMs.length > 0 ? compFMs : allFMs.filter((fm) => fm.component_type === 'mechanical').slice(0, 3)

        for (const fm of relevantFMs) {
          const s = fm.default_severity || 5
          const o = fm.default_occurrence || 5
          const d = fm.default_detection || 5
          fmeaRows.push({
            component: comp,
            failureMode: fm,
            severity: s,
            occurrence: o,
            detection: d,
            rpz: s * o * d,
            ap: calculateAP(s, o, d),
          })
        }
      }

      // Sort by RPZ descending (highest risk first)
      fmeaRows.sort((a, b) => b.rpz - a.rpz)
      setRows(fmeaRows)
    } catch (err) {
      console.error('Failed to load FMEA data:', err)
    } finally {
      setLoading(false)
    }
  }

  const stats = {
    total: rows.length,
    critical: rows.filter((r) => r.rpz > 200).length,
    actionRequired: rows.filter((r) => r.rpz > 100 && r.rpz <= 200).length,
    acceptable: rows.filter((r) => r.rpz <= 100).length,
  }

  const [suggesting, setSuggesting] = useState(false)
  const [suggestions, setSuggestions] = useState<FailureMode[]>([])
  const [suggestSource, setSuggestSource] = useState<string>('')

  async function suggestFMs(componentId: string) {
    setSuggesting(true)
    setSuggestions([])
    try {
      const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/components/${componentId}/suggest-fms`, {
        method: 'POST',
      })
      if (res.ok) {
        const json = await res.json()
        setSuggestions(json.suggestions || [])
        setSuggestSource(json.source || 'unknown')
      }
    } catch (err) {
      console.error('FM suggest failed:', err)
    } finally {
      setSuggesting(false)
    }
  }

  // Get unique components for the suggest button
  const components = [...new Map(rows.map((r) => [r.component.id, r.component])).values()]

  /**
   * Accept a suggested FM: build an FMEA row from the FM defaults, prepend it
   * to the table state, and remove the FM from the suggestion list.
   * Returns false if the (component, fm.id) combo already exists in rows.
   */
  function acceptSuggestion(fm: FailureMode, componentId: string): boolean {
    const comp = components.find((c) => c.id === componentId)
    if (!comp) return false
    const dup = rows.find((r) => r.component.id === componentId && r.failureMode.id === fm.id)
    if (dup) {
      // Still drop the suggestion so the UI does not keep offering it.
      setSuggestions((prev) => prev.filter((s) => s.id !== fm.id))
      return false
    }
    const s = fm.default_severity || 5
    const o = fm.default_occurrence || 5
    const d = fm.default_detection || 5
    const newRow: FMEARow = {
      component: comp,
      failureMode: fm,
      severity: s,
      occurrence: o,
      detection: d,
      rpz: s * o * d,
      ap: calculateAP(s, o, d),
    }
    setRows((prev) => [newRow, ...prev].sort((a, b) => b.rpz - a.rpz))
    setSuggestions((prev) => prev.filter((sg) => sg.id !== fm.id))
    return true
  }

  function rejectSuggestion(fmId: string) {
    setSuggestions((prev) => prev.filter((sg) => sg.id !== fmId))
  }

  return {
    rows,
    loading,
    stats,
    components,
    suggestFMs,
    suggesting,
    suggestions,
    suggestSource,
    setSuggestions,
    acceptSuggestion,
    rejectSuggestion,
  }
}
