import { useEffect, useState } from 'react'
import type { HoursPayoutOut, HoursPayoutListResponse } from '../types/hoursPayout'
import { api } from '../api/client'
import { Spinner } from '../components/Spinner'
import { Layout } from '../components/Layout'
import { Modal } from '../components/Modal'

interface UserItem {
  id: string
  full_name: string
  personnel_number: string | null
  is_active: boolean
}

interface UserListResponse {
  total: number
  items: UserItem[]
}

interface Me {
  first_name: string
  last_name: string
  role: string
}

interface OvertimeBalance {
  balance_hours: number
}

const MONTH_NAMES = [
  'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
  'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember',
]

const inputClass = 'w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-purple-400 focus:border-transparent'

function formatPeriod(year: number | null, month: number | null): string {
  if (!year) return '—'
  if (!month) return String(year)
  return `${MONTH_NAMES[month - 1]} ${year}`
}

const STATUS_BADGE: Record<string, { label: string; cls: string }> = {
  requested: { label: 'Beantragt', cls: 'bg-amber-100 text-amber-700' },
  approved: { label: 'Genehmigt', cls: 'bg-green-100 text-green-700' },
  rejected: { label: 'Abgelehnt', cls: 'bg-red-100 text-red-700' },
  cancelled: { label: 'Zurückgezogen', cls: 'bg-gray-100 text-gray-500' },
}

function StatusBadge({ status }: { status: string }) {
  const b = STATUS_BADGE[status] ?? { label: status, cls: 'bg-gray-100 text-gray-500' }
  return <span className={`inline-block px-2 py-0.5 rounded-full text-xs font-medium ${b.cls}`}>{b.label}</span>
}

