import { useEffect, useState } from 'react'
import api from '../api'
import toast from 'react-hot-toast'
import { useAuth } from '../context/AuthContext'

const CURRENT_YEAR = new Date().getFullYear()

function Modal({ title, onClose, children }) {
  return (
    <div className="fixed inset-0 bg-black/50 flex items-end sm:items-center justify-center z-50 p-0 sm:p-4">
      <div className="bg-white rounded-t-2xl sm:rounded-2xl shadow-xl w-full sm:max-w-lg max-h-[92vh] flex flex-col">
        <div className="flex items-center justify-between p-4 sm:p-6 border-b shrink-0 sticky top-0 bg-white z-10">
          <h2 className="text-lg font-semibold">{title}</h2>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-2xl leading-none">&times;</button>
        </div>
        <div className="p-4 sm:p-6 overflow-y-auto">{children}</div>
      </div>
    </div>
  )
}

function CategoryBadge({ value, categories }) {
  const cat = categories.find(c => c.value === value)
  return <span className="inline-flex items-center gap-1 text-xs bg-blue-50 text-blue-700 px-2 py-0.5 rounded-full font-medium">{cat ? `${cat.icon} ${cat.label}` : value}</span>
}

export default function Charges() {
  const { user } = useAuth()
  const [properties, setProperties] = useState([])
  const [charges, setCharges] = useState([])
  const [filterProperty, setFilterProperty] = useState('')
  const [filterYear, setFilterYear] = useState(String(CURRENT_YEAR))
  const [showModal, setShowModal] = useState(false)
  const [showBilan, setShowBilan] = useState(false)
  const [bilan, setBilan] = useState(null)
  const [bilanLoading, setBilanLoading] = useState(false)
  const [pdfLoadingLeaseId, setPdfLoadingLeaseId] = useState(null)
  const [closingLeaseId, setClosingLeaseId] = useState(null)
  const [cancelingLeaseId, setCancelingLeaseId] = useState(null)
  const [loading, setLoading] = useState(false)
  const [editCharge, setEditCharge] = useState(null)
  const [deductibleSummary, setDeductibleSummary] = useState(null)
  const [showDeductible, setShowDeductible] = useState(false)
  const [categories, setCategories] = useState([])
  const [availableYears, setAvailableYears] = useState([CURRENT_YEAR])

  const emptyForm = {
    property_id: '',
    category: 'eau',
    label: '',
    amount: '',
    date: new Date().toISOString().slice(0, 10),
    year: String(CURRENT_YEAR),
    notes: '',
    invoice: null,
    recoverable_type: 'recoverable',
  }
  const [form, setForm] = useState(emptyForm)

  const loadProperties = async () => {
    const { data } = await api.get('/properties')
    setProperties(data)
    if (data.length && !filterProperty) setFilterProperty(String(data[0].id))
  }

  const loadCharges = async () => {
    const params = new URLSearchParams()
    if (filterProperty) params.append('property_id', filterProperty)
    if (filterYear) params.append('year', filterYear)
    const { data } = await api.get(`/charges?${params}`)
    setCharges(data)
  }

  const loadDeductibleSummary = async () => {
    if (!filterProperty) { setDeductibleSummary(null); return }
    try {
      const { data } = await api.get(`/charges/deductible-summary/${filterProperty}`)
      setDeductibleSummary(data)
    } catch { setDeductibleSummary(null) }
  }

  // Load all distinct years from charges (unfiltered by year) to populate year selectors
  const loadAvailableYears = async () => {
    const params = new URLSearchParams()
    if (filterProperty) params.append('property_id', filterProperty)
    try {
      const { data } = await api.get(`/charges?${params}`)
      const yearsFromData = [...new Set(data.map(c => c.year).filter(Boolean))]
      const merged = [...new Set([CURRENT_YEAR, ...yearsFromData])].sort((a, b) => b - a)
      setAvailableYears(merged)
    } catch {}
  }

  useEffect(() => { loadProperties(); api.get('/categories').then(r => setCategories(r.data)) }, [])
  useEffect(() => { if (filterProperty) { loadCharges(); loadDeductibleSummary(); loadAvailableYears() } }, [filterProperty, filterYear])

  const openAdd = () => {
    setEditCharge(null)
    setForm({ ...emptyForm, property_id: filterProperty, year: filterYear })
    setShowModal(true)
  }

  const openEdit = (c) => {
    setEditCharge(c)
    setForm({
      property_id: String(c.property_id),
      category: c.category,
      label: c.label,
      amount: String(c.amount),
      date: c.date,
      year: String(c.year),
      notes: c.notes || '',
      invoice: null,
      recoverable_type: c.recoverable_type || (c.recoverable !== 0 ? 'recoverable' : 'none'),
    })
    setShowModal(true)
  }

  const handleSubmit = async e => {
    e.preventDefault(); setLoading(true)
    try {
      const fd = new FormData()
      Object.entries(form).forEach(([k, v]) => {
        if (k === 'invoice') { if (v) fd.append('invoice', v) }
        else fd.append(k, v)
      })
      if (editCharge) {
        await api.put(`/charges/${editCharge.id}`, fd, { headers: { 'Content-Type': 'multipart/form-data' } })
        toast.success('Charge mise à jour !')
      } else {
        await api.post('/charges', fd, { headers: { 'Content-Type': 'multipart/form-data' } })
        toast.success('Charge ajoutée !')
      }
      setShowModal(false)
      loadCharges()
    } catch (err) { toast.error(err.response?.data?.error || 'Erreur') }
    finally { setLoading(false) }
  }

  const handleDelete = async (id) => {
    if (!confirm('Supprimer cette charge ?')) return
    try { await api.delete(`/charges/${id}`); toast.success('Charge supprimée'); loadCharges() }
    catch { toast.error('Erreur lors de la suppression') }
  }

  const downloadInvoice = async (charge) => {
    try {
      const token = localStorage.getItem('token')
      const resp = await fetch(`/api/charges/${charge.id}/invoice`, {
        headers: { Authorization: `Bearer ${token}` }
      })
      if (!resp.ok) throw new Error()
      const blob = await resp.blob()
      const url = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url; a.download = charge.invoice_name; a.click()
      window.URL.revokeObjectURL(url)
    } catch { toast.error('Impossible de télécharger la facture') }
  }

  const loadBilan = async () => {
    if (!filterProperty || !filterYear) return
    setBilanLoading(true)
    try {
      const { data } = await api.get(`/charges/bilan/${filterProperty}/${filterYear}`)
      setBilan(data)
      setShowBilan(true)
    } catch (err) { toast.error(err.response?.data?.error || 'Erreur bilan') }
    finally { setBilanLoading(false) }
  }

  const printBilan = () => {
    if (!bilan) return
    const catLabel = v => { const c = categories.find(c => c.value === v); return c ? `${c.icon} ${c.label}` : v }
    const fmtEur = v => `${Number(v).toFixed(2)} €`
    const solde = bilan.total_provisions_percues - bilan.total_charges_reelles
    const isPos = solde >= 0
    const ownerName = (user?.first_name && user?.last_name) ? `${user.first_name} ${user.last_name}` : (user?.name || '')
    const ownerBlock = `<div class="owner-block">
      <span class="owner-label">BAILLEUR</span>
      <strong>${ownerName}</strong>
      ${user?.address ? `<br>${user.address}` : ''}
      ${user?.email ? `<br>${user.email}` : ''}
      ${user?.phone ? `<br>${user.phone}` : ''}
    </div>`

    const tenantsRows = bilan.bilans.map(b => {
      const pos = b.trop_percu >= 0
      return `
        <div class="tenant-block">
          <div class="tenant-header">
            <div>
              <strong>${b.tenant_name}</strong>
              ${b.tenant_email ? `<br><span class="small">${b.tenant_email}</span>` : ''}
            </div>
            <span class="badge ${pos ? 'badge-green' : 'badge-orange'}">${pos ? '↩ Remboursement' : '↑ Appel de fonds'}</span>
          </div>
          <table class="inner-table">
            <tr>
              <td>Occupation</td>
              <td class="amount">${b.occupied_days} / ${b.year_days} jours (${Number(b.ratio_percent || 0).toFixed(2)}%)</td>
            </tr>
            <tr>
              <td>Provisions perçues</td>
              <td class="amount">${fmtEur(b.provisions_percues)}</td>
            </tr>
            <tr>
              <td>Quote-part des charges réelles (prorata occupation)</td>
              <td class="amount">${fmtEur(b.quote_part_charges)}</td>
            </tr>
            <tr class="${pos ? 'row-green' : 'row-orange'}">
              <td><strong>${pos ? 'Trop-perçu à restituer' : 'Solde restant dû'}</strong></td>
              <td class="amount"><strong>${fmtEur(Math.abs(b.trop_percu))}</strong></td>
            </tr>
          </table>
        </div>`
    }).join('')

    const catRows = bilan.charges_by_category.map(c => {
      const pct = bilan.total_charges_reelles > 0 ? (c.total / bilan.total_charges_reelles * 100).toFixed(1) : 0
      return `<tr><td>${catLabel(c.category)}</td><td class="amount">${fmtEur(c.total)}</td><td class="pct">${pct}%</td></tr>`
    }).join('')

    const html = `<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Bilan de charges ${bilan.year} — ${bilan.property?.name}</title>
<style>
  * { box-sizing: border-box; margin: 0; padding: 0; }
  body { font-family: Arial, sans-serif; font-size: 13px; color: #1a1a1a; padding: 40px; max-width: 800px; margin: auto; }
  h1 { font-size: 22px; font-weight: bold; margin-bottom: 4px; }
  h2 { font-size: 15px; font-weight: 600; margin: 24px 0 10px; border-bottom: 1px solid #e5e7eb; padding-bottom: 6px; }
  .subtitle { color: #6b7280; font-size: 12px; margin-bottom: 28px; }
  .summary { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-bottom: 24px; }
  .card { border: 1px solid #e5e7eb; border-radius: 10px; padding: 14px; text-align: center; }
  .card .label { font-size: 11px; color: #6b7280; margin-bottom: 4px; }
  .card .value { font-size: 20px; font-weight: bold; }
  .card.red .value { color: #dc2626; }
  .card.blue .value { color: #2563eb; }
  .card.green { border-color: #bbf7d0; background: #f0fdf4; }
  .card.green .value { color: #15803d; }
  .card.orange { border-color: #fed7aa; background: #fff7ed; }
  .card.orange .value { color: #c2410c; }
  .card .note { font-size: 11px; color: #9ca3af; margin-top: 4px; }
  table { width: 100%; border-collapse: collapse; }
  table th { text-align: left; padding: 8px 10px; background: #f9fafb; font-size: 12px; color: #374151; }
  table td { padding: 8px 10px; border-bottom: 1px solid #f3f4f6; }
  td.amount { text-align: right; font-weight: 600; }
  td.pct { text-align: right; color: #6b7280; font-size: 11px; }
  .tenant-block { border: 1px solid #e5e7eb; border-radius: 10px; padding: 14px; margin-bottom: 12px; }
  .tenant-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px; }
  .tenant-header strong { font-size: 14px; }
  .small { font-size: 11px; color: #9ca3af; }
  .badge { font-size: 11px; font-weight: 600; padding: 3px 8px; border-radius: 99px; }
  .badge-green { background: #dcfce7; color: #15803d; }
  .badge-orange { background: #ffedd5; color: #c2410c; }
  .inner-table td { padding: 6px 8px; border-bottom: 1px solid #f3f4f6; font-size: 12px; }
  .row-green td { background: #f0fdf4; color: #15803d; }
  .row-orange td { background: #fff7ed; color: #c2410c; }
  .footer { margin-top: 40px; padding-top: 16px; border-top: 1px solid #e5e7eb; font-size: 11px; color: #9ca3af; text-align: center; }
  .owner-block { border: 1px solid #e5e7eb; border-radius: 8px; padding: 10px 14px; margin-bottom: 20px; font-size: 12px; line-height: 1.6; }
  .owner-label { display: block; font-size: 10px; color: #6b7280; font-weight: 600; margin-bottom: 2px; letter-spacing: 0.05em; }
  @media print {
    body { padding: 20px; }
    .no-print { display: none; }
  }
</style>
</head>
<body>
  <h1>Bilan annuel de charges ${bilan.year}</h1>
  <p class="subtitle">${bilan.property?.name} — ${bilan.property?.address || ''}</p>

  ${ownerBlock}
  <div class="summary">
      <div class="label">Charges réelles</div>
      <div class="value red">${fmtEur(bilan.total_charges_reelles)}</div>
      <div class="note">${bilan.charges_count} facture${bilan.charges_count > 1 ? 's' : ''}</div>
    </div>
    <div class="card">
      <div class="label">Provisions perçues</div>
      <div class="value blue">${fmtEur(bilan.total_provisions_percues)}</div>
    </div>
    <div class="card ${isPos ? 'green' : 'orange'}">
      <div class="label">${isPos ? 'Trop-perçu global' : 'Solde insuffisant'}</div>
      <div class="value">${isPos ? '+' : '-'}${fmtEur(Math.abs(solde))}</div>
    </div>
  </div>

  ${bilan.charges_by_category.length > 0 ? `
  <h2>Répartition des charges par catégorie</h2>
  <table>
    <thead><tr><th>Catégorie</th><th style="text-align:right">Montant</th><th style="text-align:right">%</th></tr></thead>
    <tbody>${catRows}</tbody>
    <tfoot><tr><td><strong>Total</strong></td><td class="amount"><strong>${fmtEur(bilan.total_charges_reelles)}</strong></td><td></td></tr></tfoot>
  </table>` : ''}

  ${bilan.bilans.length > 0 ? `<h2>Décompte par locataire</h2>${tenantsRows}` : ''}

  <div class="footer">Document généré le ${new Date().toLocaleDateString('fr-FR')} — Bilan de régularisation de charges ${bilan.year}</div>

  <script>window.onload = () => window.print()<\/script>
</body>
</html>`

    const w = window.open('', '_blank')
    w.document.write(html)
    w.document.close()
  }

  const downloadPdfLease = async (leaseBilan) => {
    if (!filterProperty || !filterYear || !leaseBilan?.lease_id) return
    setPdfLoadingLeaseId(leaseBilan.lease_id)
    try {
      const token = localStorage.getItem('token')
      const resp = await fetch(`/api/charges/bilan/${filterProperty}/${filterYear}/pdf?lease_id=${leaseBilan.lease_id}`, {
        headers: { Authorization: `Bearer ${token}` }
      })
      if (!resp.ok) throw new Error()
      const blob = await resp.blob()
      const url = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      const tenantSlug = leaseBilan.tenant_name.replace(/[^a-z0-9]/gi, '_')
      a.download = `decompte_charges_${filterYear}_${tenantSlug}.pdf`
      a.click()
      window.URL.revokeObjectURL(url)
    } catch { toast.error('Erreur lors de la génération du PDF') }
    finally { setPdfLoadingLeaseId(null) }
  }

  const cancelLeaseExercise = async (leaseBilan) => {
    if (!filterProperty || !filterYear || !leaseBilan?.lease_id) return
    const appliedWarning = leaseBilan.applied_payment_id
      ? '\n\n⚠️ Cette régularisation a déjà été appliquée à un paiement. Ce paiement sera corrigé (montant de régularisation remis à 0).'
      : ''
    if (!confirm(
      `Annuler la clôture du bilan annuel des charges ${filterYear} pour ${leaseBilan.tenant_name} ?` +
      appliedWarning +
      '\n\nCette action est irréversible.'
    )) return
    setCancelingLeaseId(leaseBilan.lease_id)
    try {
      await api.delete(`/charges/bilan/${filterProperty}/${filterYear}/close/${leaseBilan.lease_id}`)
      toast.success(`Clôture annulée pour ${leaseBilan.tenant_name} (${filterYear})`)
      await loadBilan()
    } catch (err) {
      toast.error(err.response?.data?.error || 'Erreur lors de l\'annulation')
    } finally {
      setCancelingLeaseId(null)
    }
  }

  const closeLeaseExercise = async (leaseBilan) => {
    if (!filterProperty || !filterYear || !leaseBilan?.lease_id) return
    if (!confirm(
      `Clôturer le bilan annuel des charges ${filterYear} pour ${leaseBilan.tenant_name} ?\n\n` +
      `Le calcul se fera au prorata d'occupation (${leaseBilan.occupied_days}/${leaseBilan.year_days} jours).\n\n` +
      `Cette opération est définitive.`
    )) return
    setClosingLeaseId(leaseBilan.lease_id)
    try {
      const { data } = await api.post(`/charges/bilan/${filterProperty}/${filterYear}/close`, {
        lease_id: leaseBilan.lease_id
      })
      const reg = data.regularizations?.[0]
      if (reg) {
        toast.success(
          `Bilan annuel clôturé (${filterYear}) : ${reg.tenant} | Prorata ${reg.occupied_days}/${reg.year_days} jours | ` +
          `${reg.trop_percu >= 0 ? '-' : '+'}${Math.abs(reg.trop_percu).toFixed(2)} € sur le prochain loyer`,
          { duration: 6000 }
        )
      } else {
        toast.success(`Bilan annuel clôturé pour ${filterYear}`)
      }
      await loadBilan()
    } catch (err) {
      toast.error(err.response?.data?.error || 'Erreur lors de la clôture')
    } finally {
      setClosingLeaseId(null)
    }
  }

  const fmt = v => `${Number(v).toFixed(2)} €`
  const fmtDate = d => d ? new Date(d + 'T00:00:00').toLocaleDateString('fr-FR') : '—'
  const totalAmount = charges.reduce((s, c) => s + c.amount, 0)

  return (
    <div>
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-6">
        <div>
          <h1 className="text-2xl font-bold text-gray-900">🧾 Gestion des charges</h1>
          <p className="text-gray-500 text-sm mt-1">Charges réelles par immeuble et bilan annuel</p>
        </div>
        <div className="flex flex-wrap gap-2">
          <button onClick={loadBilan} disabled={!filterProperty || bilanLoading}
            className="btn-secondary flex items-center gap-2 text-sm">
            {bilanLoading ? '...' : '📊 Bilan annuel'}
          </button>
          <button onClick={openAdd} className="btn-primary text-sm">+ Ajouter une charge</button>
        </div>
      </div>

      {/* Filters */}
      <div className="card mb-6 flex flex-wrap gap-4">
        <div className="flex-1 min-w-48">
          <label className="label">Immeuble / Bien</label>
          <select className="input" value={filterProperty} onChange={e => setFilterProperty(e.target.value)}>
            <option value="">Tous les biens</option>
            {properties.map(p => <option key={p.id} value={p.id}>{p.name} — {p.address}</option>)}
          </select>
        </div>
        <div className="w-36">
          <label className="label">Année</label>
          <select className="input" value={filterYear} onChange={e => setFilterYear(e.target.value)}>
            {availableYears.map(y => <option key={y} value={y}>{y}</option>)}
          </select>
        </div>
        {filterProperty && filterYear && (
          <div className="flex items-end">
            <div className="bg-blue-50 border border-blue-200 rounded-lg px-4 py-2 text-sm">
              <span className="text-blue-500">Total charges :</span>
              <span className="text-blue-800 font-bold ml-2">{fmt(totalAmount)}</span>
              <span className="text-blue-400 ml-2">({charges.length} ligne{charges.length > 1 ? 's' : ''})</span>
            </div>
          </div>
        )}
      </div>

      {/* Deductible summary table (10 years) */}
      {filterProperty && deductibleSummary && (
        <div className="card mb-6">
          <button
            onClick={() => setShowDeductible(v => !v)}
            className="w-full flex items-center justify-between text-left"
          >
            <div className="flex items-center gap-2">
              <span className="text-lg">💼</span>
              <div>
                <h3 className="text-sm font-semibold text-purple-800">Charges déductibles des impôts — 10 ans</h3>
                <p className="text-xs text-purple-500">
                  Total cumulé : <span className="font-bold">{fmt(deductibleSummary.grand_total)}</span>
                </p>
              </div>
            </div>
            <span className={`text-gray-400 transition-transform ${showDeductible ? 'rotate-180' : ''}`}>▼</span>
          </button>
          {showDeductible && (
            <div className="mt-4 overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="bg-purple-50 border-b border-purple-100">
                    <th className="text-left px-4 py-2 text-purple-700 font-semibold">Année</th>
                    <th className="text-right px-4 py-2 text-purple-700 font-semibold">Montant déductible</th>
                    <th className="text-right px-4 py-2 text-purple-700 font-semibold">Nb factures</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-purple-50">
                  {deductibleSummary.years.map(y => (
                    <tr key={y.year} className={`hover:bg-purple-50/50 ${String(y.year) === filterYear ? 'bg-purple-50 font-semibold' : ''}`}>
                      <td className="px-4 py-2 text-gray-700">{y.year}</td>
                      <td className={`px-4 py-2 text-right ${y.total > 0 ? 'text-purple-700' : 'text-gray-300'}`}>
                        {y.total > 0 ? fmt(y.total) : '—'}
                      </td>
                      <td className={`px-4 py-2 text-right ${y.count > 0 ? 'text-gray-600' : 'text-gray-300'}`}>
                        {y.count > 0 ? y.count : '—'}
                      </td>
                    </tr>
                  ))}
                </tbody>
                <tfoot className="bg-purple-50 border-t-2 border-purple-200">
                  <tr>
                    <td className="px-4 py-2 font-bold text-purple-800">Total (10 ans)</td>
                    <td className="px-4 py-2 text-right font-bold text-purple-800">{fmt(deductibleSummary.grand_total)}</td>
                    <td className="px-4 py-2 text-right font-bold text-gray-600">
                      {deductibleSummary.years.reduce((s, y) => s + y.count, 0)}
                    </td>
                  </tr>
                </tfoot>
              </table>
            </div>
          )}
        </div>
      )}

      {/* Charges list */}
      {charges.length === 0 ? (
        <div className="card text-center py-12">
          <p className="text-4xl mb-3">🧾</p>
          <p className="text-gray-500">Aucune charge enregistrée pour cette période.</p>
          <button onClick={openAdd} className="btn-primary mt-4">Ajouter une première charge</button>
        </div>
      ) : (
        <div>
          {/* Desktop table */}
          <div className="card overflow-hidden p-0 hidden md:block">
            <table className="w-full">
              <thead className="bg-gray-50 border-b">
                <tr>
                  <th className="text-left px-6 py-3 text-sm font-semibold text-gray-600">Date</th>
                  <th className="text-left px-6 py-3 text-sm font-semibold text-gray-600">Catégorie</th>
                  <th className="text-left px-6 py-3 text-sm font-semibold text-gray-600">Libellé</th>
                  <th className="text-left px-6 py-3 text-sm font-semibold text-gray-600">Immeuble</th>
                  <th className="text-right px-6 py-3 text-sm font-semibold text-gray-600">Montant</th>
                  <th className="text-center px-6 py-3 text-sm font-semibold text-gray-600">Récup.</th>
                  <th className="text-center px-6 py-3 text-sm font-semibold text-gray-600">Facture</th>
                  <th className="px-6 py-3"></th>
                </tr>
              </thead>
              <tbody className="divide-y divide-gray-50">
                {charges.map(c => (
                  <tr key={c.id} className="hover:bg-gray-50">
                    <td className="px-6 py-4 text-sm text-gray-600">{fmtDate(c.date)}</td>
                    <td className="px-6 py-4"><CategoryBadge value={c.category} categories={categories} /></td>
                    <td className="px-6 py-4 text-gray-900 font-medium">{c.label}</td>
                    <td className="px-6 py-4 text-sm text-gray-500">{c.property_name}</td>
                    <td className="px-6 py-4 text-right font-semibold text-gray-900">{fmt(c.amount)}</td>
                    <td className="px-6 py-4 text-center">
                      {c.recoverable_type === 'recoverable'
                        ? <span className="text-xs bg-green-100 text-green-700 font-semibold px-2 py-0.5 rounded-full">✓ Locataire</span>
                        : c.recoverable_type === 'deductible'
                          ? <span className="text-xs bg-purple-100 text-purple-700 font-semibold px-2 py-0.5 rounded-full">💼 Déductible</span>
                          : <span className="text-xs bg-gray-100 text-gray-500 font-semibold px-2 py-0.5 rounded-full">✗ Aucun</span>}
                    </td>
                    <td className="px-6 py-4 text-center">
                      {c.invoice_path ? (
                        <button onClick={() => downloadInvoice(c)} className="text-green-600 hover:text-green-800 text-sm font-medium" title={c.invoice_name}>
                          📎 {c.invoice_name?.length > 20 ? c.invoice_name.slice(0, 17) + '…' : c.invoice_name}
                        </button>
                      ) : <span className="text-gray-300 text-xs">—</span>}
                    </td>
                    <td className="px-6 py-4 text-right space-x-2 whitespace-nowrap">
                      <button onClick={() => openEdit(c)} className="text-blue-500 hover:text-blue-700 text-sm">✏️</button>
                      <button onClick={() => handleDelete(c.id)} className="text-gray-400 hover:text-red-600 ml-1">🗑️</button>
                    </td>
                  </tr>
                ))}
              </tbody>
              <tfoot className="bg-gray-50 border-t-2 border-gray-200">
                <tr>
                  <td colSpan={5} className="px-6 py-3 text-sm font-semibold text-gray-700">Total</td>
                  <td className="px-6 py-3 text-right font-bold text-gray-900">{fmt(totalAmount)}</td>
                  <td colSpan={2}></td>
                </tr>
              </tfoot>
            </table>
          </div>

          {/* Mobile cards */}
          <div className="md:hidden space-y-3">
            {charges.map(c => (
              <div key={c.id} className="card">
                <div className="flex items-start justify-between mb-1">
                  <div className="flex-1 min-w-0">
                    <p className="font-semibold text-gray-900 truncate">{c.label}</p>
                    <div className="flex items-center gap-2 mt-1 flex-wrap">
                      <CategoryBadge value={c.category} categories={categories} />
                      {c.recoverable_type === 'recoverable'
                        ? <span className="text-xs bg-green-100 text-green-700 px-1.5 py-0.5 rounded-full font-medium">Locataire</span>
                        : c.recoverable_type === 'deductible'
                          ? <span className="text-xs bg-purple-100 text-purple-700 px-1.5 py-0.5 rounded-full font-medium">Déductible</span>
                          : <span className="text-xs bg-gray-100 text-gray-400 px-1.5 py-0.5 rounded-full font-medium">Aucun</span>}
                    </div>
                  </div>
                  <p className="font-bold text-gray-900 text-lg ml-3 shrink-0">{fmt(c.amount)}</p>
                </div>
                <p className="text-sm text-gray-500">{fmtDate(c.date)}</p>
                <div className="flex items-center justify-between mt-3 pt-3 border-t border-gray-50">
                  {c.invoice_path
                    ? <button onClick={() => downloadInvoice(c)} className="text-green-600 text-sm">📎 Facture</button>
                    : <span />}
                  <div className="flex gap-3">
                    <button onClick={() => openEdit(c)} className="text-blue-500 text-sm">✏️ Modifier</button>
                    <button onClick={() => handleDelete(c.id)} className="text-red-400 text-sm">🗑️</button>
                  </div>
                </div>
              </div>
            ))}
            <div className="card bg-gray-50 flex justify-between items-center">
              <span className="font-semibold text-gray-700">Total</span>
              <span className="font-bold text-gray-900">{fmt(totalAmount)}</span>
            </div>
          </div>
        </div>
      )}

      {/* Add/Edit Modal */}
      {showModal && (
        <Modal title={editCharge ? 'Modifier la charge' : 'Ajouter une charge'} onClose={() => setShowModal(false)}>
          <form onSubmit={handleSubmit} className="space-y-4">
            <div>
              <label className="label">Immeuble / Bien *</label>
              <select className="input" required value={form.property_id}
                onChange={e => setForm(f => ({ ...f, property_id: e.target.value }))}>
                <option value="">— Sélectionner —</option>
                {properties.map(p => <option key={p.id} value={p.id}>{p.name} — {p.address}</option>)}
              </select>
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div>
                <label className="label">Catégorie *</label>
                <select className="input" value={form.category}
                  onChange={e => setForm(f => ({ ...f, category: e.target.value }))}>
                  {categories.map(c => <option key={c.value} value={c.value}>{c.icon} {c.label}</option>)}
                </select>
              </div>
              <div>
                <label className="label">Année *</label>
                <select className="input" value={form.year}
                  onChange={e => setForm(f => ({ ...f, year: e.target.value }))}>
                  {availableYears.map(y => <option key={y} value={y}>{y}</option>)}
                </select>
              </div>
            </div>
            <div>
              <label className="label">Libellé *</label>
              <input className="input" required value={form.label}
                onChange={e => setForm(f => ({ ...f, label: e.target.value }))}
                placeholder="Ex : Facture eau T1 2024" />
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div>
                <label className="label">Montant (€) *</label>
                <input className="input" type="number" step="0.01" min="0" required value={form.amount}
                  onChange={e => setForm(f => ({ ...f, amount: e.target.value }))} />
              </div>
              <div>
                <label className="label">Date de la dépense *</label>
                <input className="input" type="date" required value={form.date}
                  onChange={e => setForm(f => ({ ...f, date: e.target.value }))} />
              </div>
            </div>
            <div>
              <label className="label">Notes (optionnel)</label>
              <input className="input" value={form.notes}
                onChange={e => setForm(f => ({ ...f, notes: e.target.value }))}
                placeholder="Numéro de facture, prestataire…" />
            </div>
            <div>
              <label className="label">Affectation de la charge</label>
              <div className="space-y-2 mt-1">
                {[
                  { value: 'recoverable', label: '✓ Récupérable auprès du locataire', sub: 'Incluse dans le bilan de régularisation annuel', color: 'green' },
                  { value: 'deductible', label: '💼 Déductible des impôts', sub: 'Charge du propriétaire déductible fiscalement', color: 'purple' },
                  { value: 'none', label: '✗ Aucun des deux', sub: 'Charge non récupérable et non déductible', color: 'gray' },
                ].map(opt => (
                  <label key={opt.value} className={`flex items-start gap-3 cursor-pointer rounded-xl border-2 p-3 transition-colors ${form.recoverable_type === opt.value ? `border-${opt.color}-400 bg-${opt.color}-50` : 'border-gray-100 hover:border-gray-200'}`}>
                    <input type="radio" name="recoverable_type" value={opt.value}
                      checked={form.recoverable_type === opt.value}
                      onChange={e => setForm(f => ({ ...f, recoverable_type: e.target.value }))}
                      className="mt-0.5 accent-blue-600" />
                    <div>
                      <p className="text-sm font-medium text-gray-800">{opt.label}</p>
                      <p className="text-xs text-gray-400">{opt.sub}</p>
                    </div>
                  </label>
                ))}
              </div>
            </div>
            <div>
              <label className="label">Facture (PDF, JPG, PNG — max 10 Mo)</label>
              {editCharge?.invoice_name && !form.invoice && (
                <p className="text-xs text-green-600 mb-1">📎 Fichier actuel : {editCharge.invoice_name}</p>
              )}
              <input className="input" type="file" accept=".pdf,.jpg,.jpeg,.png,.webp"
                onChange={e => setForm(f => ({ ...f, invoice: e.target.files[0] || null }))} />
            </div>
            <div className="flex gap-3 pt-2">
              <button type="button" onClick={() => setShowModal(false)} className="btn-secondary flex-1">Annuler</button>
              <button type="submit" disabled={loading} className="btn-primary flex-1">
                {loading ? '...' : editCharge ? 'Mettre à jour' : 'Ajouter'}
              </button>
            </div>
          </form>
        </Modal>
      )}

      {/* Bilan annuel Modal */}
      {showBilan && bilan && (
        <Modal title={`📊 Bilan annuel ${bilan.year} — ${bilan.property?.name}`} onClose={() => setShowBilan(false)}>
          <div className="space-y-6">
            <div className="flex justify-end gap-2 flex-wrap">
              <button onClick={printBilan}
                className="btn-secondary flex items-center gap-2 text-sm">
                🖨️ Aperçu / Imprimer
              </button>
            </div>
            {/* Summary cards */}
            <div className="grid grid-cols-2 gap-3">
              <div className="bg-red-50 border border-red-100 rounded-xl p-4 text-center">
                <p className="text-xs text-red-500 font-medium mb-1">Charges récupérables</p>
                <p className="text-2xl font-bold text-red-700">{fmt(bilan.total_charges_reelles)}</p>
                <p className="text-xs text-red-400 mt-1">{bilan.charges_count} facture{bilan.charges_count > 1 ? 's' : ''}</p>
              </div>
              <div className="bg-blue-50 border border-blue-100 rounded-xl p-4 text-center">
                <p className="text-xs text-blue-500 font-medium mb-1">Provisions perçues</p>
                <p className="text-2xl font-bold text-blue-700">{fmt(bilan.total_provisions_percues)}</p>
                <p className="text-xs text-blue-400 mt-1">de tous les locataires</p>
              </div>
            </div>

            {/* Charges déductibles (info) */}
            {bilan.total_deductible > 0 && (
              <div className="bg-purple-50 border border-purple-200 rounded-xl p-3 flex items-center justify-between text-sm">
                <span className="text-purple-700">💼 Charges déductibles des impôts (à votre charge)</span>
                <span className="font-semibold text-purple-800">{fmt(bilan.total_deductible)}</span>
              </div>
            )}

            {/* Charges non récupérables (info) */}
            {bilan.total_non_recoverable > 0 && (
              <div className="bg-gray-50 border border-gray-200 rounded-xl p-3 flex items-center justify-between text-sm">
                <span className="text-gray-500">✗ Sans affectation (à votre charge, non déductible)</span>
                <span className="font-semibold text-gray-700">{fmt(bilan.total_non_recoverable)}</span>
              </div>
            )}

            {/* Solde global */}
            {(() => {
              const solde = bilan.total_provisions_percues - bilan.total_charges_reelles
              const isPositive = solde >= 0
              return (
                <div className={`rounded-xl p-4 text-center border ${isPositive ? 'bg-green-50 border-green-200' : 'bg-orange-50 border-orange-200'}`}>
                  <p className={`text-sm font-medium ${isPositive ? 'text-green-600' : 'text-orange-600'}`}>
                    {isPositive ? '✅ Trop-perçu global (à restituer)' : '⚠️ Solde insuffisant (à appeler)'}
                  </p>
                  <p className={`text-3xl font-bold mt-1 ${isPositive ? 'text-green-700' : 'text-orange-700'}`}>
                    {isPositive ? '+' : ''}{fmt(solde)}
                  </p>
                </div>
              )
            })()}

            {/* Charges par catégorie */}
            {bilan.charges_by_category.length > 0 && (
              <div>
                <h3 className="text-sm font-semibold text-gray-700 mb-2">Répartition par catégorie</h3>
                <div className="space-y-1">
                  {bilan.charges_by_category.map(c => {
                    const cat = categories.find(x => x.value === c.category)
                    const pct = bilan.total_charges_reelles > 0 ? (c.total / bilan.total_charges_reelles * 100).toFixed(1) : 0
                    return (
                      <div key={c.category} className="flex items-center justify-between text-sm py-1">
                        <span className="text-gray-600">{cat ? `${cat.icon} ${cat.label}` : c.category}</span>
                        <div className="flex items-center gap-3">
                          <div className="w-24 bg-gray-100 rounded-full h-1.5">
                            <div className="bg-blue-500 h-1.5 rounded-full" style={{ width: `${pct}%` }}></div>
                          </div>
                          <span className="text-gray-500 w-8 text-right text-xs">{pct}%</span>
                          <span className="font-medium text-gray-900 w-20 text-right">{fmt(c.total)}</span>
                        </div>
                      </div>
                    )
                  })}
                </div>
              </div>
            )}

            {/* Par locataire */}
            {bilan.bilans.length > 0 ? (
              <div>
                <h3 className="text-sm font-semibold text-gray-700 mb-3">Décompte par locataire (prorata d'occupation)</h3>
                <div className="space-y-3">
                  {bilan.bilans.map(b => {
                    const isPos = b.trop_percu >= 0
                    return (
                      <div key={b.lease_id} className="border rounded-xl p-4">
                        <div className="flex items-start justify-between mb-3">
                          <div>
                            <p className="font-semibold text-gray-900">{b.tenant_name}</p>
                            {b.tenant_email && <p className="text-xs text-gray-400">{b.tenant_email}</p>}
                          </div>
                          <span className={`text-sm font-bold px-2 py-0.5 rounded-full ${isPos ? 'bg-green-100 text-green-700' : 'bg-orange-100 text-orange-700'}`}>
                            {isPos ? '↩ Remboursement' : '↑ Appel de fonds'}
                          </span>
                        </div>
                        <div className="mb-3 text-xs text-gray-500 bg-gray-50 rounded-lg px-3 py-2">
                          Occupation sur l'année: <span className="font-semibold text-gray-700">{b.occupied_days} / {b.year_days} jours ({Number(b.ratio_percent || 0).toFixed(2)}%)</span>
                        </div>
                        <div className="grid grid-cols-3 gap-2 text-sm">
                          <div className="bg-gray-50 rounded-lg p-2 text-center">
                            <p className="text-xs text-gray-500">Provisions perçues</p>
                            <p className="font-semibold text-gray-800">{fmt(b.provisions_percues)}</p>
                          </div>
                          <div className="bg-gray-50 rounded-lg p-2 text-center">
                            <p className="text-xs text-gray-500">Quote-part réelle (prorata)</p>
                            <p className="font-semibold text-gray-800">{fmt(b.quote_part_charges)}</p>
                          </div>
                          <div className={`rounded-lg p-2 text-center ${isPos ? 'bg-green-50' : 'bg-orange-50'}`}>
                            <p className={`text-xs font-medium ${isPos ? 'text-green-600' : 'text-orange-600'}`}>
                              {isPos ? 'Trop-perçu' : 'Solde dû'}
                            </p>
                            <p className={`font-bold text-lg ${isPos ? 'text-green-700' : 'text-orange-700'}`}>
                              {fmt(Math.abs(b.trop_percu))}
                            </p>
                          </div>
                        </div>
                        <div className="mt-3 flex items-center justify-between gap-2 flex-wrap">
                          <button
                            onClick={() => downloadPdfLease(b)}
                            disabled={pdfLoadingLeaseId === b.lease_id}
                            className="flex items-center gap-2 text-sm px-3 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-semibold transition-colors disabled:opacity-60"
                          >
                            {pdfLoadingLeaseId === b.lease_id ? '⏳ Génération…' : '📥 Décompte PDF'}
                          </button>
                          <div className="flex items-center gap-2 flex-wrap justify-end">
                            {b.closed ? (
                              <>
                                <span className="text-xs text-green-700 bg-green-50 border border-green-200 px-2 py-1 rounded-lg font-medium">✅ Bilan clôturé</span>
                                <button
                                  onClick={() => cancelLeaseExercise(b)}
                                  disabled={cancelingLeaseId === b.lease_id}
                                  className="flex items-center gap-2 text-sm px-3 py-2 rounded-lg bg-red-500 hover:bg-red-600 text-white font-semibold transition-colors disabled:opacity-60"
                                >
                                  {cancelingLeaseId === b.lease_id ? '⏳ Annulation…' : '↩ Annuler la clôture'}
                                </button>
                              </>
                            ) : (
                              <button
                                onClick={() => closeLeaseExercise(b)}
                                disabled={closingLeaseId === b.lease_id}
                                className="flex items-center gap-2 text-sm px-3 py-2 rounded-lg bg-orange-500 hover:bg-orange-600 text-white font-semibold transition-colors disabled:opacity-60"
                              >
                                {closingLeaseId === b.lease_id ? '⏳ Clôture du bilan…' : '✅ Clôturer le bilan annuel'}
                              </button>
                            )}
                          </div>
                        </div>
                      </div>
                    )
                  })}
                </div>
              </div>
            ) : (
              <p className="text-center text-gray-400 text-sm py-4">Aucun locataire trouvé pour cette période.</p>
            )}
          </div>
        </Modal>
      )}
    </div>
  )
}
