import { useState, useCallback, useEffect } from 'react'
import type { Case } from '@/types'
import { useCaseUpdate, useKvnrUpdate } from '@/hooks/useCases'
import { CASE_SECTIONS, type FieldConfig } from './fieldConfig'

type FormValues = Record<string, unknown>

interface UseInlineEditReturn {
  editing: boolean
  formValues: FormValues
  saving: boolean
  error: string
  success: boolean
  startEditing: () => void
  cancelEditing: () => void
  saveAll: () => Promise<Case | null>
  setFieldValue: (key: string, value: unknown) => void
  canEditField: (field: FieldConfig, isAdmin: boolean) => boolean
  isDirty: boolean
}

function extractFormValues(caseData: Case): FormValues {
  const values: FormValues = {}
  for (const section of CASE_SECTIONS) {
    for (const field of section.fields) {
      values[field.key] = caseData[field.key]
    }
  }
  return values
}

function getDirtyFields(original: FormValues, current: FormValues): FormValues {
  const dirty: FormValues = {}
  for (const key of Object.keys(current)) {
    const orig = original[key] ?? null
    const curr = current[key] ?? null
    if (orig !== curr) {
      dirty[key] = curr
    }
  }
  return dirty
}

export function useInlineEdit(
  caseData: Case,
): UseInlineEditReturn {
  const caseUpdateMutation = useCaseUpdate()
  const kvnrUpdateMutation = useKvnrUpdate()

  const [editing, setEditing] = useState(false)
  const [formValues, setFormValues] = useState<FormValues>(() => extractFormValues(caseData))
  const [originalValues, setOriginalValues] = useState<FormValues>(() => extractFormValues(caseData))
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState('')
  const [success, setSuccess] = useState(false)

  // Reset when case changes
  useEffect(() => {
    const vals = extractFormValues(caseData)
    setFormValues(vals)
    setOriginalValues(vals)
    setEditing(false)
    setError('')
    setSuccess(false)
  }, [caseData.id, caseData.updated_at])

  const startEditing = useCallback(() => {
    setFormValues(extractFormValues(caseData))
    setOriginalValues(extractFormValues(caseData))
    setEditing(true)
    setError('')
    setSuccess(false)
  }, [caseData])

  const cancelEditing = useCallback(() => {
    setFormValues(extractFormValues(caseData))
    setEditing(false)
    setError('')
    setSuccess(false)
  }, [caseData])

  const setFieldValue = useCallback((key: string, value: unknown) => {
    setFormValues((prev) => ({ ...prev, [key]: value }))
    setSuccess(false)
  }, [])

  const isDirty = Object.keys(getDirtyFields(originalValues, formValues)).length > 0

  const saveAll = useCallback(async (): Promise<Case | null> => {
    const dirty = getDirtyFields(originalValues, formValues)
    if (Object.keys(dirty).length === 0) {
      setEditing(false)
      return null
    }

    setSaving(true)
    setError('')
    setSuccess(false)

    try {
      let lastResult: Case | null = null

      // Split: KVNR goes to its own endpoint (accessible by all users)
      if ('kvnr' in dirty) {
        const kvnrVal = dirty.kvnr as string | null
        const kvnrResult = await kvnrUpdateMutation.mutateAsync({
          id: caseData.id,
          kvnr: kvnrVal?.trim() || null,
        })
        lastResult = kvnrResult
        delete dirty.kvnr
      }

      // Remaining fields go to the admin-only general update endpoint
      if (Object.keys(dirty).length > 0) {
        // Convert empty strings to null for optional text fields
        const payload: FormValues = {}
        for (const [key, value] of Object.entries(dirty)) {
          if (typeof value === 'string' && value.trim() === '') {
            payload[key] = null
          } else {
            payload[key] = value
          }
        }
        const updateResult = await caseUpdateMutation.mutateAsync({
          id: caseData.id,
          data: payload,
        })
        lastResult = updateResult
      }

      if (lastResult) {
        setSuccess(true)
        setEditing(false)
      }

      return lastResult
    } catch (err: unknown) {
      const msg =
        err instanceof Error ? err.message : 'Fehler beim Speichern.'
      setError(msg)
      return null
    } finally {
      setSaving(false)
    }
  }, [caseData.id, formValues, originalValues, caseUpdateMutation, kvnrUpdateMutation])

  const canEditField = useCallback(
    (field: FieldConfig, isAdmin: boolean): boolean => {
      if (!editing) return false
      if (field.editableBy === 'all') return true
      return isAdmin
    },
    [editing],
  )

  return {
    editing,
    formValues,
    saving,
    error,
    success,
    startEditing,
    cancelEditing,
    saveAll,
    setFieldValue,
    canEditField,
    isDirty,
  }
}
