import { useState, useEffect, useCallback } from 'react'
import { useAlert } from '../context/AlertContext'
import { useAuth } from '../context/AuthContext'
import Forbidden from '../components/Forbidden'
import { motion, AnimatePresence } from 'framer-motion'
import ConfirmModal from '../components/ConfirmModal'
import useModalLock from '../hooks/useModalLock'
import FormField from '../components/FormField'

import apiFetch from '../utils/api'
const API_BASE = '/api/admin'

interface BalanceEntry {
  name: string
  vacation_total: number
  vacation_used: number
  vacation_remaining: number
  sick_used: number
}

interface UserShort {
  id: number | string
  name: string
}

interface FundUserData {
  name: string
  worked: number
  covered: number
  overtime: number
  missing: number
}

interface MonthFundData {
  month_name: string
  fund: number
  business_days: number
  users?: Record<string, FundUserData>
}

interface ProjectUser {
  user_id: number
  user_name: string
  hours: number
}

interface ProjectEntry {
  project_id: number | null
  project_number?: string
  project_name?: string
  hours: number
  users: ProjectUser[]
}

interface MonthProjectData {
  month_name: string
  projects: ProjectEntry[]
}

interface BalancesData {
  users: UserShort[]
  balances: Record<string, BalanceEntry>
}

interface FundData {
  months: Record<string, MonthFundData>
  holidays: unknown[]
  users: UserShort[]
  balances: Record<string, unknown>
}

interface ProjectData {
  months: Record<string, MonthProjectData>
}

const getVacationClass = (remaining: number): string => {
  if (remaining <= 0) return 'text-danger'
  if (remaining < 20) return 'text-warning'
  return ''
}

const renderFundDiff = (data: { overtime: number; missing: number }) => {
  if (data.overtime > 0) {
    return <span className="text-warning fw-600">+{data.overtime}h</span>
  }
  if (data.missing > 0) {
    return <span className="text-danger">-{data.missing}h</span>
  }
  return <span className="text-success">0h</span>
}

const renderMonthlyStatus = (us: FundUserData, isFulfilled: boolean, isCurrentMonth: boolean) => {
  if (us.overtime > 0) {
    return <span className="text-warning fw-600" style={{ fontSize: '11px' }}>+{us.overtime}h</span>
  }
  if (us.missing > 0) {
    return <span className="text-danger fw-600" style={{ fontSize: '11px' }}>-{us.missing}h</span>
  }
  if (isFulfilled && !isCurrentMonth) {
    return <span className="text-success" style={{ fontSize: '11px' }}>OK</span>
  }
  return null
}

const getProgressBackground = (us: FundUserData, isFulfilled: boolean, isCurrentMonth: boolean): string => {
  if (us.overtime > 0) return 'linear-gradient(135deg, var(--warning), #d97706)'
  if (isFulfilled) return 'linear-gradient(135deg, var(--success), #059669)'
  if (isCurrentMonth) return 'var(--gradient)'
  return 'var(--danger)'
}

