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,
} from 'lucide-react'
import { useLibraryStore } from '@/store/library-store'
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))
}

// ─── 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 }: {
  process: Process
  simulation: Simulation | null | undefined
  showGroupChip?: boolean
  groupName?: string
}) {
  const navigate = useNavigate()

  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"
      onClick={() => 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">
        <p className="text-[13px] font-medium truncate">{process.name || 'Sin nombre'}</p>
        <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>
    </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,
}: {
  onNavigateToGroup: (groupId: string | null) => void
  onImport: (groupId?: string) => void
}) {
  const { groups, processes, settings, createGroup } = useLibraryStore()
  const [search, setSearch] = useState('')
  const [activeTags, setActiveTags] = useState<string[]>([])

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

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

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

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

  // Empty state: sin grupos ni procesos
  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}
              />
            )
          })}
        </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 = processes.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)}
            />
          </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 }: {
  process: Process
  showGroupChip?: boolean
  groupName?: string
}) {
  const { getLatestSimulation } = 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} />
}

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

function GroupView({
  groupId,
  onBack,
}: {
  groupId: string | null
  onBack: () => 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 groupProcesses = processes
    .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} />
        ))}
      </div>
    </div>
  )
}

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

export function LibraryPage() {
  const navigate = useNavigate()
  const { load, isLoading, processes, groups, settings } = useLibraryStore()
  const [view, setView] = useState<'home' | 'group'>('home')
  const [activeGroupId, setActiveGroupId] = useState<string | null>(null)
  const [transitioning, setTransitioning] = useState(false)

  useEffect(() => {
    load()
  }, [load])

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

  // Preflight fix: contar grupos reales en lugar del clientName heredado
  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">
            <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 con transición */}
        {isLoading ? (
          <div className="flex items-center justify-center py-24">
            <div className="h-6 w-6 rounded-full border-2 border-primary border-t-transparent animate-spin" />
          </div>
        ) : (
          <div
            className="transition-all duration-150"
            style={{ opacity: transitioning ? 0 : 1, transform: transitioning ? 'translateY(6px)' : 'translateY(0)' }}
          >
            {view === 'home' ? (
              <HomeView
                onNavigateToGroup={navigateToGroup}
                onImport={handleImport}
              />
            ) : (
              <GroupView
                groupId={activeGroupId}
                onBack={navigateHome}
              />
            )}
          </div>
        )}
      </div>
    </div>
  )
}
