import { useEffect, useState, useRef, useCallback } from 'react'
import { useNavigate } from '@tanstack/react-router'
import {
  Upload, Search, Plus, Building2, FolderX, GitBranch,
  Clock, TrendingUp, BarChart2, FileX2, X, Settings,
  MoreVertical, Trash2, Share2, Lock, User,
} from 'lucide-react'
import { useLibraryStore } from '@/store/library-store'
import { useAuth } from '@/auth/AuthContext'
import { supabaseProcessRepo } from '@/persistence/supabase/process-repo'
import { formatCurrency } from '@/lib/format'
import type { Process, ProcessGroup, Simulation } from '@/domain/types'
import { AppHeader } from '@/components/AppHeader'

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

function relativeDate(ts: number): string {
  const days = Math.floor((Date.now() - ts) / 86_400_000)
  if (days === 0) return 'hoy'
  if (days === 1) return 'hace 1 día'
  return `hace ${days} días`
}

function tagCloudData(processes: Process[]): Array<{ tag: string; count: number; fontSize: string }> {
  const freq = new Map<string, number>()
  processes.forEach((p) => p.tags.forEach((t) => freq.set(t, (freq.get(t) ?? 0) + 1)))
  const sorted = [...freq.entries()].sort((a, b) => b[1] - a[1]).slice(0, 12)
  if (sorted.length === 0) return []
  const maxCount = sorted[0][1]
  const minCount = sorted[sorted.length - 1][1]
  const range = maxCount - minCount || 1
  return sorted.map(([tag, count]) => {
    const t = (count - minCount) / range
    return { tag, count, fontSize: `${Math.round(10 + t * 3)}px` }
  })
}

function matchesSearch(p: Process, q: string): boolean {
  const lower = q.toLowerCase()
  return p.name.toLowerCase().includes(lower) || p.tags.some((t) => t.includes(lower))
}

function matchesTags(p: Process, activeTags: string[]): boolean {
  return activeTags.every((t) => p.tags.includes(t))
}

// ─── Ownership Badge ──────────────────────────────────────────────────────────

function OwnershipBadge({ process, currentUserId }: { process: Process; currentUserId: string }) {
  const isOwn = process.ownerId === currentUserId
  return (
    <div
      className="flex-shrink-0 flex items-center"
      title={isOwn ? 'Solo vos' : 'De otro consultor'}
    >
      {isOwn
        ? <Lock className="h-3 w-3 text-muted-foreground/60" />
        : <User className="h-3 w-3 text-muted-foreground/60" />
      }
    </div>
  )
}

// ─── Toast ────────────────────────────────────────────────────────────────────

function useToast() {
  const [message, setMessage] = useState<string | null>(null)

  function show(msg: string) {
    setMessage(msg)
    setTimeout(() => setMessage(null), 2800)
  }

  return { message, show }
}

function Toast({ message }: { message: string | null }) {
  if (!message) return null
  return (
    <div
      className="fixed bottom-6 left-1/2 -translate-x-1/2 z-50 px-4 py-2.5 rounded-lg text-[13px] font-medium text-white shadow-lg transition-all"
      style={{ background: '#15803d' }}
    >
      {message}
    </div>
  )
}

// ─── KPI Badge ────────────────────────────────────────────────────────────────

function KpiBadge({ process, simulation }: { process: Process; simulation: Simulation | null | undefined }) {
  if (simulation === undefined) return null // cargando

  if (!simulation) {
    return <span className="text-[11px] italic text-muted-foreground">Sin simular</span>
  }

  if (simulation.resultAutomated) {
    const ahorro = (simulation.result.totalCost - simulation.resultAutomated.totalCost) * process.annualFrequency
    return (
      <div className="text-right">
        <div className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium"
          style={{ background: '#f0fdf4', border: '1px solid #86efac', color: '#15803d' }}>
          <TrendingUp className="h-3 w-3" />
          {formatCurrency(ahorro, process.currency)}
        </div>
        <p className="text-[10px] text-muted-foreground mt-0.5">Ahorro anual proyectado</p>
      </div>
    )
  }

  const costoAnual = simulation.result.totalCost * process.annualFrequency
  return (
    <div className="text-right">
      <div className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium border border-border bg-secondary text-secondary-foreground">
        <BarChart2 className="h-3 w-3" />
        {formatCurrency(costoAnual, process.currency)}
      </div>
      <p className="text-[10px] text-muted-foreground mt-0.5">Costo anual actual</p>
    </div>
  )
}

