import { useCallback, useEffect, useState } from 'react'
import { api } from '../../api/client'

// ── Typen ────────────────────────────────────────────────────────────────────

interface AbsenceType {
  id: string
  name: string
  category: string
  color: string | null
  requires_approval: boolean
}

interface Absence {
  id: string
  type_id: string
  start_date: string
  end_date: string
  half_day_start: boolean
  half_day_end: boolean
  working_days: number
  status: 'pending' | 'approved' | 'rejected' | 'cancelled'
  note: string | null
  rejection_reason: string | null
}

interface AbsenceList {
  total: number
  items: Absence[]
}

interface VacationBalance {
  entitled_days: number
  special_days: number
  carried_over: number
  used_days: number
  total_days: number
  remaining_days: number
  pending_days: number
}

// ── Helpers ──────────────────────────────────────────────────────────────────

function fmtDate(d: string) {
  return new Date(d + 'T00:00:00').toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })
}

function statusLabel(s: Absence['status']) {
  return { pending: 'Ausstehend', approved: 'Genehmigt', rejected: 'Abgelehnt', cancelled: 'Storniert' }[s]
}

function statusColor(s: Absence['status']) {
  return {
    pending:   'bg-yellow-100 text-yellow-700',
    approved:  'bg-green-100 text-green-700',
    rejected:  'bg-red-100 text-red-700',
    cancelled: 'bg-gray-100 text-gray-500',
  }[s]
}

const today = new Date()
const todayStr = today.toISOString().slice(0, 10)

// ── Neuer Antrag Modal ───────────────────────────────────────────────────────

interface NewAbsenceModalProps {
  types: AbsenceType[]
  onClose: () => void
  onCreated: () => void
}

function NewAbsenceModal({ types, onClose, onCreated }: NewAbsenceModalProps) {
  const [typeId, setTypeId] = useState(types[0]?.id ?? '')
  const [startDate, setStartDate] = useState(todayStr)
  const [endDate, setEndDate] = useState(todayStr)
  const [note, setNote] = useState('')
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  // Kategorie SICK → quick-sick, sonst normaler Antrag
  const selectedType = types.find(t => t.id === typeId)
  const isSick = selectedType?.category === 'SICK'

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setLoading(true); setError(null)
    try {
      if (isSick) {
        await api.post('/absences/quick-sick', { start_date: startDate, end_date: endDate })
      } else {
        await api.post('/absences/', { type_id: typeId, start_date: startDate, end_date: endDate, note: note || null })
      }
      onCreated()
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Erstellen')
    } finally {
      setLoading(false) }
  }

  return (
    <div className='fixed inset-0 z-50 flex flex-col justify-end bg-black/40' onClick={onClose}>
      <div
        className='bg-white rounded-t-2xl p-5 flex flex-col gap-4'
        style={{ paddingBottom: 'calc(1.25rem + env(safe-area-inset-bottom))' }}
        onClick={e => e.stopPropagation()}
      >
        <div className='flex items-center justify-between'>
          <h2 className='text-lg font-bold text-gray-900'>Neuer Antrag</h2>
          <button onClick={onClose} className='text-gray-400 text-2xl leading-none'>×</button>
        </div>

        {error && (
          <div className='bg-red-50 border border-red-200 rounded-xl px-4 py-3 text-sm text-red-700'>{error}</div>
        )}

        <form onSubmit={handleSubmit} className='flex flex-col gap-3'>
          {/* Typ */}
          <div className='flex flex-col gap-1'>
            <label className='text-sm font-medium text-gray-700'>Art</label>
            <select
              value={typeId}
              onChange={e => setTypeId(e.target.value)}
              className='min-h-[48px] px-3 rounded-xl border border-gray-300 text-gray-900 text-base focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white'
            >
              {types.map(t => (
                <option key={t.id} value={t.id}>{t.name}</option>
              ))}
            </select>
          </div>

          {/* Datum */}
          <div className='grid grid-cols-2 gap-3'>
            <div className='flex flex-col gap-1'>
              <label className='text-sm font-medium text-gray-700'>Von</label>
              <input
                type='date'
                value={startDate}
                onChange={e => { setStartDate(e.target.value); if (e.target.value > endDate) setEndDate(e.target.value) }}
                required
                className='min-h-[48px] px-3 rounded-xl border border-gray-300 text-gray-900 text-base focus:outline-none focus:ring-2 focus:ring-blue-500'
              />
            </div>
            <div className='flex flex-col gap-1'>
              <label className='text-sm font-medium text-gray-700'>Bis</label>
              <input
                type='date'
                value={endDate}
                min={startDate}
                onChange={e => setEndDate(e.target.value)}
                required
                className='min-h-[48px] px-3 rounded-xl border border-gray-300 text-gray-900 text-base focus:outline-none focus:ring-2 focus:ring-blue-500'
              />
            </div>
          </div>

          {/* Notiz (nicht bei Krankmeldung) */}
          {!isSick && (
            <div className='flex flex-col gap-1'>
              <label className='text-sm font-medium text-gray-700'>Notiz <span className='text-gray-400 font-normal'>(optional)</span></label>
              <textarea
                value={note}
                onChange={e => setNote(e.target.value)}
                rows={2}
                placeholder='z.B. Hochzeit, Arzttermin …'
                className='px-3 py-2 rounded-xl border border-gray-300 text-gray-900 text-base focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none'
              />
            </div>
          )}

          <button
            type='submit'
            disabled={loading}
            className='min-h-[52px] rounded-xl bg-blue-600 active:bg-blue-800 text-white font-semibold text-base transition-colors disabled:opacity-50 flex items-center justify-center gap-2 mt-1'
          >
            {loading
              ? <span className='animate-spin rounded-full h-5 w-5 border-2 border-white border-t-transparent' />
              : isSick ? '🤒 Krank melden' : '✓ Antrag stellen'
            }
          </button>
        </form>
      </div>
    </div>
  )
}

