/**
 * Página Paperclip — Painel de agentes, routines e issues
 * @author Descomplicar® | @link descomplicar.pt | @copyright 2026
 */
import { useState, useEffect, useCallback } from 'react'
import { motion } from 'framer-motion'
import {
  Bot,
  Users,
  Calendar,
  CheckCircle2,
  AlertTriangle,
  Clock,
  RefreshCw,
  Activity,
  Zap,
} from 'lucide-react'

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface PaperclipAgent {
  id: string
  name: string
  role: string
  status: 'active' | 'idle' | 'error' | 'archived'
  last_heartbeat: string | null
  last_run: string | null
  total_runs: number
}

interface PaperclipRoutine {
  id: string
  name: string
  cron: string
  active: boolean
  last_run: string | null
  last_status: 'success' | 'error' | null
  next_run: string | null
}

interface PaperclipDashboard {
  agents: {
    total: number
    active: number
    idle: number
    error: number
    list: PaperclipAgent[]
  }
  routines: {
    total: number
    active: number
    list: PaperclipRoutine[]
  }
  issues: {
    open: number
    in_progress: number
    closed_7d: number
  }
}

// ---------------------------------------------------------------------------
// Animation variants (consistente com Monitor.tsx)
// ---------------------------------------------------------------------------

const containerVariants = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: { staggerChildren: 0.06 },
  },
}

const itemVariants = {
  hidden: { opacity: 0, y: 20 },
  show: {
    opacity: 1,
    y: 0,
    transition: { type: 'spring' as const, stiffness: 300, damping: 30 },
  },
}

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

/**
 * Ordem de prioridade de roles para agrupamento hierárquico.
 * Roles desconhecidos ficam no fim.
 */
const ROLE_ORDER: Record<string, number> = {
  Board: 0,
  CEO: 1,
  'C-Level': 2,
  COO: 2,
  CTO: 2,
  CFO: 2,
  CMO: 2,
  Director: 3,
  Specialist: 4,
}

function roleOrder(role: string): number {
  return ROLE_ORDER[role] ?? 99
}

/** Agrupa a lista de agentes por role, ordenando roles hierarchicamente. */
function groupAgentsByRole(agents: PaperclipAgent[]): Record<string, PaperclipAgent[]> {
  const groups: Record<string, PaperclipAgent[]> = {}
  for (const agent of agents) {
    if (!groups[agent.role]) groups[agent.role] = []
    groups[agent.role].push(agent)
  }
  return groups
}

/** Ordena as keys de um objecto de grupos pelo ranking hierárquico. */
function sortedRoleKeys(groups: Record<string, PaperclipAgent[]>): string[] {
  return Object.keys(groups).sort((a, b) => roleOrder(a) - roleOrder(b))
}

/** Formata uma string ISO ou null para data/hora legível PT. */
function formatDate(iso: string | null): string {
  if (!iso) return '—'
  try {
    return new Date(iso).toLocaleString('pt-PT', {
      day: '2-digit',
      month: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
    })
  } catch {
    return iso
  }
}

// ---------------------------------------------------------------------------
// Sub-components
// ---------------------------------------------------------------------------

/** Dot colorido de estado (verde/amarelo/vermelho). */
const StatusDot = ({ status }: { status: string }) => {
  const colour =
    status === 'active'
      ? 'bg-emerald-400 shadow-[0_0_10px_rgba(16,185,129,0.5)]'
      : status === 'idle'
      ? 'bg-amber-400 shadow-[0_0_10px_rgba(245,158,11,0.5)]'
      : status === 'error'
      ? 'bg-red-400 shadow-[0_0_10px_rgba(239,68,68,0.5)] animate-pulse'
      : 'bg-zinc-600'
  return <span className={`inline-block w-2 h-2 rounded-full ${colour}`} />
}