export default function AttendanceBalances() {
  const alert = useAlert()
  const { hasPermission } = useAuth()
  const [loading, setLoading] = useState(true)
  const [year, setYear] = useState(new Date().getFullYear())
  const [data, setData] = useState<BalancesData>({
    users: [],
    balances: {}
  })

  const [fundLoading, setFundLoading] = useState(true)
  const [fundData, setFundData] = useState<FundData>({
    months: {},
    holidays: [],
    users: [],
    balances: {}
  })

  const [projectLoading, setProjectLoading] = useState(true)
  const [projectData, setProjectData] = useState<ProjectData>({ months: {} })

  const [showEditModal, setShowEditModal] = useState(false)
  const [editingUser, setEditingUser] = useState<{ id: string; name: string } | null>(null)
  const [editForm, setEditForm] = useState({
    vacation_total: 160,
    vacation_used: 0,
    sick_used: 0
  })

  const [resetConfirm, setResetConfirm] = useState<{ show: boolean; userId: string | null; userName: string }>({ show: false, userId: null, userName: '' })

  const fetchData = useCallback(async (showLoading = true) => {
    if (showLoading) setLoading(true)
    try {
      const response = await apiFetch(`${API_BASE}/attendance?action=balances&year=${year}`)
      const result = await response.json()
      if (result.success) {
        setData(result.data)
      }
    } catch {
      alert.error('Nepodařilo se načíst data')
    } finally {
      if (showLoading) setLoading(false)
    }
  }, [year, alert])

  const fetchFundData = useCallback(async () => {
    setFundLoading(true)
    try {
      const response = await apiFetch(`${API_BASE}/attendance?action=workfund&year=${year}`)
      const result = await response.json()
      if (result.success) {
        setFundData(result.data)
      }
    } catch {
      // silent - fund data is supplementary
    } finally {
      setFundLoading(false)
    }
  }, [year])

  const fetchProjectData = useCallback(async () => {
    setProjectLoading(true)
    try {
      const response = await apiFetch(`${API_BASE}/attendance?action=project_report&year=${year}`)
      const result = await response.json()
      if (result.success) {
        setProjectData(result.data)
      }
    } catch {
      // silent - project data is supplementary
    } finally {
      setProjectLoading(false)
    }
  }, [year])

  useEffect(() => {
    fetchData()
    fetchFundData()
    fetchProjectData()
  }, [fetchData, fetchFundData, fetchProjectData])

  useModalLock(showEditModal)

  if (!hasPermission('attendance.balances')) return <Forbidden />

  const openEditModal = (userId: string, balance: BalanceEntry) => {
    setEditingUser({ id: userId, name: balance.name })
    setEditForm({
      vacation_total: balance.vacation_total,
      vacation_used: balance.vacation_used,
      sick_used: balance.sick_used
    })
    setShowEditModal(true)
  }

  const handleEditSubmit = async () => {
    if (!editingUser) return
    try {
      const response = await apiFetch(`${API_BASE}/attendance?action=balances`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          user_id: editingUser.id,
          year,
          action_type: 'edit',
          ...editForm
        })
      })

      const result = await response.json()

      if (result.success) {
        setShowEditModal(false)
        await fetchData(false)
        await new Promise(resolve => setTimeout(resolve, 300))
        alert.success(result.message)
      } else {
        alert.error(result.error)
      }
    } catch {
      alert.error('Chyba připojení')
    }
  }

  const handleReset = async () => {
    if (!resetConfirm.userId) return

    try {
      const response = await apiFetch(`${API_BASE}/attendance?action=balances`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          user_id: resetConfirm.userId,
          year,
          action_type: 'reset'
        })
      })

      const result = await response.json()

      if (result.success) {
        setResetConfirm({ show: false, userId: null, userName: '' })
        await fetchData(false)
        alert.success(result.message)
      } else {
        alert.error(result.error)
      }
    } catch {
      alert.error('Chyba připojení')
    }
  }

  const years: number[] = []
  const currentYear = new Date().getFullYear()
  const currentMonth = new Date().getMonth() + 1
  for (let y = currentYear - 5; y <= currentYear + 5; y++) {
    years.push(y)
  }

  const getYearFundTotals = (userId: string) => {
    if (!fundData.months || Object.keys(fundData.months).length === 0) return null
    let totalFund = 0
    let totalWorked = 0
    let totalCovered = 0
    for (const monthData of Object.values(fundData.months)) {
      // Use prorated fund (fund_to_date) for current month, full fund for past
      totalFund += (monthData as any).fund_to_date ?? monthData.fund
      const us = monthData.users?.[userId]
      if (us) {
        totalWorked += us.worked
        totalCovered += us.covered
      }
    }
    const missing = Math.max(0, Math.round((totalFund - totalCovered) * 10) / 10)
    const overtime = Math.max(0, Math.round((totalCovered - totalFund) * 10) / 10)
    return { fund: totalFund, worked: Math.round(totalWorked * 10) / 10, covered: Math.round(totalCovered * 10) / 10, missing, overtime }
  }

  return (
    <div>
      <motion.div
        className="admin-page-header"
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25 }}
      >
        <div>
          <h1 className="admin-page-title">Správa bilancí</h1>
        </div>
        <div className="admin-page-actions">
          <select
            value={year}
            onChange={(e) => setYear(parseInt(e.target.value))}
            className="admin-form-select"
            style={{ minWidth: '100px' }}
          >
            {years.map((y) => (
              <option key={y} value={y}>{y}</option>
            ))}
          </select>
        </div>
      </motion.div>

      <motion.div
        className="admin-card"
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25, delay: 0.06 }}
      >
        <div className="admin-card-body">
          {loading && (
            <div className="admin-skeleton" style={{ gap: '1.25rem' }}>
              {[0, 1, 2, 3, 4].map(i => (
                <div key={i} className="admin-skeleton-row">
                  <div className="admin-skeleton-line w-1/4" />
                  <div className="admin-skeleton-line w-1/3" />
                  <div className="admin-skeleton-line w-1/4" />
                </div>
              ))}
            </div>
          )}
          {!loading && Object.keys(data.balances).length === 0 && (
            <div className="admin-empty-state">
              <p>Žádní uživatelé k zobrazení.</p>
            </div>
          )}
          {!loading && Object.keys(data.balances).length > 0 && (
            <div className="admin-table-responsive">
              <table className="admin-table">
                <thead>
                  <tr>
                    <th>Zaměstnanec</th>
                    <th>Nárok (h)</th>
                    <th>Čerpáno (h)</th>
                    <th>Zbývá (h)</th>
                    <th>Nemoc (h)</th>
                    <th>Fond roku</th>
                    <th>Odpracováno</th>
                    <th>+/−</th>
                    <th>Akce</th>
                  </tr>
                </thead>
                <tbody>
                  {Object.entries(data.balances).map(([userId, balance]) => {
                    const yf = getYearFundTotals(userId)
                    return (
                      <tr key={userId}>
                        <td className="fw-500">{balance.name}</td>
                        <td className="admin-mono">{balance.vacation_total}</td>
                        <td className="admin-mono">{balance.vacation_used.toFixed(1)}</td>
                        <td className="admin-mono">
                          <span
                            className={getVacationClass(balance.vacation_remaining)}
                          >
                            {balance.vacation_remaining.toFixed(1)}
                          </span>
                        </td>
                        <td className="admin-mono">{balance.sick_used.toFixed(1)}</td>
                        <td className="admin-mono">{yf ? `${yf.fund}h` : '—'}</td>
                        <td className="admin-mono">{yf ? `${yf.worked}h` : '—'}</td>
                        <td className="admin-mono">
                          {yf ? renderFundDiff(yf) : '—'}
                        </td>
                        <td>
                          <div className="admin-table-actions">
                            <button
                              onClick={() => openEditModal(userId, balance)}
                              className="admin-btn-icon"
                              title="Upravit"
                              aria-label="Upravit"
                            >
                              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                                <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
                                <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
                              </svg>
                            </button>
                            <button
                              onClick={() => setResetConfirm({ show: true, userId, userName: balance.name })}
                              className="admin-btn-icon danger"
                              title="Resetovat"
                              aria-label="Resetovat"
                            >
                              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                                <polyline points="3 6 5 6 21 6" />
                                <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                              </svg>
                            </button>
                          </div>
                        </td>
                      </tr>
                    )
                  })}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </motion.div>

      {/* Monthly Fund Overview */}
      {!fundLoading && fundData.months && Object.keys(fundData.months).length > 0 && (
        <motion.div
          initial={{ opacity: 0, y: 12 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.25, delay: 0.12 }}
          className="mt-6"
        >
          <h2 className="admin-page-title mb-4" style={{ fontSize: '1.25rem' }}>
            Měsíční přehled fondu {year}
          </h2>
          <div className="admin-grid admin-grid-3">
            {Object.entries(fundData.months).map(([monthKey, monthData]) => {
              const isCurrentMonth = year === currentYear && parseInt(monthKey) === currentMonth
              return (
                <div
                  key={monthKey}
                  className="admin-card"
                  style={isCurrentMonth ? {
                    borderColor: 'var(--accent-color)',
                    boxShadow: '0 0 0 1px var(--accent-color)'
                  } : {}}
                >
                  <div className="admin-card-body">
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '0.75rem' }}>
                      <h3 style={{ fontWeight: 600, fontSize: '1rem', margin: 0 }}>
                        {monthData.month_name}
                        {isCurrentMonth && (
                          <span style={{
                            marginLeft: '0.5rem',
                            fontSize: '0.7rem',
                            padding: '0.125rem 0.375rem',
                            background: 'var(--accent-light)',
                            color: 'var(--accent-color)',
                            borderRadius: 'var(--border-radius-sm)',
                            fontWeight: 500
                          }}>
                            aktuální
                          </span>
                        )}
                      </h3>
                      <span className="text-secondary" style={{ fontSize: '12px' }}>
                        {monthData.fund}h ({monthData.business_days} dnů)
                      </span>
                    </div>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: '0.375rem' }}>
                      {fundData.users && fundData.users.map(user => {
                        const us = monthData.users?.[String(user.id)]
                        if (!us) return null
                        const pct = monthData.fund > 0 ? Math.min(100, (us.covered / monthData.fund) * 100) : 0
                        const isFulfilled = us.covered >= monthData.fund
                        return (
                          <div key={user.id}>
                            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '12px' }}>
                              <span style={{ color: 'var(--text-primary)' }}>{us.name}</span>
                              <span style={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
                                <span className="text-secondary">{us.worked}h</span>
                                {renderMonthlyStatus(us, isFulfilled, isCurrentMonth)}
                              </span>
                            </div>
                            <div style={{
                              marginTop: '0.125rem',
                              height: '3px',
                              background: 'var(--bg-tertiary)',
                              borderRadius: '2px',
                              overflow: 'hidden'
                            }}>
                              <div style={{
                                height: '100%',
                                width: `${pct}%`,
                                background: getProgressBackground(us, isFulfilled, isCurrentMonth),
                                borderRadius: '2px',
                                transition: 'width 0.3s ease'
                              }} />
                            </div>
                          </div>
                        )
                      })}
                    </div>
                  </div>
                </div>
              )
            })}
          </div>
        </motion.div>
      )}

      {fundLoading && (
        <div className="mt-6">
          <div className="admin-skeleton" style={{ gap: '1.25rem' }}>
            {[0, 1, 2].map(i => (
              <div key={i} className="admin-skeleton-row">
                <div className="admin-skeleton-line w-1/4" />
                <div className="admin-skeleton-line w-1/3" />
                <div className="admin-skeleton-line w-1/4" />
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Monthly Project Overview */}
      {!projectLoading && projectData.months && Object.keys(projectData.months).length > 0 && (
        <motion.div
          initial={{ opacity: 0, y: 12 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.25, delay: 0.15 }}
          className="mt-6"
        >
          <h2 className="admin-page-title mb-4" style={{ fontSize: '1.25rem' }}>
            Měsíční přehled projektů {year}
          </h2>
          <div className="admin-grid admin-grid-3">
            {Object.entries(projectData.months).map(([monthKey, monthInfo]) => {
              const isCurrentMonth = year === currentYear && parseInt(monthKey) === currentMonth
              const totalHours = monthInfo.projects.reduce((sum, p) => sum + p.hours, 0)
              if (monthInfo.projects.length === 0) return null
              return (
                <div
                  key={monthKey}
                  className="admin-card"
                  style={isCurrentMonth ? {
                    borderColor: 'var(--accent-color)',
                    boxShadow: '0 0 0 1px var(--accent-color)'
                  } : {}}
                >
                  <div className="admin-card-body">
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '0.75rem' }}>
                      <h3 style={{ fontWeight: 600, fontSize: '1rem', margin: 0 }}>
                        {monthInfo.month_name}
                        {isCurrentMonth && (
                          <span style={{
                            marginLeft: '0.5rem',
                            fontSize: '0.7rem',
                            padding: '0.125rem 0.375rem',
                            background: 'var(--accent-light)',
                            color: 'var(--accent-color)',
                            borderRadius: 'var(--border-radius-sm)',
                            fontWeight: 500
                          }}>
                            aktuální
                          </span>
                        )}
                      </h3>
                      <span className="text-secondary fw-600" style={{ fontSize: '12px' }}>
                        {totalHours.toFixed(1)}h
                      </span>
                    </div>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
                      {monthInfo.projects.map((proj) => (
                        <div key={proj.project_id || 'no-project'}>
                          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '0.25rem' }}>
                            <span style={{ fontSize: '12px', fontWeight: 600, color: 'var(--text-primary)' }}>
                              {proj.project_id ? proj.project_number : 'Bez projektu'}
                            </span>
                            <span className="text-secondary fw-600" style={{ fontSize: '12px' }}>
                              {proj.hours.toFixed(1)}h
                            </span>
                          </div>
                          {proj.project_id && proj.project_name && (
                            <div className="text-muted" style={{ fontSize: '0.7rem', marginBottom: '0.25rem' }}>
                              {proj.project_name}
                            </div>
                          )}
                          <div style={{ display: 'flex', flexDirection: 'column', gap: '0.125rem' }}>
                            {proj.users.map((u) => {
                              const pct = proj.hours > 0 ? Math.min(100, (u.hours / proj.hours) * 100) : 0
                              return (
                                <div key={u.user_id}>
                                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '11px' }}>
                                    <span className="text-secondary">{u.user_name}</span>
                                    <span className="text-secondary">{u.hours.toFixed(1)}h</span>
                                  </div>
                                  <div style={{
                                    marginTop: '1px',
                                    height: '3px',
                                    background: 'var(--bg-tertiary)',
                                    borderRadius: '2px',
                                    overflow: 'hidden'
                                  }}>
                                    <div style={{
                                      height: '100%',
                                      width: `${pct}%`,
                                      background: proj.project_id
                                        ? 'var(--gradient)'
                                        : '#94a3b8',
                                      borderRadius: '2px',
                                      transition: 'width 0.3s ease'
                                    }} />
                                  </div>
                                </div>
                              )
                            })}
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              )
            })}
          </div>
        </motion.div>
      )}

      {projectLoading && (
        <div className="mt-6">
          <div className="admin-skeleton" style={{ gap: '1.25rem' }}>
            {[0, 1, 2].map(i => (
              <div key={i} className="admin-skeleton-row">
                <div className="admin-skeleton-line w-1/4" />
                <div className="admin-skeleton-line w-1/3" />
                <div className="admin-skeleton-line w-1/4" />
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Edit Modal */}
      <AnimatePresence>
        {showEditModal && editingUser && (
          <motion.div
            className="admin-modal-overlay"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
          >
            <div className="admin-modal-backdrop" onClick={() => setShowEditModal(false)} />
            <motion.div
              className="admin-modal"
              initial={{ opacity: 0, scale: 0.95, y: 20 }}
              animate={{ opacity: 1, scale: 1, y: 0 }}
              exit={{ opacity: 0, scale: 0.95, y: 20 }}
              transition={{ duration: 0.2 }}
            >
              <div className="admin-modal-header">
                <h2 className="admin-modal-title">Upravit dovolenou</h2>
                <p className="text-secondary" style={{ marginTop: '0.25rem' }}>
                  {editingUser.name}
                </p>
              </div>

              <div className="admin-modal-body">
                <div className="admin-form">
                  <FormField label="Nárok na dovolenou (hodiny)">
                    <input
                      type="number"
                      value={editForm.vacation_total}
                      onChange={(e) => setEditForm({ ...editForm, vacation_total: parseFloat(e.target.value) })}
                      min="0"
                      max="500"
                      step="1"
                      className="admin-form-input"
                    />
                  </FormField>

                  <FormField label="Čerpáno dovolené (hodiny)">
                    <input
                      type="number"
                      value={editForm.vacation_used}
                      onChange={(e) => setEditForm({ ...editForm, vacation_used: parseFloat(e.target.value) })}
                      min="0"
                      max="500"
                      step="0.5"
                      className="admin-form-input"
                    />
                  </FormField>

                  <FormField label="Čerpáno nemocenské (hodiny)">
                    <input
                      type="number"
                      value={editForm.sick_used}
                      onChange={(e) => setEditForm({ ...editForm, sick_used: parseFloat(e.target.value) })}
                      min="0"
                      max="500"
                      step="0.5"
                      className="admin-form-input"
                    />
                  </FormField>
                </div>
              </div>

              <div className="admin-modal-footer">
                <button
                  type="button"
                  onClick={() => setShowEditModal(false)}
                  className="admin-btn admin-btn-secondary"
                >
                  Zrušit
                </button>
                <button
                  type="button"
                  onClick={handleEditSubmit}
                  className="admin-btn admin-btn-primary"
                >
                  Uložit
                </button>
              </div>
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Reset Confirmation */}
      <ConfirmModal
        isOpen={resetConfirm.show}
        onClose={() => setResetConfirm({ show: false, userId: null, userName: '' })}
        onConfirm={handleReset}
        title="Resetovat bilanci"
        message={`Opravdu chcete vynulovat čerpání dovolené a nemocenské pro ${resetConfirm.userName} za rok ${year}?`}
        confirmText="Resetovat"
        confirmVariant="danger"
      />
    </div>
  )
}
