import { useEffect, useMemo, useState } from 'react'
import { Info, AlertTriangle, RotateCcw, Check, GitMerge } from 'lucide-react'
import { Label } from '@/components/ui/label'
import { Button } from '@/components/ui/button'
import { Slider } from '@/components/ui/slider'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { ScrollArea } from '@/components/ui/scroll-area'
import { useProcessStore } from '@/store/process-store'
import { parseBpmnXml } from '@/domain/bpmn-parser'
import { formatPercent } from '@/lib/format'
import type { GatewayConfig } from '@/domain/types'

interface GatewayPanelProps {
  selectedElementId: string | null
}

// Tolerancia para validar que la suma de probs XOR = 1.0
const XOR_SUM_TOLERANCE = 0.005

function sumBranches(gw: GatewayConfig): number {
  return gw.branches.reduce((s, b) => s + b.probability, 0)
}

export function isXorSumValid(gw: GatewayConfig): boolean {
  if (gw.gatewayType !== 'exclusive') return true
  return Math.abs(sumBranches(gw) - 1.0) <= XOR_SUM_TOLERANCE
}

export function GatewayPanel({ selectedElementId }: GatewayPanelProps) {
  const { gateways, currentProcess, updateGateway, activities } = useProcessStore()
  const [localGw, setLocalGw] = useState<GatewayConfig | null>(null)
  const [isDirty, setIsDirty] = useState(false)

  // Mapa bpmnElementId → nombre legible (parseamos el XML una sola vez)
  const elementNames = useMemo(() => {
    if (!currentProcess) return new Map<string, string>()
    try {
      const graph = parseBpmnXml(currentProcess.bpmnXml)
      return new Map(Array.from(graph.nodes.values()).map((n) => [n.id, n.name || n.id]))
    } catch {
      return new Map<string, string>()
    }
  }, [currentProcess?.bpmnXml])

  const gateway = gateways.find((g) => g.bpmnElementId === selectedElementId) ?? null

  useEffect(() => {
    setLocalGw(gateway ? structuredClone(gateway) : null)
    setIsDirty(false)
  }, [selectedElementId, gateways])

  function targetLabel(targetId: string): string {
    // Primero buscar en actividades (tienen nombre más descriptivo)
    const act = activities.find((a) => a.bpmnElementId === targetId)
    if (act?.name) return act.name
    // Luego en el mapa del grafo
    const fromGraph = elementNames.get(targetId)
    if (fromGraph) return fromGraph
    return targetId
  }

  function setProbability(branchIndex: number, value: number) {
    if (!localGw) return
    const updated = structuredClone(localGw)
    updated.branches[branchIndex].probability = value
    setLocalGw(updated)
    setIsDirty(true)
  }

  function distributeUniformly() {
    if (!localGw) return
    const n = localGw.branches.length
    const equalProb = parseFloat((1 / n).toFixed(4))
    const updated = structuredClone(localGw)
    updated.branches = updated.branches.map((b, i) => ({
      ...b,
      probability: i === n - 1 ? parseFloat((1 - equalProb * (n - 1)).toFixed(4)) : equalProb,
    }))
    setLocalGw(updated)
    setIsDirty(true)
  }

  async function handleSave() {
    if (!localGw) return
    await updateGateway(localGw)
    setIsDirty(false)
  }

  // ── Empty state ──────────────────────────────────────────────────────────
  if (!selectedElementId) {
    return (
      <div className="flex flex-col items-center justify-center h-full text-center px-6 py-12">
        <div className="w-12 h-12 bg-slate-100 rounded-full flex items-center justify-center mb-3">
          <GitMerge className="h-6 w-6 text-slate-400" />
        </div>
        <p className="text-sm font-medium text-slate-600 mb-1">Seleccioná un gateway</p>
        <p className="text-xs text-slate-400">Hacé click sobre un gateway en el diagrama para configurar sus probabilidades</p>
      </div>
    )
  }

  if (!localGw) {
    return (
      <div className="flex items-center justify-center h-full">
        <p className="text-xs text-slate-400">Gateway sin configuración</p>
      </div>
    )
  }

  // ── AND Paralelo: informativo, sin sliders ────────────────────────────────
  if (localGw.gatewayType === 'parallel') {
    return (
      <ScrollArea className="h-full">
        <div className="p-4 space-y-4">
          <div>
            <div className="flex items-center gap-2 mb-1">
              <span className="text-xs font-semibold text-slate-500 uppercase tracking-wide">Gateway Paralelo (AND)</span>
            </div>
            <p className="text-xs font-medium text-slate-800 font-mono">{localGw.bpmnElementId}</p>
          </div>

          <div className="bg-blue-50 border border-blue-200 rounded-lg p-3 space-y-2">
            <div className="flex items-start gap-2">
              <Info className="h-4 w-4 text-blue-500 shrink-0 mt-0.5" />
              <div>
                <p className="text-xs font-semibold text-blue-800">Ejecución paralela</p>
                <p className="text-xs text-blue-700 mt-0.5">
                  En un gateway AND todas las salidas se ejecutan simultáneamente.
                  No hay probabilidades configurables — la probabilidad de cada rama
                  es igual a la probabilidad de llegada al gateway.
                </p>
              </div>
            </div>
          </div>

          <div className="space-y-2">
            <Label className="text-xs font-medium">Flujos de salida</Label>
            {localGw.branches.map((branch) => (
              <div key={branch.flowId} className="flex items-center justify-between p-2.5 rounded-lg bg-slate-50 border border-slate-100">
                <div className="min-w-0">
                  <p className="text-xs font-medium text-slate-700 truncate">{targetLabel(branch.targetElementId)}</p>
                  <p className="text-xs text-slate-400 font-mono">{branch.flowId}</p>
                </div>
                <span className="text-xs font-mono font-semibold text-blue-600 shrink-0 ml-2">100%</span>
              </div>
            ))}
          </div>
        </div>
      </ScrollArea>
    )
  }

  // ── XOR Exclusivo / OR Inclusivo (con aviso) ──────────────────────────────
  const isInclusive = localGw.gatewayType === 'inclusive'
  const currentSum = sumBranches(localGw)
  const xorValid = isInclusive || Math.abs(currentSum - 1.0) <= XOR_SUM_TOLERANCE
  const sumColor = xorValid ? 'text-green-600' : 'text-destructive'

  return (
    <ScrollArea className="h-full">
      <div className="p-4 space-y-4">
        {/* Header */}
        <div>
          <span className="text-xs font-semibold text-slate-500 uppercase tracking-wide block mb-1">
            {isInclusive ? 'Gateway Inclusivo (OR)' : 'Gateway Exclusivo (XOR)'}
          </span>
          <p className="text-xs font-medium text-slate-800 font-mono">{localGw.bpmnElementId}</p>
        </div>

        {/* Aviso para OR inclusivo */}
        {isInclusive && (
          <div className="bg-amber-50 border border-amber-200 rounded-lg p-3 flex items-start gap-2">
            <AlertTriangle className="h-4 w-4 text-amber-500 shrink-0 mt-0.5" />
            <p className="text-xs text-amber-800">
              <span className="font-semibold">Gateway Inclusivo (OR)</span> — En el MVP se simula como
              XOR: solo una rama se toma por instancia. Las probabilidades deben sumar 1.
              El soporte OR nativo llega en V1.0.
            </p>
          </div>
        )}

        {/* Suma actual + botón distribuir */}
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-1.5">
            <span className="text-xs text-slate-500">Suma de probabilidades:</span>
            <span className={`text-xs font-mono font-bold ${sumColor}`}>
              {formatPercent(currentSum * 100, 1)}
            </span>
            {!xorValid && (
              <Tooltip>
                <TooltipTrigger asChild>
                  <AlertTriangle className="h-3.5 w-3.5 text-destructive cursor-help" />
                </TooltipTrigger>
                <TooltipContent side="right" className="max-w-44 text-xs">
                  La suma debe ser exactamente 100% para poder simular
                </TooltipContent>
              </Tooltip>
            )}
            {xorValid && (
              <Tooltip>
                <TooltipTrigger asChild>
                  <Check className="h-3.5 w-3.5 text-green-500 cursor-help" />
                </TooltipTrigger>
                <TooltipContent side="right" className="text-xs">
                  Suma 100% — listo para simular
                </TooltipContent>
              </Tooltip>
            )}
          </div>
          <Tooltip>
            <TooltipTrigger asChild>
              <Button
                variant="ghost"
                size="sm"
                className="h-7 text-xs gap-1 text-slate-500"
                onClick={distributeUniformly}
              >
                <RotateCcw className="h-3 w-3" />
                Distribuir uniformemente
              </Button>
            </TooltipTrigger>
            <TooltipContent side="left" className="max-w-52 text-xs">
              Reparte el 100% en partes iguales entre todas las ramas del gateway
            </TooltipContent>
          </Tooltip>
        </div>

        {/* Sliders por rama */}
        <div className="space-y-4">
          {localGw.branches.map((branch, idx) => (
            <div key={branch.flowId} className="space-y-1.5">
              <div className="flex items-start justify-between gap-2">
                <div className="min-w-0">
                  <p className="text-xs font-medium text-slate-700 truncate leading-tight">
                    {targetLabel(branch.targetElementId)}
                  </p>
                  <p className="text-[10px] text-slate-400 font-mono truncate">{branch.flowId}</p>
                </div>
                <span className="text-xs font-mono font-semibold text-slate-700 shrink-0 w-11 text-right tabular-nums">
                  {formatPercent(branch.probability * 100, 1)}
                </span>
              </div>
              <Slider
                value={[Math.round(branch.probability * 1000) / 10]}
                min={0}
                max={100}
                step={1}
                onValueChange={([v]) => setProbability(idx, parseFloat((v / 100).toFixed(4)))}
              />
            </div>
          ))}
        </div>

        {/* Error de suma — banner prominente */}
        {!xorValid && (
          <div className="bg-destructive/10 border border-destructive/30 rounded-lg p-3 flex items-start gap-2">
            <AlertTriangle className="h-4 w-4 text-destructive shrink-0 mt-0.5" />
            <p className="text-xs text-destructive">
              La suma es <strong>{formatPercent(currentSum * 100, 1)}</strong> — debe ser 100%.
              Ajustá los sliders o usá "Distribuir" para repartir uniformemente.
              El botón <strong>Simular</strong> quedará deshabilitado hasta corregirlo.
            </p>
          </div>
        )}

        <Button
          size="sm"
          onClick={handleSave}
          disabled={!isDirty}
          className="w-full"
        >
          {isDirty ? 'Guardar probabilidades' : 'Sin cambios'}
        </Button>
      </div>
    </ScrollArea>
  )
}