// ─── Process Card ─────────────────────────────────────────────────────────────

function ProcessCard({ process, simulation, showGroupChip, groupName, onDelete, currentUserId, onShared }: {
  process: Process
  simulation: Simulation | null | undefined
  showGroupChip?: boolean
  groupName?: string
  onDelete?: () => void
  currentUserId: string
  onShared?: () => void
}) {
  const navigate = useNavigate()
  const [menuState, setMenuState] = useState<null | 'menu' | 'confirm'>(null)
  const isOwn = process.ownerId === currentUserId

  // Cierra el menú al hacer click fuera de él
  useEffect(() => {
    if (!menuState) return
    function handleDocClick() { setMenuState(null) }
    document.addEventListener('click', handleDocClick)
    return () => document.removeEventListener('click', handleDocClick)
  }, [menuState])

  return (
    <div
      className="flex items-center gap-3 px-4 py-3 rounded-xl border border-border bg-card hover:border-border/80 hover:shadow-sm transition-all cursor-pointer group"
      onClick={() => {
        if (menuState) { setMenuState(null); return }
        navigate({ to: '/workspace/$processId', params: { processId: process.id } })
      }}
    >
      {/* Ícono */}
      <div className="flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center"
        style={{ background: '#fff3e6' }}>
        <GitBranch className="h-4 w-4" style={{ color: '#F59845' }} />
      </div>

      {/* Info central */}
      <div className="flex-1 min-w-0">
        <div className="flex items-center gap-1.5">
          <p className="text-[13px] font-medium truncate">{process.name || 'Sin nombre'}</p>
          <OwnershipBadge process={process} currentUserId={currentUserId} />
        </div>
        <div className="flex items-center gap-1 mt-0.5">
          <Clock className="h-3 w-3 text-muted-foreground" />
          <span className="text-[11px] text-muted-foreground">Modificado {relativeDate(process.updatedAt)}</span>
        </div>
        {(process.tags.length > 0 || showGroupChip) && (
          <div className="flex flex-wrap gap-1 mt-1">
            {showGroupChip && groupName && (
              <span className="text-[10px] px-2 py-0.5 rounded-full border"
                style={{ background: '#fff3e6', borderColor: '#F59845', color: '#7a3e00' }}>
                {groupName}
              </span>
            )}
            {process.tags.map((tag) => (
              <span key={tag} className="text-[10px] px-2 py-0.5 rounded-full bg-secondary border border-border text-secondary-foreground">
                {tag}
              </span>
            ))}
          </div>
        )}
      </div>

      {/* KPI derecha */}
      <div className="flex-shrink-0 min-w-[90px]">
        <KpiBadge process={process} simulation={simulation} />
      </div>

      {/* Menú de opciones (⋮) — en el flujo flex, a la derecha del KPI */}
      {onDelete && (
        <div
          className="relative flex-shrink-0"
          onClick={(e) => e.stopPropagation()}
        >
          <button
            className={`p-1 rounded hover:bg-secondary text-muted-foreground hover:text-foreground transition-all ${menuState === null ? 'opacity-0 group-hover:opacity-100' : 'opacity-100'}`}
            onClick={(e) => { e.stopPropagation(); setMenuState(menuState === 'menu' ? null : 'menu') }}
            title="Opciones"
          >
            <MoreVertical className="h-3.5 w-3.5" />
          </button>
          {menuState === 'menu' && (
            <div
              className="absolute right-0 top-7 z-20 bg-card border border-border rounded-lg shadow-lg py-1 min-w-[160px]"
              onClick={(e) => e.stopPropagation()}
            >
              {isOwn && (
                <button
                  className="flex items-center gap-2 w-full px-3 py-1.5 text-[12px] text-foreground hover:bg-secondary transition-colors"
                  onClick={async (e) => {
                    e.stopPropagation()
                    await supabaseProcessRepo.setShared(process.id, true)
                    setMenuState(null)
                    onShared?.()
                  }}
                >
                  <Share2 className="h-3.5 w-3.5" />
                  Compartir con equipo
                </button>
              )}
              <button
                className="flex items-center gap-2 w-full px-3 py-1.5 text-[12px] text-destructive hover:bg-destructive/10 transition-colors"
                onClick={(e) => { e.stopPropagation(); setMenuState('confirm') }}
              >
                <Trash2 className="h-3.5 w-3.5" />
                Eliminar
              </button>
            </div>
          )}
          {menuState === 'confirm' && (
            <div
              className="absolute right-0 top-6 z-20 bg-card border border-border rounded-lg shadow-lg p-3 min-w-[170px]"
              onClick={(e) => e.stopPropagation()}
            >
              <p className="text-[12px] font-medium mb-2 text-foreground">¿Eliminar proceso?</p>
              <p className="text-[11px] text-muted-foreground mb-3">Esta acción no se puede deshacer.</p>
              <div className="flex gap-1.5">
                <button
                  className="flex-1 text-[11px] px-2 py-1 rounded font-medium text-white transition-opacity hover:opacity-90"
                  style={{ background: '#ef4444' }}
                  onClick={(e) => { e.stopPropagation(); onDelete(); setMenuState(null) }}
                >
                  Eliminar
                </button>
                <button
                  className="flex-1 text-[11px] px-2 py-1 rounded border border-border text-muted-foreground hover:bg-secondary transition-colors"
                  onClick={(e) => { e.stopPropagation(); setMenuState(null) }}
                >
                  Cancelar
                </button>
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  )
}

// ─── Group Card ───────────────────────────────────────────────────────────────

function GroupCard({ group, processCount, lastUpdated, onClick }: {
  group: ProcessGroup
  processCount: number
  lastUpdated: number | null
  onClick: () => void
}) {
  return (
    <button
      className="text-left w-full rounded-xl p-3 transition-all"
      style={{
        background: 'hsl(var(--card))',
        border: '0.5px solid hsl(var(--border))',
        borderLeft: '3px solid #F59845',
        borderRadius: '0.5rem',
      }}
      onMouseEnter={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = 'hsl(var(--border) / 0.8)'; (e.currentTarget as HTMLButtonElement).style.borderLeftColor = '#F59845' }}
      onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = 'hsl(var(--border))'; (e.currentTarget as HTMLButtonElement).style.borderLeftColor = '#F59845' }}
      onClick={onClick}
    >
      <p className="text-2xl font-medium" style={{ color: '#F59845' }}>{processCount}</p>
      <p className="text-[13px] font-medium truncate mt-0.5">{group.name}</p>
      {lastUpdated && (
        <p className="text-[11px] text-muted-foreground mt-1">
          Actualizado {relativeDate(lastUpdated)}
        </p>
      )}
    </button>
  )
}

// ─── New Group Card ───────────────────────────────────────────────────────────

function NewGroupCard({ label, onCreate }: { label: string; onCreate: (name: string) => void }) {
  const [editing, setEditing] = useState(false)
  const [value, setValue] = useState('')
  const inputRef = useRef<HTMLInputElement>(null)

  const confirm = useCallback(() => {
    const trimmed = value.trim()
    if (trimmed) onCreate(trimmed)
    setValue('')
    setEditing(false)
  }, [value, onCreate])

  const cancel = useCallback(() => {
    setValue('')
    setEditing(false)
  }, [])

  useEffect(() => {
    if (editing) inputRef.current?.focus()
  }, [editing])

  if (editing) {
    return (
      <div className="rounded-xl p-3 transition-all"
        style={{ border: '1.5px solid #F59845', background: 'hsl(var(--card))', borderRadius: '0.5rem' }}>
        <input
          ref={inputRef}
          value={value}
          onChange={(e) => setValue(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === 'Enter') confirm()
            if (e.key === 'Escape') cancel()
          }}
          placeholder={`Nombre del ${label.toLowerCase()}...`}
          className="w-full text-[12px] bg-transparent border-none outline-none placeholder:text-muted-foreground"
        />
        <div className="flex gap-1.5 mt-2">
          <button
            onClick={confirm}
            className="text-[11px] px-2 py-0.5 rounded font-medium text-white"
            style={{ background: '#F59845' }}
          >
            Crear
          </button>
          <button
            onClick={cancel}
            className="text-[11px] px-2 py-0.5 rounded font-medium text-muted-foreground border border-border"
          >
            Cancelar
          </button>
        </div>
      </div>
    )
  }

  return (
    <button
      className="text-left w-full rounded-xl p-3 flex flex-col items-center justify-center gap-1.5 transition-all group"
      style={{ border: '0.5px dashed hsl(var(--border))', background: 'hsl(var(--card))', borderRadius: '0.5rem', minHeight: '80px' }}
      onMouseEnter={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = '#F59845'; (e.currentTarget as HTMLButtonElement).style.color = '#F59845' }}
      onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = 'hsl(var(--border))'; (e.currentTarget as HTMLButtonElement).style.color = '' }}
      onClick={() => setEditing(true)}
    >
      <Plus className="h-4 w-4 text-muted-foreground group-hover:text-[#F59845] transition-colors" />
      <span className="text-[12px] text-muted-foreground group-hover:text-[#F59845] transition-colors">
        Nuevo {label.toLowerCase()}
      </span>
    </button>
  )
}

