'use client'

import { useState, useEffect, useCallback, useRef } from 'react'

// ── Types ──────────────────────────────────────────────────
export interface OperationalStateInfo {
  id: string
  label_de: string
  label_en: string
  sort_order: number
}

export interface DeltaResult {
  added_patterns: number
  removed_patterns: number
  added_hazards: string[]
  removed_hazards: string[]
  added_measures: string[]
  removed_measures: string[]
}

interface ProjectMetadata {
  limits_form?: Record<string, unknown>
  operational_states?: string[]
  [key: string]: unknown
}

// ── Hook ───────────────────────────────────────────────────
export function useOperationalStates(projectId: string) {
  const [allStates, setAllStates] = useState<OperationalStateInfo[]>([])
  const [transitions, setTransitions] = useState<string[]>([])
  const [selectedStates, setSelectedStates] = useState<string[]>([])
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [saved, setSaved] = useState(false)
  const [deltaResult, setDeltaResult] = useState<DeltaResult | null>(null)
  const [deltaLoading, setDeltaLoading] = useState(false)
  const metadataRef = useRef<ProjectMetadata>({})
  const savedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  useEffect(() => {
    loadData()
    return () => {
      if (savedTimerRef.current) clearTimeout(savedTimerRef.current)
    }
  }, [projectId]) // eslint-disable-line react-hooks/exhaustive-deps

  async function loadData() {
    try {
      const [statesRes, projRes] = await Promise.all([
        fetch('/api/sdk/v1/iace/operational-states'),
        fetch(`/api/sdk/v1/iace/projects/${projectId}`),
      ])

      if (statesRes.ok) {
        const json = await statesRes.json()
        setAllStates(json.operational_states || [])
        setTransitions(json.transitions || [])
      }

      if (projRes.ok) {
        const proj = await projRes.json()
        const meta: ProjectMetadata = proj.metadata || {}
        metadataRef.current = meta
        setSelectedStates(meta.operational_states || [])
      }
    } catch (err) {
      console.error('Failed to load operational states:', err)
    } finally {
      setLoading(false)
    }
  }

  const toggleState = useCallback((stateId: string) => {
    setSelectedStates((prev) => {
      const next = prev.includes(stateId)
        ? prev.filter((s) => s !== stateId)
        : [...prev, stateId]
      return next
    })
    setDeltaResult(null)
  }, [])

  const saveSelection = useCallback(async (states: string[]) => {
    setSaving(true)
    setSaved(false)
    try {
      const newMetadata = { ...metadataRef.current, operational_states: states }
      const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ metadata: newMetadata }),
      })
      if (res.ok) {
        metadataRef.current = newMetadata
        setSaved(true)
        if (savedTimerRef.current) clearTimeout(savedTimerRef.current)
        savedTimerRef.current = setTimeout(() => setSaved(false), 2000)
      }
    } catch (err) {
      console.error('Failed to save:', err)
    } finally {
      setSaving(false)
    }
  }, [projectId])

  const runDeltaAnalysis = useCallback(async (states: string[]) => {
    setDeltaLoading(true)
    setDeltaResult(null)
    try {
      // Build MatchInput from project's components — derive tags from names/types
      const compRes = await fetch(`/api/sdk/v1/iace/projects/${projectId}/components`)
      let componentTags: string[] = []
      let energyIds: string[] = []
      if (compRes.ok) {
        const cj = await compRes.json()
        const comps = (cj.components || cj || []) as Array<{ library_id?: string; component_type?: string; name?: string; energy_source_ids?: string[] }>
        // Use library_ids if available, otherwise derive tags from component names/types
        const libIds = comps.map((c) => c.library_id).filter(Boolean) as string[]
        if (libIds.length > 0) {
          componentTags = libIds
        } else {
          // Derive tags from component names for pattern matching
          const tagMap: Record<string, string[]> = {
            sensor: ['sensor', 'has_sensor'], software: ['software', 'has_software'],
            firmware: ['firmware', 'has_firmware'], ai_model: ['has_ai', 'ai_model'],
            hmi: ['hmi', 'display'], electrical: ['electric_motor', 'electric_drive'],
            network: ['networked', 'ethernet'], actuator: ['actuator', 'hydraulic'],
            mechanical: ['moving_mechanical_parts'], hydraulic: ['hydraulic'],
          }
          const nameKeywords: Record<string, string[]> = {
            roboter: ['cobot', 'robot_arm'], motor: ['electric_motor', 'electric_drive'],
            scanner: ['sensor', 'safety_scanner'], sps: ['controller', 'plc'],
            steuerung: ['controller', 'plc'], greifer: ['actuator', 'gripper'],
            schutzzaun: ['safety_fence'], lichtgitter: ['light_curtain'],
            kamera: ['camera', 'sensor'], ventil: ['valve', 'pneumatic'],
          }
          const tags = new Set<string>()
          for (const c of comps) {
            const typeTags = tagMap[c.component_type || ''] || ['moving_mechanical_parts']
            typeTags.forEach((t) => tags.add(t))
            const nameLower = (c.name || '').toLowerCase()
            for (const [kw, kwTags] of Object.entries(nameKeywords)) {
              if (nameLower.includes(kw)) kwTags.forEach((t) => tags.add(t))
            }
          }
          componentTags = [...tags]
        }
        energyIds = comps.flatMap((c) => c.energy_source_ids || [])
      }

      const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/delta-analysis`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          current: {
            component_library_ids: componentTags,
            energy_source_ids: energyIds,
            custom_tags: componentTags,
            operational_states: metadataRef.current.operational_states || [],
          },
          proposed: {
            component_library_ids: componentTags,
            energy_source_ids: energyIds,
            custom_tags: componentTags,
            operational_states: states,
          },
        }),
      })
      if (res.ok) {
        const json = await res.json()
        setDeltaResult({
          added_patterns: json.added_patterns?.length || 0,
          removed_patterns: json.removed_patterns?.length || 0,
          added_hazards: (json.added_hazards || []).map((h: { name?: string }) => h.name || ''),
          removed_hazards: (json.removed_hazards || []).map((h: { name?: string }) => h.name || ''),
          added_measures: (json.added_measures || []).map((m: { id?: string }) => m.id || ''),
          removed_measures: (json.removed_measures || []).map((m: { id?: string }) => m.id || ''),
        })
      }
    } catch (err) {
      console.error('Delta analysis failed:', err)
    } finally {
      setDeltaLoading(false)
    }
  }, [projectId])

  /** Transitions that involve only selected states */
  const activeTransitions = transitions.filter((t) => {
    const [from, to] = t.split('\u2192')
    return selectedStates.includes(from) && selectedStates.includes(to)
  })

  return {
    allStates,
    transitions,
    activeTransitions,
    selectedStates,
    toggleState,
    saveSelection,
    runDeltaAnalysis,
    loading,
    saving,
    saved,
    deltaResult,
    deltaLoading,
  }
}
