import { useEffect, useState } from 'react'
import type { SpecialAssignmentOut, SpecialAssignmentCreate, AssignmentMode } from '../types/specialAssignment'
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
}

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

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

interface AssignmentRow {
  assignment: SpecialAssignmentOut
  user: UserItem
}

const MODE_LABELS: Record<AssignmentMode, string> = {
  fza: 'FZA',
  payroll: 'Abrechnung',
  both: 'Beides',
}

const MODE_COLORS: Record<AssignmentMode, string> = {
  fza: 'bg-green-100 text-green-700',
  payroll: 'bg-blue-100 text-blue-700',
  both: 'bg-amber-100 text-amber-700',
}

function factorColor(factor: number): string {
  if (factor > 1.0) return 'text-amber-700 font-semibold'
  if (factor < 1.0) return 'text-blue-600 font-semibold'
  return 'text-gray-400'
}

function getMonthRange(yearMonth: string): { first: string; last: string } {
  const [y, m] = yearMonth.split('-').map(Number)
  const first = `${y}-${String(m).padStart(2, '0')}-01`
  const lastDate = new Date(y, m, 0)
  const last = `${y}-${String(m).padStart(2, '0')}-${String(lastDate.getDate()).padStart(2, '0')}`
  return { first, last }
}

function overlapsMonth(dateFrom: string, dateTo: string, yearMonth: string): boolean {
  const { first, last } = getMonthRange(yearMonth)
  return dateFrom <= last && dateTo >= first
}

