import type { ComponentType } from 'react'
import { Position, type NodeProps } from '@xyflow/react'
import { FlowNodeCard } from '../threat-visuals/index'
import { SafeHandle as Handle } from './safe-handle'
import {
  FileCode2,
  Shield,
  Radar,
  Grid3X3,
  Globe,
  CircleCheck,
  TriangleAlert,
  CircleX,
  Lightbulb,
} from 'lucide-react'
import { getConnectorLogo } from './logos'

// ── SourceNode ──────────────────────────────────────────────────────────────

const iconMap: Record<string, ComponentType<{ size?: number; className?: string }>> = {
  FileCode2,
  Shield,
  Radar,
  Grid3X3,
  Globe,
}

// Sources that should use real product logos instead of lucide icons
const sourcesWithLogos = new Set([
  'MITRE ATT&CK',
  'OpenCTI Intel',
  'SigmaHQ',
  'YARA Rules',
  'ET/Snort',
])

const categoryColors: Record<string, { bg: string; text: string }> = {
  detection: { bg: 'bg-blue-50 dark:bg-blue-500/10', text: 'text-blue-600 dark:text-blue-400' },
  intel: { bg: 'bg-violet-50 dark:bg-violet-500/10', text: 'text-violet-600 dark:text-violet-400' },
  validation: {
    bg: 'bg-amber-50 dark:bg-amber-500/10',
    text: 'text-amber-600 dark:text-amber-400',
  },
  framework: { bg: 'bg-slate-50 dark:bg-slate-800', text: 'text-slate-600 dark:text-slate-400' },
}

export interface SourceNodeData {
  name: string
  icon: string
  category: string
  categoryLabel: string
  health: 'healthy' | 'warning' | 'error'
  ruleCount: number
  countLabel: string
  cadence: string
}

const healthDot: Record<string, string> = {
  healthy: 'bg-emerald-400',
  warning: 'bg-amber-400',
  error: 'bg-rose-400',
}

export function SourceNode({ data }: NodeProps & { data: SourceNodeData }) {
  const fallbackColors = {
    bg: 'bg-slate-50 dark:bg-slate-800',
    text: 'text-slate-600 dark:text-slate-400',
  }
  const colors = categoryColors[data.category] ?? fallbackColors
  const useLogo = sourcesWithLogos.has(data.name)
  const Icon = iconMap[data.icon]

  return (
    <div>
      <FlowNodeCard
        title={data.name}
        eyebrow={data.categoryLabel}
        tone={
          data.category === 'framework'
            ? 'slate'
            : data.category === 'detection'
              ? 'blue'
              : data.category === 'intel'
                ? 'violet'
                : 'amber'
        }
        variant="stripe"
        icon={
          useLogo ? (
            (() => {
              const Logo = getConnectorLogo(data.name)
              return <Logo size={14} />
            })()
          ) : Icon ? (
            <Icon size={12} className={colors.text} />
          ) : null
        }
        meta={
          <div className="flex items-center gap-2">
            <span
              className={`inline-block h-1.5 w-1.5 rounded-full ${healthDot[data.health] ?? ''}`}
            />
            <span className="font-semibold tabular-nums text-slate-700 dark:text-slate-200">
              {data.ruleCount.toLocaleString()}
            </span>
            <span>{data.countLabel}</span>
            <span className="text-slate-300 dark:text-slate-600">|</span>
            <span>{data.cadence}</span>
          </div>
        }
        className={colors.bg}
      />
      <Handle
        type="source"
        position={Position.Right}
        className="!h-2 !w-2 !border-[1.5px] !border-white dark:!border-slate-800 !bg-blue-400"
      />
    </div>
  )
}

// ── PlatformNode ────────────────────────────────────────────────────────────

export interface PlatformNodeData {
  name: string
  role: string
  metric: string
}