/** Badge de role do agente. */
const RoleBadge = ({ role }: { role: string }) => {
  const styles: Record<string, string> = {
    Board: 'bg-violet-500/20 text-violet-300 border border-violet-500/30',
    CEO: 'bg-cyan-500/20 text-cyan-300 border border-cyan-500/30',
    'C-Level': 'bg-blue-500/20 text-blue-300 border border-blue-500/30',
    COO: 'bg-blue-500/20 text-blue-300 border border-blue-500/30',
    CTO: 'bg-blue-500/20 text-blue-300 border border-blue-500/30',
    CFO: 'bg-blue-500/20 text-blue-300 border border-blue-500/30',
    CMO: 'bg-blue-500/20 text-blue-300 border border-blue-500/30',
    Director: 'bg-sky-500/20 text-sky-300 border border-sky-500/30',
    Specialist: 'bg-teal-500/20 text-teal-300 border border-teal-500/30',
  }
  const cls = styles[role] ?? 'bg-zinc-700/40 text-zinc-400 border border-zinc-600/30'
  return (
    <span className={`px-2 py-0.5 rounded text-[10px] font-semibold uppercase tracking-wide ${cls}`}>
      {role}
    </span>
  )
}

/** Card de estatística no topo. */
const StatCard = ({
  label,
  value,
  icon: Icon,
  accent,
}: {
  label: string
  value: number
  icon: React.ElementType
  accent: string
}) => (
  <motion.div
    variants={itemVariants}
    className="glass-card p-5 flex items-center gap-4"
  >
    <div className={`w-10 h-10 rounded-xl flex items-center justify-center ${accent}`}>
      <Icon className="w-5 h-5" />
    </div>
    <div>
      <p className="text-2xl font-bold text-white">{value}</p>
      <p className="text-xs text-zinc-500 uppercase tracking-wide">{label}</p>
    </div>
  </motion.div>
)

/** Card individual de agente. */
const AgentCard = ({ agent }: { agent: PaperclipAgent }) => {
  const statusLabel: Record<string, string> = {
    active: 'Activo',
    idle: 'Inactivo',
    error: 'Erro',
    archived: 'Arquivado',
  }
  const statusColour: Record<string, string> = {
    active: 'text-emerald-400',
    idle: 'text-amber-400',
    error: 'text-red-400',
    archived: 'text-zinc-500',
  }

  return (
    <motion.div
      variants={itemVariants}
      className="glass-card p-4 flex flex-col gap-3 hover:border-cyan-500/20 transition-colors"
    >
      {/* Cabeçalho: ícone + nome + status dot */}
      <div className="flex items-start justify-between gap-2">
        <div className="flex items-center gap-2.5">
          <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-cyan-500/20 to-blue-600/20 border border-cyan-500/20 flex items-center justify-center flex-shrink-0">
            <Bot className="w-4 h-4 text-cyan-400" />
          </div>
          <span className="text-sm font-semibold text-white leading-tight">{agent.name}</span>
        </div>
        <StatusDot status={agent.status} />
      </div>

      {/* Role badge + estado */}
      <div className="flex items-center gap-2 flex-wrap">
        <RoleBadge role={agent.role} />
        <span className={`text-xs font-medium ${statusColour[agent.status] ?? 'text-zinc-400'}`}>
          {statusLabel[agent.status] ?? agent.status}
        </span>
      </div>

      {/* Último heartbeat */}
      <div className="flex items-center gap-1.5 text-xs text-zinc-500">
        <Clock className="w-3 h-3 flex-shrink-0" />
        <span className="truncate">
          {agent.last_heartbeat ? formatDate(agent.last_heartbeat) : 'Sem heartbeat'}
        </span>
      </div>
    </motion.div>
  )
}

/** Secção de agentes agrupados por role. */
const AgentsSection = ({ agents }: { agents: PaperclipAgent[] }) => {
  const groups = groupAgentsByRole(agents)
  const roleKeys = sortedRoleKeys(groups)

  if (agents.length === 0) {
    return (
      <motion.div variants={itemVariants} className="glass-card p-8 text-center">
        <Bot className="w-8 h-8 text-zinc-600 mx-auto mb-2" />
        <p className="text-zinc-500 text-sm">Sem agentes disponíveis</p>
      </motion.div>
    )
  }

  return (
    <>
      {roleKeys.map(role => (
        <motion.div key={role} variants={itemVariants}>
          {/* Separador de grupo */}
          <div className="flex items-center gap-3 mb-3">
            <Users className="w-4 h-4 text-cyan-500" />
            <h3 className="text-xs font-semibold uppercase tracking-widest text-cyan-400">{role}</h3>
            <div className="flex-1 h-px bg-white/5" />
            <span className="text-xs text-zinc-600">{groups[role].length}</span>
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3 mb-6">
            {groups[role].map(agent => (
              <AgentCard key={agent.id || agent.name} agent={agent} />
            ))}
          </div>
        </motion.div>
      ))}
    </>
  )
}