export function HoursPayoutPage() {
  const [me, setMe] = useState<Me | null>(null)
  const [users, setUsers] = useState<UserItem[]>([])
  const [pageLoading, setPageLoading] = useState(true)
  const [pageError, setPageError] = useState<string | null>(null)

  // Filter state
  const currentYear = new Date().getFullYear()
  const [filterUser, setFilterUser] = useState('')
  const [filterYear, setFilterYear] = useState<number>(currentYear)
  const [filterMonth, setFilterMonth] = useState<number>(0)

  // Table data
  const [payouts, setPayouts] = useState<HoursPayoutOut[]>([])
  const [totalCount, setTotalCount] = useState(0)
  const [tableLoading, setTableLoading] = useState(false)

  // Modal state
  const [showModal, setShowModal] = useState(false)
  const [formUserId, setFormUserId] = useState('')
  const [formHours, setFormHours] = useState<number>(8)
  const [formYear, setFormYear] = useState<number>(currentYear)
  const [formMonth, setFormMonth] = useState<number>(new Date().getMonth() + 1)
  const [formNote, setFormNote] = useState('')
  const [formHasPeriod, setFormHasPeriod] = useState(true)
  const [modalSaving, setModalSaving] = useState(false)
  const [modalError, setModalError] = useState<string | null>(null)

  // Overtime balance for selected user
  const [overtimeBalance, setOvertimeBalance] = useState<number | null>(null)
  const [overtimeLoading, setOvertimeLoading] = useState(false)

  // Initial load
  useEffect(() => {
    async function init() {
      try {
        const [meData, listData] = await Promise.all([
          api.get<Me>('/auth/me'),
          api.get<UserListResponse>('/users/?limit=500'),
        ])
        setMe(meData)
        setUsers(listData.items.filter(u => u.is_active))
      } catch (e: unknown) {
        setPageError(e instanceof Error ? e.message : 'Fehler beim Laden')
      } finally {
        setPageLoading(false)
      }
    }
    init()
  }, [])

  // Load on mount after users available
  useEffect(() => {
    if (!pageLoading) {
      loadPayouts()
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pageLoading])

  async function loadPayouts() {
    setTableLoading(true)
    try {
      const params: Record<string, string> = {}
      if (filterUser) params.user_id = filterUser
      if (filterYear) params.year = String(filterYear)
      if (filterMonth > 0) params.month = String(filterMonth)

      const data = await api.get<HoursPayoutListResponse>(
        `/hr/payouts?${new URLSearchParams(params)}`
      )
      setPayouts(data.payouts)
      setTotalCount(data.total_count)
    } catch (e: unknown) {
      setPageError(e instanceof Error ? e.message : 'Fehler beim Laden der Auszahlungen')
    } finally {
      setTableLoading(false)
    }
  }

  function handleSearch() {
    loadPayouts()
  }

  async function loadOvertimeBalance(userId: string) {
    if (!userId) {
      setOvertimeBalance(null)
      return
    }
    setOvertimeLoading(true)
    try {
      const data = await api.get<OvertimeBalance>(`/absences/overtime-balance?user_id=${userId}`)
      setOvertimeBalance(data.balance_hours)
    } catch {
      setOvertimeBalance(null)
    } finally {
      setOvertimeLoading(false)
    }
  }

  function openNewModal() {
    setFormUserId('')
    setFormHours(8)
    setFormYear(currentYear)
    setFormMonth(new Date().getMonth() + 1)
    setFormNote('')
    setFormHasPeriod(true)
    setOvertimeBalance(null)
    setModalError(null)
    setShowModal(true)
  }

  function handleUserChange(userId: string) {
    setFormUserId(userId)
    loadOvertimeBalance(userId)
  }

  async function handleSave() {
    if (!formUserId) {
      setModalError('Bitte einen Mitarbeiter auswählen.')
      return
    }
    if (!formHours || formHours <= 0) {
      setModalError('Stunden müssen größer als 0 sein.')
      return
    }
    setModalSaving(true)
    setModalError(null)
    try {
      await api.post<HoursPayoutOut>('/hr/payouts', {
        user_id: formUserId,
        hours: formHours,
        period_year: formHasPeriod ? formYear : null,
        period_month: formHasPeriod ? formMonth : null,
        note: formNote.trim() || null,
      })
      setShowModal(false)
      loadPayouts()
    } catch (e: unknown) {
      setModalError(e instanceof Error ? e.message : 'Fehler beim Anlegen')
    } finally {
      setModalSaving(false)
    }
  }

  async function handleDelete(payout: HoursPayoutOut) {
    if (!confirm('Auszahlung wirklich stornieren?')) return
    try {
      await api.del(`/hr/payouts/${payout.id}`)
      setPayouts(prev => prev.filter(p => p.id !== payout.id))
      setTotalCount(prev => prev - 1)
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler beim Stornieren')
    }
  }

  async function handleApprove(payout: HoursPayoutOut) {
    if (!confirm(`Auszahlung über ${Number(payout.hours).toFixed(2)} h für ${payout.user_name} genehmigen? Der Saldo wird abgezogen.`)) return
    try {
      const updated = await api.post<HoursPayoutOut>(`/hr/payouts/${payout.id}/approve`, {})
      setPayouts(prev => prev.map(p => (p.id === payout.id ? updated : p)))
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler beim Genehmigen')
    }
  }

  async function handleReject(payout: HoursPayoutOut) {
    const reason = prompt('Grund der Ablehnung (optional):')
    if (reason === null) return  // Abbrechen
    try {
      const updated = await api.post<HoursPayoutOut>(`/hr/payouts/${payout.id}/reject`, {
        rejection_reason: reason.trim() || null,
      })
      setPayouts(prev => prev.map(p => (p.id === payout.id ? updated : p)))
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler beim Ablehnen')
    }
  }

  if (pageLoading) return (
    <div className='min-h-screen bg-gray-50 flex items-center justify-center'><Spinner /></div>
  )
  if (pageError) return (
    <div className='min-h-screen bg-gray-50 flex items-center justify-center'>
      <p className='text-red-600'>{pageError}</p>
    </div>
  )

  const isOverBudget = overtimeBalance !== null && formHours > overtimeBalance

  return (
    <Layout userRole={me?.role ?? ''} userName={`${me?.first_name} ${me?.last_name}`}>
      <div className='space-y-6'>

        {/* Header */}
        <div className='flex items-center justify-between'>
          <div>
            <h1 className='text-xl font-bold text-gray-800'>💸 Stunden-Auszahlung</h1>
            <p className='text-sm text-gray-500 mt-0.5'>Überstunden-Auszahlungen verwalten</p>
          </div>
          <button
            onClick={openNewModal}
            className='px-4 py-2 bg-purple-600 text-white text-sm font-semibold rounded-lg hover:bg-purple-700 transition-colors'
          >
            + Auszahlung anlegen
          </button>
        </div>

        {/* Filter bar */}
        <div className='bg-white rounded-xl border border-gray-200 shadow-sm p-4'>
          <div className='flex flex-wrap gap-3 items-end'>
            <div className='flex-1 min-w-48'>
              <label className='block text-xs font-medium text-gray-700 mb-1'>Mitarbeiter</label>
              <select
                value={filterUser}
                onChange={e => setFilterUser(e.target.value)}
                className={inputClass}
              >
                <option value=''>Alle Mitarbeiter</option>
                {users.map(u => (
                  <option key={u.id} value={u.id}>
                    {u.full_name}{u.personnel_number ? ` (${u.personnel_number})` : ''}
                  </option>
                ))}
              </select>
            </div>
            <div className='w-32'>
              <label className='block text-xs font-medium text-gray-700 mb-1'>Jahr</label>
              <input
                type='number'
                value={filterYear}
                onChange={e => setFilterYear(Number(e.target.value))}
                min={2000}
                max={2100}
                className={inputClass}
              />
            </div>
            <div className='w-44'>
              <label className='block text-xs font-medium text-gray-700 mb-1'>Monat</label>
              <select
                value={filterMonth}
                onChange={e => setFilterMonth(Number(e.target.value))}
                className={inputClass}
              >
                <option value={0}>Alle Monate</option>
                {MONTH_NAMES.map((name, i) => (
                  <option key={i + 1} value={i + 1}>{name}</option>
                ))}
              </select>
            </div>
            <button
              onClick={handleSearch}
              disabled={tableLoading}
              className='px-4 py-2 bg-purple-600 text-white text-sm font-semibold rounded-lg hover:bg-purple-700 disabled:opacity-50 transition-colors'
            >
              {tableLoading ? 'Lade…' : 'Suchen'}
            </button>
          </div>
        </div>

        {/* Table */}
        <div className='bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden'>
          {tableLoading ? (
            <div className='flex items-center justify-center py-16'><Spinner /></div>
          ) : (
            <>
              <div className='overflow-x-auto'>
                <table className='w-full text-sm'>
                  <thead className='bg-gray-50 text-gray-500 text-xs uppercase'>
                    <tr>
                      {['Mitarbeiter', 'Stunden', 'Status', 'Abrechnungsmonat', 'Notiz', 'Angelegt von', 'Datum', 'Aktion'].map(h => (
                        <th key={h} className='px-4 py-3 text-left font-medium'>{h}</th>
                      ))}
                    </tr>
                  </thead>
                  <tbody className='divide-y divide-gray-100'>
                    {payouts.map(payout => (
                      <tr key={payout.id} className='hover:bg-gray-50 transition-colors'>
                        <td className='px-4 py-3 font-medium text-gray-800'>{payout.user_name}</td>
                        <td className='px-4 py-3'>
                          <span className='font-bold text-purple-700'>
                            {Number(payout.hours).toFixed(2)} h
                          </span>
                        </td>
                        <td className='px-4 py-3'>
                          <StatusBadge status={payout.status} />
                          {payout.status === 'rejected' && payout.rejection_reason && (
                            <div className='text-xs text-gray-400 mt-0.5 max-w-[10rem] truncate' title={payout.rejection_reason}>
                              {payout.rejection_reason}
                            </div>
                          )}
                        </td>
                        <td className='px-4 py-3 text-gray-600'>
                          {formatPeriod(payout.period_year, payout.period_month)}
                        </td>
                        <td className='px-4 py-3 text-gray-500 max-w-xs truncate'>
                          {payout.note || '—'}
                        </td>
                        <td className='px-4 py-3 text-gray-500'>{payout.created_by_name}</td>
                        <td className='px-4 py-3 text-gray-500'>
                          {new Date(payout.created_at).toLocaleDateString('de-DE', {
                            day: '2-digit', month: '2-digit', year: 'numeric',
                          })}
                        </td>
                        <td className='px-4 py-3'>
                          {payout.status === 'requested' ? (
                            <div className='flex gap-2'>
                              <button
                                onClick={() => handleApprove(payout)}
                                className='text-xs text-green-600 hover:underline font-medium'
                                title='Genehmigen'
                              >
                                ✓ Genehmigen
                              </button>
                              <button
                                onClick={() => handleReject(payout)}
                                className='text-xs text-red-500 hover:underline'
                                title='Ablehnen'
                              >
                                ✗ Ablehnen
                              </button>
                            </div>
                          ) : payout.status === 'approved' ? (
                            <button
                              onClick={() => handleDelete(payout)}
                              className='text-xs text-red-500 hover:underline'
                              title='Stornieren'
                            >
                              🗑️ Stornieren
                            </button>
                          ) : (
                            <span className='text-xs text-gray-300'>—</span>
                          )}
                        </td>
                      </tr>
                    ))}
                    {payouts.length === 0 && (
                      <tr>
                        <td colSpan={8} className='px-4 py-10 text-center text-gray-400'>
                          Keine Auszahlungen gefunden.
                        </td>
                      </tr>
                    )}
                  </tbody>
                </table>
              </div>
              {totalCount > 0 && (
                <div className='px-4 py-3 border-t border-gray-100 text-xs text-gray-400'>
                  {totalCount} Einträge gesamt
                </div>
              )}
            </>
          )}
        </div>
      </div>

      {/* New Payout Modal */}
      {showModal && (
        <Modal
          title='Auszahlung anlegen'
          onClose={() => setShowModal(false)}
        >
          <div className='space-y-4'>

            {/* Mitarbeiter */}
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Mitarbeiter *</span>
              <select
                value={formUserId}
                onChange={e => handleUserChange(e.target.value)}
                className={inputClass}
              >
                <option value=''>— bitte wählen —</option>
                {users.map(u => (
                  <option key={u.id} value={u.id}>
                    {u.full_name}{u.personnel_number ? ` (${u.personnel_number})` : ''}
                  </option>
                ))}
              </select>
            </label>

            {/* Overtime balance indicator */}
            {formUserId && (
              <div className='text-sm'>
                {overtimeLoading ? (
                  <span className='text-gray-400'>Lade Überstundenguthaben…</span>
                ) : overtimeBalance !== null ? (
                  <span className={isOverBudget ? 'text-orange-600 font-medium' : 'text-green-700'}>
                    Verfügbares Überstundenguthaben: {Number(overtimeBalance).toFixed(2)} h
                    {isOverBudget && ' ⚠️ Auszahlung überschreitet verfügbares Guthaben'}
                  </span>
                ) : (
                  <span className='text-gray-400'>Guthaben nicht verfügbar</span>
                )}
              </div>
            )}

            {/* Stunden */}
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Stunden *</span>
              <input
                type='number'
                min='0.25'
                max='999'
                step='0.25'
                value={formHours}
                onChange={e => setFormHours(parseFloat(e.target.value))}
                className={inputClass}
              />
            </label>

            {/* Abrechnungsmonat */}
            <div>
              <div className='flex items-center gap-2 mb-2'>
                <span className='text-xs font-medium text-gray-700'>Abrechnungsmonat</span>
                <label className='flex items-center gap-1 text-xs text-gray-500 cursor-pointer'>
                  <input
                    type='checkbox'
                    checked={formHasPeriod}
                    onChange={e => setFormHasPeriod(e.target.checked)}
                    className='rounded'
                  />
                  angeben
                </label>
              </div>
              {formHasPeriod && (
                <div className='flex gap-3'>
                  <div className='flex-1'>
                    <label className='block text-xs text-gray-500 mb-1'>Jahr</label>
                    <input
                      type='number'
                      min={2000}
                      max={2100}
                      value={formYear}
                      onChange={e => setFormYear(Number(e.target.value))}
                      className={inputClass}
                    />
                  </div>
                  <div className='flex-1'>
                    <label className='block text-xs text-gray-500 mb-1'>Monat</label>
                    <select
                      value={formMonth}
                      onChange={e => setFormMonth(Number(e.target.value))}
                      className={inputClass}
                    >
                      {MONTH_NAMES.map((name, i) => (
                        <option key={i + 1} value={i + 1}>{name}</option>
                      ))}
                    </select>
                  </div>
                </div>
              )}
            </div>

            {/* Notiz */}
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Notiz</span>
              <textarea
                value={formNote}
                onChange={e => setFormNote(e.target.value)}
                maxLength={500}
                rows={3}
                placeholder='Optionale Notiz zur Auszahlung…'
                className={inputClass + ' resize-none'}
              />
              <span className='text-xs text-gray-400'>{formNote.length}/500</span>
            </label>

            {modalError && (
              <div className='text-sm text-red-600 bg-red-50 border border-red-200 rounded px-3 py-2'>
                {modalError}
              </div>
            )}

            <div className='flex justify-end gap-2 pt-2'>
              <button
                onClick={() => setShowModal(false)}
                className='px-4 py-2 text-sm text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-50'
              >
                Abbrechen
              </button>
              <button
                onClick={handleSave}
                disabled={modalSaving}
                className='px-4 py-2 text-sm font-semibold text-white bg-purple-600 rounded-lg hover:bg-purple-700 disabled:opacity-50'
              >
                {modalSaving ? 'Speichere…' : 'Auszahlung anlegen'}
              </button>
            </div>
          </div>
        </Modal>
      )}
    </Layout>
  )
}