export function PlatformNode({ data }: NodeProps & { data: PlatformNodeData }) {
  return (
    <div>
      <FlowNodeCard
        title={data.name}
        eyebrow={data.role}
        tone="orange"
        variant="outline"
        icon={<CountermeasureDiamond />}
        meta={
          <div className="flex items-center gap-1.5">
            <span className="inline-block h-1.5 w-1.5 rounded-full bg-orange-400" />
            <span className="font-semibold text-slate-700 dark:text-slate-200">{data.metric}</span>
          </div>
        }
        className="w-[200px]"
      />
      <Handle
        type="target"
        position={Position.Left}
        className="!h-2 !w-2 !border-[1.5px] !border-white dark:!border-slate-800 !bg-orange-400"
      />
      <Handle
        type="source"
        position={Position.Right}
        className="!h-2 !w-2 !border-[1.5px] !border-white dark:!border-slate-800 !bg-orange-400"
      />
    </div>
  )
}

function CountermeasureDiamond() {
  return (
    <svg width="16" height="16" viewBox="0 0 46.64 46.64" xmlns="http://www.w3.org/2000/svg">
      <rect
        x="2.62"
        y="16.42"
        width="13.8"
        height="13.8"
        rx=".57"
        ry=".57"
        transform="translate(-13.7 13.56) rotate(-45)"
        fill="#f1f5f9"
      />
      <rect
        x="16.42"
        y="30.22"
        width="13.8"
        height="13.8"
        rx=".57"
        ry=".57"
        transform="translate(-19.42 27.36) rotate(-45)"
        fill="#64748b"
      />
      <rect
        x="16.42"
        y="2.62"
        width="13.8"
        height="13.8"
        rx=".57"
        ry=".57"
        transform="translate(.1 19.28) rotate(-45)"
        fill="#f97316"
      />
    </svg>
  )
}

// ── TenantNode ──────────────────────────────────────────────────────────────

export interface TenantNodeData {
  name: string
  color: string
  status: 'active' | 'degraded' | 'offline'
  requests24h: number
  detections: number
}

const statusConfig: Record<
  string,
  {
    icon: ComponentType<{ size?: number; className?: string }>
    label: string
    textColor: string
    hex: string
    bg: string
  }
> = {
  active: {
    icon: CircleCheck,
    label: 'Active',
    textColor: 'text-emerald-500',
    hex: '#34d399',
    bg: 'bg-emerald-50 dark:bg-emerald-500/10',
  },
  degraded: {
    icon: TriangleAlert,
    label: 'Degraded',
    textColor: 'text-amber-500',
    hex: '#fbbf24',
    bg: 'bg-amber-50 dark:bg-amber-500/10',
  },
  offline: {
    icon: CircleX,
    label: 'Offline',
    textColor: 'text-rose-500',
    hex: '#fb7185',
    bg: 'bg-rose-50 dark:bg-rose-500/10',
  },
}

export function TenantNode({ data }: NodeProps & { data: TenantNodeData }) {
  const activeDefault = {
    icon: CircleCheck,
    label: 'Active',
    textColor: 'text-emerald-500',
    hex: '#34d399',
    bg: 'bg-emerald-50 dark:bg-emerald-500/10',
  }
  const status = statusConfig[data.status] ?? activeDefault

  return (
    <div>
      <FlowNodeCard
        title={data.name}
        eyebrow={<span className={status.textColor}>{status.label}</span>}
        tone={data.status === 'active' ? 'emerald' : data.status === 'degraded' ? 'amber' : 'rose'}
        variant="stripe"
        icon={<status.icon size={13} className={status.textColor} />}
        meta={
          <div className="flex items-center gap-2">
            <span className="font-semibold tabular-nums text-slate-700 dark:text-slate-200">
              {data.requests24h.toLocaleString()}
            </span>
            <span>req/24h</span>
            <span className="text-slate-300 dark:text-slate-600">|</span>
            <span className="font-semibold tabular-nums text-blue-500 dark:text-blue-400">
              {data.detections.toLocaleString()}
            </span>
            <span>det</span>
          </div>
        }
        className={status.bg}
      />
      <Handle
        type="target"
        position={Position.Left}
        className="!h-2 !w-2 !border-[1.5px] !border-white dark:!border-slate-800"
        style={{ background: status.hex }}
      />
      <Handle
        type="source"
        position={Position.Right}
        className="!h-2 !w-2 !border-[1.5px] !border-white dark:!border-slate-800"
        style={{ background: status.hex }}
      />
    </div>
  )
}