/** Tabela de routines. */
const RoutinesTable = ({ routines }: { routines: PaperclipRoutine[] }) => {
  if (routines.length === 0) {
    return (
      <motion.div variants={itemVariants} className="glass-card p-8 text-center">
        <Calendar className="w-8 h-8 text-zinc-600 mx-auto mb-2" />
        <p className="text-zinc-500 text-sm">Sem routines disponíveis</p>
      </motion.div>
    )
  }

  return (
    <motion.div variants={itemVariants} className="glass-card overflow-hidden">
      <div className="px-5 py-4 border-b border-white/5 flex items-center gap-2">
        <Calendar className="w-4 h-4 text-cyan-400" />
        <h3 className="text-sm font-semibold text-white uppercase tracking-wide">Routines</h3>
        <span className="ml-auto text-xs text-zinc-500">{routines.length} routines</span>
      </div>
      <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="text-xs text-zinc-500 uppercase tracking-wide border-b border-white/5">
              <th className="px-5 py-3 text-left">Nome</th>
              <th className="px-5 py-3 text-left">Cron</th>
              <th className="px-5 py-3 text-center">Activa</th>
              <th className="px-5 py-3 text-left">Último run</th>
              <th className="px-5 py-3 text-center">Estado</th>
              <th className="px-5 py-3 text-left">Próximo run</th>
            </tr>
          </thead>
          <tbody>
            {routines.map((routine, idx) => (
              <tr
                key={routine.id || routine.name}
                className={`border-b border-white/5 hover:bg-white/[0.02] transition-colors ${
                  idx % 2 === 0 ? '' : 'bg-white/[0.01]'
                }`}
              >
                <td className="px-5 py-3 text-white font-medium">{routine.name}</td>
                <td className="px-5 py-3">
                  <code className="text-xs bg-white/5 px-2 py-0.5 rounded text-cyan-300">
                    {routine.cron}
                  </code>
                </td>
                <td className="px-5 py-3 text-center">
                  {routine.active ? (
                    <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-emerald-500/20 text-emerald-400 text-xs font-medium">
                      <CheckCircle2 className="w-3 h-3" /> Sim
                    </span>
                  ) : (
                    <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-zinc-700/40 text-zinc-500 text-xs font-medium">
                      Não
                    </span>
                  )}
                </td>
                <td className="px-5 py-3 text-zinc-400 text-xs whitespace-nowrap">
                  {formatDate(routine.last_run)}
                </td>
                <td className="px-5 py-3 text-center">
                  {routine.last_status === 'success' ? (
                    <CheckCircle2 className="w-4 h-4 text-emerald-400 mx-auto" />
                  ) : routine.last_status === 'error' ? (
                    <AlertTriangle className="w-4 h-4 text-red-400 mx-auto" />
                  ) : (
                    <span className="text-zinc-600 text-xs">—</span>
                  )}
                </td>
                <td className="px-5 py-3 text-zinc-400 text-xs whitespace-nowrap">
                  {formatDate(routine.next_run)}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </motion.div>
  )
}

/** Contador de issues (open / in-progress / closed). */
const IssuesBar = ({ issues }: { issues: PaperclipDashboard['issues'] }) => (
  <motion.div variants={itemVariants} className="glass-card p-5">
    <div className="flex items-center gap-2 mb-4">
      <Activity className="w-4 h-4 text-cyan-400" />
      <h3 className="text-sm font-semibold text-white uppercase tracking-wide">Issues</h3>
    </div>
    <div className="grid grid-cols-3 gap-4">
      <div className="text-center">
        <p className="text-2xl font-bold text-red-400">{issues.open}</p>
        <p className="text-xs text-zinc-500 mt-1">Abertas</p>
      </div>
      <div className="text-center border-x border-white/5">
        <p className="text-2xl font-bold text-amber-400">{issues.in_progress}</p>
        <p className="text-xs text-zinc-500 mt-1">Em progresso</p>
      </div>
      <div className="text-center">
        <p className="text-2xl font-bold text-emerald-400">{issues.closed_7d}</p>
        <p className="text-xs text-zinc-500 mt-1">Fechadas (7d)</p>
      </div>
    </div>
  </motion.div>
)

// ---------------------------------------------------------------------------
// Página principal
// ---------------------------------------------------------------------------

export default function Paperclip() {
  const [data, setData] = useState<PaperclipDashboard | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [lastUpdated, setLastUpdated] = useState<Date | null>(null)

  const fetchData = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const res = await fetch('/api/paperclip')
      if (!res.ok) {
        const body = await res.json().catch(() => ({}))
        throw new Error(body?.message ?? `HTTP ${res.status}`)
      }
      const json: PaperclipDashboard = await res.json()
      setData(json)
      setLastUpdated(new Date())
    } catch (err) {
      setError((err as Error).message)
    } finally {
      setLoading(false)
    }
  }, [])

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

  return (
    <div className="min-h-screen bg-zinc-950 p-6 space-y-6">
      {/* Cabeçalho */}
      <motion.div
        variants={containerVariants}
        initial="hidden"
        animate="show"
        className="flex items-center justify-between"
      >
        <motion.div variants={itemVariants} className="flex items-center gap-4">
          <div className="w-12 h-12 rounded-xl bg-gradient-to-br from-cyan-500 to-blue-600 flex items-center justify-center shadow-lg shadow-cyan-500/30">
            <Bot className="w-6 h-6 text-white" />
          </div>
          <div>
            <h1 className="text-xl font-bold text-white">Paperclip</h1>
            <p className="text-xs text-zinc-500">
              Orquestrador autónomo — agentes, routines e issues
            </p>
          </div>
        </motion.div>

        <motion.div variants={itemVariants} className="flex items-center gap-3">
          {lastUpdated && (
            <span className="text-xs text-zinc-600">
              Actualizado às {lastUpdated.toLocaleTimeString('pt-PT', { hour: '2-digit', minute: '2-digit' })}
            </span>
          )}
          <button
            onClick={fetchData}
            disabled={loading}
            className="flex items-center gap-2 px-4 py-2 rounded-lg bg-white/5 hover:bg-white/10 border border-white/10 text-sm text-zinc-300 transition-colors disabled:opacity-50"
          >
            <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
            Actualizar
          </button>
        </motion.div>
      </motion.div>

      {/* Estado de erro */}
      {error && (
        <motion.div
          initial={{ opacity: 0, y: -10 }}
          animate={{ opacity: 1, y: 0 }}
          className="flex items-center gap-3 px-5 py-4 rounded-xl bg-red-500/10 border border-red-500/20 text-red-400 text-sm"
        >
          <AlertTriangle className="w-4 h-4 flex-shrink-0" />
          <span>Erro ao carregar dados: {error}</span>
        </motion.div>
      )}

      {/* Estado de carregamento inicial */}
      {loading && !data && (
        <motion.div
          variants={containerVariants}
          initial="hidden"
          animate="show"
          className="grid grid-cols-2 sm:grid-cols-4 gap-4"
        >
          {[...Array(4)].map((_, i) => (
            <div key={i} className="glass-card p-5 h-20 animate-pulse bg-white/[0.03]" />
          ))}
        </motion.div>
      )}

      {/* Conteúdo principal */}
      {data && (
        <motion.div
          variants={containerVariants}
          initial="hidden"
          animate="show"
          className="space-y-6"
        >
          {/* Stats cards */}
          <div className="grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4 gap-4">
            <StatCard
              label="Agentes activos"
              value={data.agents.active}
              icon={Zap}
              accent="bg-emerald-500/20 text-emerald-400"
            />
            <StatCard
              label="Agentes idle"
              value={data.agents.idle}
              icon={Bot}
              accent="bg-amber-500/20 text-amber-400"
            />
            <StatCard
              label="Agentes com erro"
              value={data.agents.error}
              icon={AlertTriangle}
              accent="bg-red-500/20 text-red-400"
            />
            <StatCard
              label="Routines activas"
              value={data.routines.active}
              icon={Calendar}
              accent="bg-cyan-500/20 text-cyan-400"
            />
          </div>

          {/* Issues */}
          <IssuesBar issues={data.issues} />

          {/* Agentes agrupados por role */}
          <div>
            <motion.div variants={itemVariants} className="flex items-center gap-2 mb-4">
              <Users className="w-4 h-4 text-cyan-400" />
              <h2 className="text-sm font-semibold text-white uppercase tracking-wide">
                Agentes
              </h2>
              <span className="text-xs text-zinc-500 ml-1">({data.agents.total} total)</span>
            </motion.div>
            <AgentsSection agents={data.agents.list} />
          </div>

          {/* Routines */}
          <RoutinesTable routines={data.routines.list} />
        </motion.div>
      )}
    </div>
  )
}