// ─── Home View ────────────────────────────────────────────────────────────────

function HomeView({
  onNavigateToGroup,
  onImport,
  ownerFilter,
  currentUserId,
  onShared,
}: {
  onNavigateToGroup: (groupId: string | null) => void
  onImport: (groupId?: string) => void
  ownerFilter: 'all' | 'mine'
  currentUserId: string
  onShared: () => void
}) {
  const { groups, processes, settings, createGroup, isLoading } = useLibraryStore()
  const { user } = useAuth()
  const [search, setSearch] = useState('')
  const [activeTags, setActiveTags] = useState<string[]>([])

  const visibleProcesses = ownerFilter === 'mine'
    ? processes.filter((p) => p.ownerId === currentUserId)
    : processes

  const cloud = tagCloudData(visibleProcesses)
  const unclassifiedProcesses = visibleProcesses.filter((p) => p.groupId == null)

  const isSearching = search.trim().length > 0 || activeTags.length > 0

  const filteredProcesses = isSearching
    ? visibleProcesses.filter((p) => matchesSearch(p, search) && matchesTags(p, activeTags))
    : []

  function toggleTag(tag: string) {
    setActiveTags((prev) => prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag])
  }

  // Skeleton mientras carga y aún no hay datos (evita flash de empty state)
  if (isLoading && groups.length === 0 && processes.length === 0) {
    return (
      <div className="space-y-5 animate-pulse">
        <div className="h-4 w-32 bg-slate-100 rounded" />
        <div className="grid gap-2.5" style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))' }}>
          {[1, 2, 3].map((i) => (
            <div key={i} className="h-20 rounded-xl bg-slate-100" />
          ))}
        </div>
        <div className="space-y-2">
          {[1, 2].map((i) => (
            <div key={i} className="h-14 rounded-xl bg-slate-100" />
          ))}
        </div>
      </div>
    )
  }

  // Empty state: sin grupos ni procesos (ya terminó de cargar)
  if (groups.length === 0 && processes.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center py-24 gap-4">
        <Building2 className="h-16 w-16 text-muted-foreground/30" />
        <p className="text-base font-medium">Tu biblioteca está vacía</p>
        <p className="text-[13px] text-muted-foreground">Importá tu primer BPMN para empezar</p>
        <button
          onClick={() => onImport()}
          className="flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium text-white transition-opacity hover:opacity-90"
          style={{ background: '#F59845' }}
        >
          <Upload className="h-4 w-4" />
          Importar BPMN
        </button>
      </div>
    )
  }

  return (
    <div className="space-y-5">
      {/* Búsqueda */}
      <div className="relative">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
        <input
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          placeholder="Buscar proceso por nombre..."
          className="w-full pl-9 pr-4 py-2 text-sm rounded-lg border border-border bg-background focus:outline-none focus:ring-1 focus:ring-primary"
        />
      </div>

      {/* Resultados de búsqueda */}
      {isSearching && (
        <div className="space-y-2">
          {/* Filtros activos */}
          {activeTags.length > 0 && (
            <div className="flex items-center gap-1.5 flex-wrap">
              <span className="text-[11px] text-muted-foreground">Filtros activos:</span>
              {activeTags.map((tag) => (
                <button
                  key={tag}
                  onClick={() => toggleTag(tag)}
                  className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full border"
                  style={{ background: '#fff3e6', borderColor: '#F59845', color: '#7a3e00' }}
                >
                  {tag} <X className="h-2.5 w-2.5" />
                </button>
              ))}
              <button
                onClick={() => setActiveTags([])}
                className="text-[11px] text-muted-foreground hover:text-foreground"
              >
                Limpiar todo
              </button>
            </div>
          )}
          <p className="text-[11px] text-muted-foreground uppercase tracking-wide font-medium">
            {filteredProcesses.length} resultado{filteredProcesses.length !== 1 ? 's' : ''}
          </p>
          {filteredProcesses.length === 0 && (
            <p className="text-[13px] text-muted-foreground py-4 text-center">Sin resultados para esa búsqueda.</p>
          )}
          {filteredProcesses.map((p) => {
            const group = groups.find((g) => g.id === p.groupId)
            return (
              <ProcessCardWithSim
                key={p.id}
                process={p}
                showGroupChip
                groupName={group?.name}
                currentUserId={currentUserId}
                onShared={onShared}
              />
            )
          })}
        </div>
      )}

      {/* Vista normal — grupos */}
      {!isSearching && (
        <>
          {/* Tag cloud (wow): visible cuando hay >= 3 tags distintos */}
          {cloud.length >= 3 && (
            <div className="flex flex-wrap items-center gap-2">
              <span className="text-[11px] text-muted-foreground shrink-0">Tags:</span>
              {cloud.map(({ tag, fontSize }) => (
                <button
                  key={tag}
                  onClick={() => toggleTag(tag)}
                  className="px-2 py-0.5 rounded-full border transition-all hover:border-[#F59845] hover:bg-[#fff3e6] hover:text-[#7a3e00]"
                  style={{ fontSize, background: 'white', borderColor: 'hsl(var(--border))' }}
                >
                  {tag}
                </button>
              ))}
            </div>
          )}
          {/* Tags simples cuando hay 1-2 */}
          {cloud.length > 0 && cloud.length < 3 && (
            <div className="flex items-center gap-2 flex-wrap">
              <span className="text-[12px] text-muted-foreground">Tags:</span>
              {cloud.map(({ tag }) => (
                <button
                  key={tag}
                  onClick={() => toggleTag(tag)}
                  className="text-[11px] px-2.5 py-0.5 rounded-full border transition-all"
                  style={{ background: 'white', borderColor: 'hsl(var(--border))' }}
                >
                  {tag}
                </button>
              ))}
            </div>
          )}

          {/* Header sección grupos */}
          <div className="flex items-center gap-2">
            <span className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
              {settings.groupLabel}s
            </span>
            <span className="text-[10px] bg-secondary px-1.5 py-0.5 rounded text-muted-foreground">
              {groups.length}
            </span>
          </div>

          {/* Grid de grupos */}
          <div className="grid gap-2.5" style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))' }}>
            {groups.map((group) => {
              const groupProcesses = visibleProcesses.filter((p) => p.groupId === group.id)
              const lastUpdated = groupProcesses.length > 0
                ? Math.max(...groupProcesses.map((p) => p.updatedAt))
                : null
              return (
                <GroupCard
                  key={group.id}
                  group={group}
                  processCount={groupProcesses.length}
                  lastUpdated={lastUpdated}
                  onClick={() => onNavigateToGroup(group.id)}
                />
              )
            })}
            <NewGroupCard
              label={settings.groupLabel}
              onCreate={(name) => createGroup(name, user!.id)}
            />
          </div>

          {/* Sin clasificar */}
          {unclassifiedProcesses.length > 0 && (
            <button
              className="w-full flex items-center gap-3 px-4 py-3 rounded-xl text-left transition-all hover:border-border/80"
              style={{ border: '0.5px dashed hsl(var(--border))', background: 'hsl(var(--card))', borderRadius: '0.5rem' }}
              onClick={() => onNavigateToGroup(null)}
            >
              <FolderX className="h-4 w-4 text-muted-foreground flex-shrink-0" />
              <div className="flex-1 min-w-0">
                <span className="text-[13px] font-medium text-secondary-foreground">
                  Procesos sin {settings.groupLabel.toLowerCase()} asignado
                </span>
              </div>
              <span className="text-[11px] text-muted-foreground flex-shrink-0">
                {unclassifiedProcesses.length} proceso{unclassifiedProcesses.length !== 1 ? 's' : ''}
              </span>
            </button>
          )}
        </>
      )}
    </div>
  )
}