// ── Haupt-Screen ─────────────────────────────────────────────────────────────

export function MobileAbsencesScreen() {
  const [balance, setBalance]       = useState<VacationBalance | null>(null)
  const [absences, setAbsences]     = useState<Absence[]>([])
  const [types, setTypes]           = useState<AbsenceType[]>([])
  const [typeMap, setTypeMap]       = useState<Record<string, AbsenceType>>({})
  const [loading, setLoading]       = useState(true)
  const [error, setError]           = useState<string | null>(null)
  const [showModal, setShowModal]   = useState(false)

  const year = today.getFullYear()

  const load = useCallback(async () => {
    setError(null)
    try {
      const [bal, list, typeList] = await Promise.all([
        api.get<VacationBalance>(`/absences/balance?year=${year}`),
        api.get<AbsenceList>(`/absences/?year=${year}&limit=50`),
        api.get<AbsenceType[]>('/absence-types/'),
      ])
      setBalance(bal)
      setAbsences(list.items)
      const active = typeList.filter(t => (t as AbsenceType & { is_active?: boolean }).is_active !== false)
      setTypes(active)
      setTypeMap(Object.fromEntries(active.map(t => [t.id, t])))
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden')
    } finally {
      setLoading(false)
    }
  }, [year])

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

  if (loading) return (
    <div className='flex flex-col items-center justify-center flex-1 py-20 gap-4'>
      <div className='animate-spin rounded-full h-10 w-10 border-4 border-blue-500 border-t-transparent' />
      <p className='text-sm text-gray-400'>Wird geladen…</p>
    </div>
  )

  // Abwesenheiten sortiert: zukünftige + laufende zuerst, dann vergangene
  const sorted = [...absences].sort((a, b) => b.start_date.localeCompare(a.start_date))
  const upcoming = sorted.filter(a => a.end_date >= todayStr && a.status !== 'cancelled' && a.status !== 'rejected')
  const past     = sorted.filter(a => a.end_date < todayStr || a.status === 'cancelled' || a.status === 'rejected')

  return (
    <div className='flex flex-col gap-4 px-4 pt-4'>

      {error && (
        <div className='bg-red-50 border border-red-200 rounded-xl px-4 py-3 text-sm text-red-700'>{error}</div>
      )}

      {/* Urlaubskonto */}
      {balance && (
        <div className='bg-white rounded-2xl border border-gray-200 shadow-sm px-5 py-4'>
          <p className='text-xs font-semibold text-gray-400 uppercase tracking-widest mb-3'>Urlaubskonto {year}</p>
          <div className='flex items-center justify-between mb-3'>
            <div>
              <p className='text-4xl font-bold text-blue-600'>{balance.remaining_days}</p>
              <p className='text-sm text-gray-500 mt-0.5'>Tage verbleibend</p>
            </div>
            <div className='flex flex-col gap-1.5 text-right text-sm'>
              <div className='flex gap-2 justify-end'>
                <span className='text-gray-400'>Anspruch</span>
                <span className='font-semibold text-gray-700'>{balance.total_days} Tage</span>
              </div>
              <div className='flex gap-2 justify-end'>
                <span className='text-gray-400'>Genommen</span>
                <span className='font-semibold text-gray-700'>{balance.used_days} Tage</span>
              </div>
              {balance.pending_days > 0 && (
                <div className='flex gap-2 justify-end'>
                  <span className='text-gray-400'>Ausstehend</span>
                  <span className='font-semibold text-yellow-600'>{balance.pending_days} Tage</span>
                </div>
              )}
              {balance.carried_over > 0 && (
                <div className='flex gap-2 justify-end'>
                  <span className='text-gray-400'>Übertrag</span>
                  <span className='font-semibold text-gray-700'>{balance.carried_over} Tage</span>
                </div>
              )}
            </div>
          </div>

          {/* Fortschrittsbalken */}
          <div className='h-2 bg-gray-100 rounded-full overflow-hidden'>
            <div
              className='h-full bg-blue-500 rounded-full transition-all'
              style={{ width: `${Math.min(100, (balance.used_days / Math.max(balance.total_days, 1)) * 100)}%` }}
            />
          </div>
        </div>
      )}

      {/* Neuer Antrag Button */}
      <button
        onClick={() => setShowModal(true)}
        className='flex items-center justify-center gap-2 min-h-[52px] rounded-xl bg-blue-600 active:bg-blue-800 text-white font-semibold text-base shadow-sm transition-colors'
      >
        <span className='text-lg'>+</span>
        Antrag stellen / Krank melden
      </button>

      {/* Kommende Abwesenheiten */}
      {upcoming.length > 0 && (
        <section>
          <p className='text-xs font-semibold text-gray-400 uppercase tracking-widest mb-2 px-1'>Aktuell & Geplant</p>
          <div className='flex flex-col gap-2'>
            {upcoming.map(a => (
              <AbsenceCard key={a.id} absence={a} type={typeMap[a.type_id]} />
            ))}
          </div>
        </section>
      )}

      {/* Vergangene Abwesenheiten */}
      {past.length > 0 && (
        <section className='mb-4'>
          <p className='text-xs font-semibold text-gray-400 uppercase tracking-widest mb-2 px-1'>Vergangen</p>
          <div className='flex flex-col gap-2'>
            {past.map(a => (
              <AbsenceCard key={a.id} absence={a} type={typeMap[a.type_id]} />
            ))}
          </div>
        </section>
      )}

      {upcoming.length === 0 && past.length === 0 && !loading && (
        <div className='flex flex-col items-center py-12 gap-2 text-gray-400'>
          <span className='text-4xl'>🌴</span>
          <p className='text-sm'>Keine Abwesenheiten in {year}</p>
        </div>
      )}

      {/* Modal */}
      {showModal && types.length > 0 && (
        <NewAbsenceModal
          types={types}
          onClose={() => setShowModal(false)}
          onCreated={() => { setShowModal(false); load() }}
        />
      )}
    </div>
  )
}

