import { useState, useCallback, useEffect } from 'react'
import { api } from '../api/client'
import type {
  UserOut,
  AbsenceTypeOut,
  AbsenceOut,
  AbsenceListResponse,
  UserListItem,
  VacationBalanceOut,
  OvertimeBalanceOut,
} from '../types/absence'

export function useAbsences(year: number, statusFilter: string) {
  const [user, setUser] = useState<UserOut | null>(null)
  const [types, setTypes] = useState<AbsenceTypeOut[]>([])
  const [absences, setAbsences] = useState<AbsenceOut[]>([])
  const [total, setTotal] = useState(0)
  const [balance, setBalance] = useState<VacationBalanceOut | null>(null)
  const [overtimeBalance, setOvertimeBalance] = useState<OvertimeBalanceOut | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [colleagues, setColleagues] = useState<UserListItem[]>([])

  const colleagueMap = Object.fromEntries(colleagues.map(c => [c.id, c.full_name]))

  const load = useCallback(async () => {
    setLoading(true)
    try {
      const params = statusFilter ? `?status=${statusFilter}&year=${year}` : `?year=${year}`
      const [me, typeList, absList, bal, otBal] = await Promise.all([
        api.get<UserOut>('/auth/me'),
        api.get<AbsenceTypeOut[]>('/absence-types/'),
        api.get<AbsenceListResponse>(`/absences/${params}`),
        api.get<VacationBalanceOut>(`/absences/balance?year=${year}`),
        api.get<OvertimeBalanceOut>('/absences/overtime-balance'),
      ])
      setUser(me)
      setTypes(typeList.filter(t => t.is_active))
      setAbsences(absList.items)
      setTotal(absList.total)
      setBalance(bal)
      setOvertimeBalance(otBal)
      if (colleagues.length === 0) {
        try {
          // Schlanke Kollegenliste (für alle Rollen zugänglich) – u.a. Vertreter-Auswahl
          setColleagues(await api.get<UserListItem[]>('/users/colleagues'))
        } catch { /* ignore */ }
      }
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden')
    } finally {
      setLoading(false)
    }
  }, [statusFilter, year]) // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => { load() }, [load])

  const createAbsence = async (
    form: { type_id: string; start_date: string; end_date: string; half_day_start: boolean; half_day_end: boolean; note: string; for_user_id: string; substitute_id?: string },
    onSuccess: () => void,
    setSubmitting: (v: boolean) => void,
    fzaHours?: number,
  ) => {
    if (!form.type_id || !form.start_date || !form.end_date) {
      setError('Bitte alle Pflichtfelder ausfüllen')
      return
    }
    setSubmitting(true)
    setError('')
    try {
      await api.post('/absences/', {
        type_id: form.type_id,
        start_date: form.start_date,
        end_date: form.end_date,
        half_day_start: form.half_day_start,
        half_day_end: form.half_day_end,
        note: form.note || null,
        for_user_id: form.for_user_id || null,
        substitute_id: form.substitute_id || null,
        ...(fzaHours !== undefined ? { fza_hours: fzaHours } : {}),
      })
      onSuccess()
      await load()
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Erstellen')
    } finally {
      setSubmitting(false)
    }
  }

  const approve = async (id: string) => {
    setError('')
    try { await api.post(`/absences/${id}/approve`, {}); await load() }
    catch (e: unknown) { setError(e instanceof Error ? e.message : 'Fehler') }
  }

  const reject = async (id: string, rejectReason: string, onSuccess: () => void) => {
    if (!rejectReason.trim()) return
    setError('')
    try {
      await api.post(`/absences/${id}/reject`, { rejection_reason: rejectReason })
      onSuccess()
      await load()
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler')
    }
  }

  const saveEdit = async (
    editAbsence: AbsenceOut,
    editForm: { type_id: string; start_date: string; end_date: string; half_day_start: boolean; half_day_end: boolean; note: string; correction_note: string },
    isManager: boolean,
    onSuccess: () => void,
    setSubmitting: (v: boolean) => void,
  ) => {
    if (!editForm.type_id || !editForm.start_date || !editForm.end_date) {
      setError('Bitte alle Pflichtfelder ausfüllen')
      return
    }
    if (editAbsence.status === 'approved' && !isManager && !editForm.correction_note.trim()) {
      setError('Änderungsgrund ist Pflicht bei genehmigten Anträgen.')
      return
    }
    setSubmitting(true)
    setError('')
    try {
      await api.patch(`/absences/${editAbsence.id}`, {
        type_id: editForm.type_id,
        start_date: editForm.start_date,
        end_date: editForm.end_date,
        half_day_start: editForm.half_day_start,
        half_day_end: editForm.half_day_end,
        note: editForm.note || null,
        correction_note: editForm.correction_note.trim() || null,
      })
      onSuccess()
      await load()
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Speichern')
    } finally {
      setSubmitting(false)
    }
  }

  const cancel = async (id: string) => {
    setError('')
    try { await api.del(`/absences/${id}`); await load() }
    catch (e: unknown) { setError(e instanceof Error ? e.message : 'Fehler') }
  }

  const requestCancellation = async (id: string, reason: string) => {
    setError('')
    try {
      await api.post(`/absences/${id}/request-cancellation`, { reason: reason.trim() || null })
      await load()
    } catch (e: unknown) { setError(e instanceof Error ? e.message : 'Fehler') }
  }

  const loadColleaguesIfNeeded = async () => {
    if (colleagues.length === 0) {
      try {
        setColleagues(await api.get<UserListItem[]>('/users/colleagues'))
      } catch { /* ignore */ }
    }
  }

  const typeName = (typeId: string) => types.find(t => t.id === typeId)?.name ?? typeId
  const typeColor = (typeId: string) => types.find(t => t.id === typeId)?.color ?? '#6B7280'

  const updateBalance = (updated: VacationBalanceOut) => setBalance(updated)

  return {
    user,
    types,
    absences,
    total,
    balance,
    overtimeBalance,
    loading,
    error,
    setError,
    colleagues,
    colleagueMap,
    load,
    createAbsence,
    approve,
    reject,
    saveEdit,
    cancel,
    requestCancellation,
    loadColleaguesIfNeeded,
    typeName,
    typeColor,
    updateBalance,
  }
}