// ── ConnectorNode ───────────────────────────────────────────────────────────

export interface ConnectorNodeData {
  name: string
  type: 'siem' | 'edr' | 'intel' | 'validation' | 'framework'
  status: 'connected' | 'degraded' | 'disconnected'
}

const typeConfig: Record<string, { label: string; color: string }> = {
  siem: { label: 'SIEM', color: '#60a5fa' },
  edr: { label: 'EDR', color: '#a78bfa' },
  intel: { label: 'Intel', color: '#fbbf24' },
  validation: { label: 'Validation', color: '#34d399' },
  framework: { label: 'Framework', color: '#94a3b8' },
}

const statusDot: Record<string, string> = {
  connected: 'bg-emerald-400',
  degraded: 'bg-amber-400',
  disconnected: 'bg-rose-400',
}

export function ConnectorNode({ data }: NodeProps & { data: ConnectorNodeData }) {
  const siemDefault = { label: 'SIEM', color: '#60a5fa' }
  const config = typeConfig[data.type] ?? siemDefault
  const Logo = getConnectorLogo(data.name)

  return (
    <div>
      <FlowNodeCard
        title={data.name}
        eyebrow={
          <span className="flex items-center gap-1">
            <span className={`inline-block h-1 w-1 rounded-full ${statusDot[data.status] ?? ''}`} />
            <span style={{ color: config.color }}>{config.label}</span>
          </span>
        }
        tone={
          data.type === 'siem'
            ? 'blue'
            : data.type === 'edr'
              ? 'violet'
              : data.type === 'intel'
                ? 'amber'
                : data.type === 'validation'
                  ? 'emerald'
                  : 'slate'
        }
        variant="subtle"
        size="compact"
        icon={<Logo size={16} />}
      />
      <Handle
        type="target"
        position={Position.Left}
        className="!h-2 !w-2 !border-[1.5px] !border-slate-50 dark:!border-slate-800 !bg-slate-400"
      />
    </div>
  )
}

// ── LibraryNode ─────────────────────────────────────────────────────────────

export interface LibraryNodeData {
  name: string
  category: 'detection' | 'actor' | 'intel' | 'framework' | 'opportunity'
  metric: string
}

const libCategoryConfig: Record<
  string,
  {
    icon: ComponentType<{ size?: number; className?: string }>
    label: string
  }
> = {
  detection: { icon: FileCode2, label: 'Detections' },
  actor: { icon: Shield, label: 'Actors' },
  intel: { icon: Radar, label: 'Intelligence' },
  framework: { icon: Grid3X3, label: 'Framework' },
  opportunity: { icon: Lightbulb, label: 'Opportunities' },
}

export function LibraryNode({ data }: NodeProps & { data: LibraryNodeData }) {
  const detectionDefault = { icon: FileCode2, label: 'Detections' }
  const config = libCategoryConfig[data.category] ?? detectionDefault

  return (
    <div>
      <FlowNodeCard
        title={data.name}
        eyebrow={config.label}
        tone="orange"
        variant="outline"
        icon={<config.icon size={13} className="text-orange-600 dark:text-orange-400" />}
        meta={
          <div className="flex items-center gap-1.5">
            <span className="inline-block h-1.5 w-1.5 rounded-full bg-orange-400" />
            <span className="font-semibold text-slate-700 dark:text-slate-200">{data.metric}</span>
          </div>
        }
      />
      <Handle
        type="target"
        position={Position.Left}
        className="!h-2 !w-2 !border-[1.5px] !border-white dark:!border-slate-800 !bg-orange-400"
      />
      <Handle
        type="source"
        position={Position.Right}
        className="!h-2 !w-2 !border-[1.5px] !border-white dark:!border-slate-800 !bg-orange-400"
      />
    </div>
  )
}