// ── Karte pro Abwesenheit ────────────────────────────────────────────────────

function AbsenceCard({ absence, type }: { absence: Absence; type?: AbsenceType }) {
  const isSameDay = absence.start_date === absence.end_date
  const dateStr = isSameDay
    ? fmtDate(absence.start_date)
    : `${fmtDate(absence.start_date)} – ${fmtDate(absence.end_date)}`

  const colorDot = type?.color ?? '#94a3b8'

  return (
    <div className='bg-white rounded-xl border border-gray-200 shadow-sm px-4 py-3 flex items-start gap-3'>
      {/* Farbpunkt */}
      <div className='mt-1 w-3 h-3 rounded-full flex-shrink-0' style={{ backgroundColor: colorDot }} />

      <div className='flex-1 min-w-0'>
        <div className='flex items-center justify-between gap-2 flex-wrap'>
          <p className='font-semibold text-gray-800 text-sm truncate'>{type?.name ?? '–'}</p>
          <span className={`text-[11px] font-semibold px-2 py-0.5 rounded-full ${statusColor(absence.status)}`}>
            {statusLabel(absence.status)}
          </span>
        </div>
        <p className='text-xs text-gray-500 mt-0.5'>{dateStr}</p>
        {absence.working_days > 0 && (
          <p className='text-xs text-gray-400 mt-0.5'>{absence.working_days} Arbeitstag{absence.working_days !== 1 ? 'e' : ''}</p>
        )}
        {absence.rejection_reason && (
          <p className='text-xs text-red-500 mt-1'>Grund: {absence.rejection_reason}</p>
        )}
        {absence.note && (
          <p className='text-xs text-gray-400 mt-1 italic'>„{absence.note}"</p>
        )}
      </div>
    </div>
  )
}