function currentYearMonth(): string {
  const now = new Date()
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`
}

const BATCH_SIZE = 20

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

export function SpecialAssignmentsPage() {
  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 [filterUser, setFilterUser] = useState('')
  const [filterMonth, setFilterMonth] = useState(currentYearMonth())

  // Loaded assignments (flat list with user info)
  const [rows, setRows] = useState<AssignmentRow[]>([])
  const [tableLoading, setTableLoading] = useState(false)

  // Modal state
  const [showModal, setShowModal] = useState(false)
  const [editAssignment, setEditAssignment] = useState<SpecialAssignmentOut | null>(null)
  const [form, setForm] = useState<SpecialAssignmentCreate & { user_id: string }>({
    user_id: '',
    date_from: '',
    date_to: '',
    factor: 1.5,
    mode: 'both',
    label: '',
  })
  const [modalSaving, setModalSaving] = useState(false)
  const [modalError, setModalError] = useState<string | null>(null)

  // 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)
      } catch (e: unknown) {
        setPageError(e instanceof Error ? e.message : 'Fehler beim Laden')
      } finally {
        setPageLoading(false)
      }
    }
    init()
  }, [])

  async function loadAssignments(userIdFilter: string, usersToQuery: UserItem[]) {
    setTableLoading(true)
    setRows([])
    try {
      const targets = userIdFilter
        ? usersToQuery.filter(u => u.id === userIdFilter)
        : usersToQuery

      const allRows: AssignmentRow[] = []

      // Process in batches
      for (let i = 0; i < targets.length; i += BATCH_SIZE) {
        const batch = targets.slice(i, i + BATCH_SIZE)
        const results = await Promise.all(
          batch.map(u =>
            api.get<SpecialAssignmentOut[]>(`/users/${u.id}/special-assignments`)
              .then(assignments => assignments.map(a => ({ assignment: a, user: u })))
              .catch(() => [] as AssignmentRow[])
          )
        )
        for (const chunk of results) {
          allRows.push(...chunk)
        }
      }

      setRows(allRows)
    } finally {
      setTableLoading(false)
    }
  }

  function handleSearch() {
    if (users.length > 0) {
      loadAssignments(filterUser, users)
    }
  }

  // Load on mount once users are available
  useEffect(() => {
    if (users.length > 0) {
      loadAssignments(filterUser, users)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [users])

  // Filter rows client-side by month
  const filteredRows = rows
    .filter(r => overlapsMonth(r.assignment.date_from, r.assignment.date_to, filterMonth))
    .sort((a, b) => a.user.full_name.localeCompare(b.user.full_name))

  function openNewModal() {
    setEditAssignment(null)
    setForm({ user_id: filterUser, date_from: '', date_to: '', factor: 1.5, mode: 'both', label: '' })
    setModalError(null)
    setShowModal(true)
  }

  function openEditModal(row: AssignmentRow) {
    setEditAssignment(row.assignment)
    setForm({
      user_id: row.assignment.user_id,
      date_from: row.assignment.date_from,
      date_to: row.assignment.date_to,
      factor: row.assignment.factor,
      mode: row.assignment.mode,
      label: row.assignment.label ?? '',
    })
    setModalError(null)
    setShowModal(true)
  }

  async function handleSave() {
    if (!form.user_id || !form.date_from || !form.date_to) {
      setModalError('Mitarbeiter, Von und Bis sind Pflichtfelder.')
      return
    }
    setModalSaving(true)
    setModalError(null)
    try {
      const payload: SpecialAssignmentCreate = {
        date_from: form.date_from,
        date_to: form.date_to,
        factor: form.factor,
        mode: form.mode,
        label: form.label || undefined,
      }
      if (editAssignment) {
        const updated = await api.patch<SpecialAssignmentOut>(
          `/users/${form.user_id}/special-assignments/${editAssignment.id}`,
          payload
        )
        const user = users.find(u => u.id === form.user_id)!
        setRows(prev => prev.map(r =>
          r.assignment.id === editAssignment.id ? { assignment: updated, user } : r
        ))
      } else {
        const created = await api.post<SpecialAssignmentOut>(
          `/users/${form.user_id}/special-assignments`,
          payload
        )
        const user = users.find(u => u.id === form.user_id)!
        setRows(prev => [...prev, { assignment: created, user }])
      }
      setShowModal(false)
    } catch (e: unknown) {
      setModalError(e instanceof Error ? e.message : 'Fehler beim Speichern')
    } finally {
      setModalSaving(false)
    }
  }

  async function handleDelete(row: AssignmentRow) {
    if (!confirm(`Zuweisung für ${row.user.full_name} wirklich löschen?`)) return
    try {
      await api.del(`/users/${row.user.id}/special-assignments/${row.assignment.id}`)
      setRows(prev => prev.filter(r => r.assignment.id !== row.assignment.id))
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler beim Löschen')
    }
  }

  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>
  )

  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'>Sondervertretungen</h1>
            <p className='text-sm text-gray-500 mt-0.5'>Sondervertretungs-Zeiträume verwalten</p>
          </div>
          <button
            onClick={openNewModal}
            className='px-4 py-2 bg-blue-600 text-white text-sm font-semibold rounded-lg hover:bg-blue-700 transition-colors'
          >
            + Neu
          </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-44'>
              <label className='block text-xs font-medium text-gray-700 mb-1'>Monat</label>
              <input
                type='month'
                value={filterMonth}
                onChange={e => setFilterMonth(e.target.value)}
                className={inputClass}
              />
            </div>
            <button
              onClick={handleSearch}
              disabled={tableLoading}
              className='px-4 py-2 bg-blue-600 text-white text-sm font-semibold rounded-lg hover:bg-blue-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', 'Pers.-Nr.', 'Von', 'Bis', 'Faktor', 'Ziel', 'Bezeichnung', ''].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'>
                  {filteredRows.map(row => (
                    <tr key={row.assignment.id} className='hover:bg-gray-50 transition-colors'>
                      <td className='px-4 py-3 font-medium text-gray-800'>{row.user.full_name}</td>
                      <td className='px-4 py-3 text-gray-500 font-mono text-xs'>
                        {row.user.personnel_number || '—'}
                      </td>
                      <td className='px-4 py-3 text-gray-600'>
                        {new Date(row.assignment.date_from).toLocaleDateString('de-DE')}
                      </td>
                      <td className='px-4 py-3 text-gray-600'>
                        {new Date(row.assignment.date_to).toLocaleDateString('de-DE')}
                      </td>
                      <td className='px-4 py-3'>
                        <span className={factorColor(row.assignment.factor)}>
                          ×{Number(row.assignment.factor).toFixed(2)}
                        </span>
                      </td>
                      <td className='px-4 py-3'>
                        <span className={`inline-block text-xs px-2 py-0.5 rounded-full font-medium ${MODE_COLORS[row.assignment.mode]}`}>
                          {MODE_LABELS[row.assignment.mode]}
                        </span>
                      </td>
                      <td className='px-4 py-3 text-gray-500'>{row.assignment.label || '—'}</td>
                      <td className='px-4 py-3'>
                        <div className='flex gap-2 justify-end'>
                          <button
                            onClick={() => openEditModal(row)}
                            className='text-xs text-blue-600 hover:underline'
                          >
                            Bearbeiten
                          </button>
                          <button
                            onClick={() => handleDelete(row)}
                            className='text-xs text-red-500 hover:underline'
                          >
                            Löschen
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))}
                  {filteredRows.length === 0 && (
                    <tr>
                      <td colSpan={8} className='px-4 py-10 text-center text-gray-400'>
                        Keine Sondervertretungs-Zuweisungen gefunden.
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>

      {/* Add/Edit Modal */}
      {showModal && (
        <Modal
          title={editAssignment ? 'Zuweisung bearbeiten' : 'Zuweisung hinzufügen'}
          onClose={() => setShowModal(false)}
        >
          <div className='space-y-4'>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Mitarbeiter *</span>
              <select
                value={form.user_id}
                onChange={e => setForm(f => ({ ...f, user_id: e.target.value }))}
                className={inputClass}
                disabled={!!editAssignment}
              >
                <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>

            <div className='flex gap-3'>
              <label className='block flex-1'>
                <span className='text-xs font-medium text-gray-700'>Von *</span>
                <input
                  type='date'
                  value={form.date_from}
                  onChange={e => setForm(f => ({ ...f, date_from: e.target.value }))}
                  className={inputClass}
                />
              </label>
              <label className='block flex-1'>
                <span className='text-xs font-medium text-gray-700'>Bis *</span>
                <input
                  type='date'
                  value={form.date_to}
                  onChange={e => setForm(f => ({ ...f, date_to: e.target.value }))}
                  className={inputClass}
                />
              </label>
            </div>

            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Faktor</span>
              <input
                type='number'
                min='0.1'
                max='10'
                step='0.1'
                value={form.factor}
                onChange={e => setForm(f => ({ ...f, factor: parseFloat(e.target.value) }))}
                className={inputClass}
              />
            </label>

            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Ziel</span>
              <select
                value={form.mode}
                onChange={e => setForm(f => ({ ...f, mode: e.target.value as AssignmentMode }))}
                className={inputClass}
              >
                <option value='fza'>Nur FZA</option>
                <option value='payroll'>Nur Abrechnung</option>
                <option value='both'>FZA + Abrechnung</option>
              </select>
            </label>

            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Bezeichnung</span>
              <input
                type='text'
                value={form.label ?? ''}
                onChange={e => setForm(f => ({ ...f, label: e.target.value }))}
                placeholder='z.B. Schichtleiter-Vertretung'
                className={inputClass}
              />
            </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-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50'
              >
                {modalSaving ? 'Speichere…' : 'Speichern'}
              </button>
            </div>
          </div>
        </Modal>
      )}
    </Layout>
  )
}