// ─── ProcessCardWithSim (carga simulación lazy) ───────────────────────────────

function ProcessCardWithSim({ process, showGroupChip, groupName, currentUserId, onShared }: {
  process: Process
  showGroupChip?: boolean
  groupName?: string
  currentUserId: string
  onShared: () => void
}) {
  const { getLatestSimulation, deleteProcess } = useLibraryStore()
  const [simulation, setSimulation] = useState<Simulation | null | undefined>(undefined)

  useEffect(() => {
    let cancelled = false
    getLatestSimulation(process.id).then((sim) => {
      if (!cancelled) setSimulation(sim ?? null)
    })
    return () => { cancelled = true }
  }, [process.id, getLatestSimulation])

  return (
    <ProcessCard
      process={process}
      simulation={simulation}
      showGroupChip={showGroupChip}
      groupName={groupName}
      onDelete={() => deleteProcess(process.id)}
      currentUserId={currentUserId}
      onShared={onShared}
    />
  )
}

// ─── Group View ───────────────────────────────────────────────────────────────

function GroupView({
  groupId,
  onBack,
  currentUserId,
  ownerFilter,
  onShared,
}: {
  groupId: string | null
  onBack: () => void
  currentUserId: string
  ownerFilter: 'all' | 'mine'
  onShared: () => void
}) {
  const { groups, processes, settings } = useLibraryStore()
  const [search, setSearch] = useState('')

  const group = groupId ? groups.find((g) => g.id === groupId) : null
  const groupName = group?.name ?? `Procesos sin ${settings.groupLabel.toLowerCase()}`

  const baseProcesses = ownerFilter === 'mine'
    ? processes.filter((p) => p.ownerId === currentUserId)
    : processes

  const groupProcesses = baseProcesses
    .filter((p) => groupId === null ? p.groupId == null : p.groupId === groupId)
    .filter((p) => matchesSearch(p, search))

  return (
    <div className="space-y-5">
      {/* Breadcrumb */}
      <div className="flex items-center gap-2">
        <button
          onClick={onBack}
          className="text-[13px] font-medium hover:opacity-80 transition-opacity"
          style={{ color: '#F59845' }}
        >
          ← Biblioteca
        </button>
        <span className="text-muted-foreground text-[13px]">/</span>
        <span className="text-[13px] font-medium">{groupName}</span>
      </div>
      <p className="text-[12px] text-muted-foreground -mt-3">
        {groupProcesses.length} proceso{groupProcesses.length !== 1 ? 's' : ''}
      </p>

      {/* Búsqueda */}
      <div className="relative">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
        <input
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          placeholder={`Buscar en este ${settings.groupLabel.toLowerCase()}...`}
          className="w-full pl-9 pr-4 py-2 text-sm rounded-lg border border-border bg-background focus:outline-none focus:ring-1 focus:ring-primary"
        />
      </div>

      {/* Empty state */}
      {groupProcesses.length === 0 && !search && (
        <div className="flex flex-col items-center justify-center py-16 gap-3">
          <FileX2 className="h-12 w-12 text-muted-foreground/30" />
          <p className="text-[13px] font-medium text-secondary-foreground">
            No hay procesos en este {settings.groupLabel.toLowerCase()}.
          </p>
          <p className="text-[13px] text-muted-foreground">Importá un BPMN para comenzar.</p>
        </div>
      )}

      {/* Lista de procesos */}
      <div className="space-y-2">
        {groupProcesses.map((p) => (
          <ProcessCardWithSim
            key={p.id}
            process={p}
            currentUserId={currentUserId}
            onShared={onShared}
          />
        ))}
      </div>
    </div>
  )
}

// ─── LibraryPage ──────────────────────────────────────────────────────────────

export function LibraryPage() {
  const navigate = useNavigate()
  const { load, processes, groups, settings } = useLibraryStore()
  const { user } = useAuth()
  const [view, setView] = useState<'home' | 'group'>('home')
  const [activeGroupId, setActiveGroupId] = useState<string | null>(null)
  const [transitioning, setTransitioning] = useState(false)
  const [ownerFilter, setOwnerFilter] = useState<'all' | 'mine'>('all')
  const { message: toastMessage, show: showToast } = useToast()

  useEffect(() => {
    if (!user) return // no fetchear hasta tener usuario confirmado (evita race condition con sesión Supabase)
    load()
  }, [load, user])

  function navigateToGroup(groupId: string | null) {
    setTransitioning(true)
    setTimeout(() => {
      setActiveGroupId(groupId)
      setView('group')
      setTransitioning(false)
    }, 150)
  }

  function navigateHome() {
    setTransitioning(true)
    setTimeout(() => {
      setView('home')
      setActiveGroupId(null)
      setTransitioning(false)
    }, 150)
  }

  function handleImport(groupId?: string) {
    if (groupId) {
      navigate({ to: '/import', search: { groupId } })
    } else {
      navigate({ to: '/import' })
    }
  }

  const currentUserId = user!.id
  const totalGroups = groups.length

  return (
    <div className="min-h-screen bg-background">
      <AppHeader />
      <div className="max-w-4xl mx-auto px-6 py-8">
        {/* Header */}
        <div className="flex items-start justify-between mb-6">
          <div>
            <h1 className="text-[18px] font-medium">Biblioteca de procesos</h1>
            <p className="text-[12px] text-muted-foreground mt-0.5">
              {processes.length} proceso{processes.length !== 1 ? 's' : ''} · {totalGroups} {settings.groupLabel.toLowerCase()}{totalGroups !== 1 ? 's' : ''}
            </p>
          </div>
          <div className="flex items-center gap-2">
            {/* Toggle Todos / Míos */}
            <div className="flex rounded-lg border border-border overflow-hidden text-[12px]">
              <button
                className="px-3 py-1.5 font-medium transition-colors"
                style={ownerFilter === 'all'
                  ? { background: '#F59845', color: 'white' }
                  : { background: 'transparent', color: 'hsl(var(--muted-foreground))' }
                }
                onClick={() => setOwnerFilter('all')}
              >
                Todos
              </button>
              <button
                className="px-3 py-1.5 font-medium transition-colors border-l border-border"
                style={ownerFilter === 'mine'
                  ? { background: '#F59845', color: 'white' }
                  : { background: 'transparent', color: 'hsl(var(--muted-foreground))' }
                }
                onClick={() => setOwnerFilter('mine')}
              >
                Míos
              </button>
            </div>

            <button
              onClick={() => navigate({ to: '/settings' })}
              className="p-2 rounded-lg text-muted-foreground hover:text-foreground hover:bg-secondary transition-colors"
              title="Configuración"
            >
              <Settings className="h-4 w-4" />
            </button>
            <button
              onClick={() => handleImport(view === 'group' && activeGroupId ? activeGroupId : undefined)}
              className="flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium text-white transition-opacity hover:opacity-90"
              style={{ background: '#F59845' }}
            >
              <Upload className="h-4 w-4" />
              Importar BPMN
            </button>
          </div>
        </div>

        {/* Contenido — sin spinner bloqueante: skeleton dentro de HomeView */}
        <div
          className="transition-all duration-150"
          style={{ opacity: transitioning ? 0 : 1, transform: transitioning ? 'translateY(6px)' : 'translateY(0)' }}
        >
          {view === 'home' ? (
            <HomeView
              onNavigateToGroup={navigateToGroup}
              onImport={handleImport}
              ownerFilter={ownerFilter}
              currentUserId={currentUserId}
              onShared={() => showToast('Proceso compartido con el equipo')}
            />
          ) : (
            <GroupView
              groupId={activeGroupId}
              onBack={navigateHome}
              currentUserId={currentUserId}
              ownerFilter={ownerFilter}
              onShared={() => showToast('Proceso compartido con el equipo')}
            />
          )}
        </div>
      </div>

      <Toast message={toastMessage} />
    </div>
  )
}
