import * as React from 'react'
import { cva } from 'class-variance-authority'

import { cn } from './utils'

/* ------------------------------------------------------------------ */
/*  Types                                                              */
/* ------------------------------------------------------------------ */

export type DetectionRuleStatus = 'active' | 'disabled' | 'testing' | 'error'

export type DetectionSeverity = 'critical' | 'high' | 'medium' | 'low' | 'info'

export interface DetectionRule {
  id: string
  name: string
  source: string
  status: DetectionRuleStatus
  lastTriggered?: Date | string
  triggerCount?: number
  severity?: DetectionSeverity
  tags?: string[]
}

/* ------------------------------------------------------------------ */
/*  Helpers                                                            */
/* ------------------------------------------------------------------ */

const STATUS_LABELS: Record<DetectionRuleStatus, string> = {
  active: 'Active',
  disabled: 'Disabled',
  testing: 'Testing',
  error: 'Error',
}

function formatDate(value: Date | string): string {
  const d = value instanceof Date ? value : new Date(value)
  return d.toLocaleDateString(undefined, {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  })
}

/* ------------------------------------------------------------------ */
/*  Variants                                                           */
/* ------------------------------------------------------------------ */

const statusDotVariants = cva('inline-block size-2 shrink-0 rounded-full', {
  variants: {
    status: {
      active: 'bg-accent-emerald',
      disabled: 'bg-foreground-muted',
      testing: 'bg-accent-amber',
      error: 'bg-accent-rose',
    },
  },
  defaultVariants: {
    status: 'active',
  },
})

const statusLabelVariants = cva('text-xs font-medium', {
  variants: {
    status: {
      active: 'text-accent-emerald',
      disabled: 'text-foreground-muted',
      testing: 'text-accent-amber',
      error: 'text-accent-rose',
    },
  },
  defaultVariants: {
    status: 'active',
  },
})

const severityBadgeVariants = cva(
  'inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-bold',
  {
    variants: {
      severity: {
        critical: 'bg-accent-rose/15 text-accent-rose',
        high: 'bg-accent-rose/10 text-accent-rose/80',
        medium: 'bg-accent-amber/10 text-accent-amber',
        low: 'bg-accent-cyan/10 text-accent-cyan',
        info: 'bg-foreground-muted/10 text-foreground-secondary',
      },
    },
    defaultVariants: {
      severity: 'info',
    },
  }
)

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

function StatusIcon({ status }: { status: DetectionRuleStatus }) {
  const iconClass = 'size-4'
  switch (status) {
    case 'active':
      return (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth={2}
          strokeLinecap="round"
          strokeLinejoin="round"
          className={cn(iconClass, 'text-accent-emerald')}
        >
          <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
          <path d="m9 12 2 2 4-4" />
        </svg>
      )
    case 'disabled':
      return (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth={2}
          strokeLinecap="round"
          strokeLinejoin="round"
          className={cn(iconClass, 'text-foreground-muted')}
        >
          <circle cx="12" cy="12" r="10" />
          <line x1="4.93" y1="4.93" x2="19.07" y2="19.07" />
        </svg>
      )
    case 'testing':
      return (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth={2}
          strokeLinecap="round"
          strokeLinejoin="round"
          className={cn(iconClass, 'text-accent-amber')}
        >
          <path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" />
        </svg>
      )
    case 'error':
      return (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth={2}
          strokeLinecap="round"
          strokeLinejoin="round"
          className={cn(iconClass, 'text-accent-rose')}
        >
          <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" />
          <line x1="12" y1="9" x2="12" y2="13" />
          <line x1="12" y1="17" x2="12.01" y2="17" />
        </svg>
      )
  }
}

/* ------------------------------------------------------------------ */
/*  DetectionStatusBadge (single rule inline indicator)                */
/* ------------------------------------------------------------------ */

export interface DetectionStatusBadgeProps extends React.ComponentProps<'span'> {
  status: DetectionRuleStatus
  /** Show the status icon. Defaults to true. */
  showIcon?: boolean
  /** Show the text label. Defaults to true. */
  showLabel?: boolean
}

function DetectionStatusBadge({
  className,
  status,
  showIcon = true,
  showLabel = true,
  ...props
}: DetectionStatusBadgeProps) {
  return (
    <span
      data-slot="detection-status-badge"
      role="status"
      aria-label={`Status: ${STATUS_LABELS[status]}`}
      className={cn('inline-flex items-center gap-1.5', className)}
      {...props}
    >
      {showIcon && <StatusIcon status={status} />}
      {showLabel && (
        <span className={statusLabelVariants({ status })}>{STATUS_LABELS[status]}</span>
      )}
    </span>
  )
}

/* ------------------------------------------------------------------ */
/*  DetectionStatusRow (single rule row for use inside a list/table)   */
/* ------------------------------------------------------------------ */

export interface DetectionStatusRowProps extends Omit<React.ComponentProps<'div'>, 'onClick'> {
  rule: DetectionRule
  onClick?: ((rule: DetectionRule) => void) | undefined
}

function DetectionStatusRow({ className, rule, onClick, ...props }: DetectionStatusRowProps) {
  return (
    <div
      data-slot="detection-status-row"
      role="listitem"
      className={cn(
        'flex items-center gap-4 rounded-lg border border-border-glass bg-glass px-4 py-3 backdrop-blur-[20px]',
        'transition-all duration-200 hover:bg-glass-hover',
        onClick && 'cursor-pointer',
        className
      )}
      onClick={onClick ? () => onClick(rule) : undefined}
      {...props}
    >
      {/* Status dot + name */}
      <div className="flex min-w-0 flex-1 items-center gap-3">
        <span aria-hidden="true" className={statusDotVariants({ status: rule.status })} />
        <div className="min-w-0 flex-1">
          <div className="truncate text-sm font-medium text-foreground">{rule.name}</div>
          <div className="truncate text-xs text-foreground-muted">{rule.source}</div>
        </div>
      </div>

      {/* Severity */}
      {rule.severity && (
        <span className={severityBadgeVariants({ severity: rule.severity })}>
          {rule.severity.charAt(0).toUpperCase() + rule.severity.slice(1)}
        </span>
      )}

      {/* Status label */}
      <span className={cn(statusLabelVariants({ status: rule.status }), 'shrink-0 text-xs')}>
        {STATUS_LABELS[rule.status]}
      </span>

      {/* Trigger count */}
      <span className="shrink-0 text-xs tabular-nums text-foreground-secondary">
        {rule.triggerCount ?? 0}
      </span>

      {/* Last triggered */}
      <span className="shrink-0 text-xs text-foreground-muted">
        {rule.lastTriggered ? formatDate(rule.lastTriggered) : 'Never'}
      </span>

      {/* Tags */}
      {rule.tags && rule.tags.length > 0 && (
        <div className="hidden items-center gap-1 lg:flex">
          {rule.tags.map(tag => (
            <span
              key={tag}
              className="rounded-full border border-border-glass bg-surface-secondary px-2 py-0.5 text-[10px] text-foreground-muted"
            >
              {tag}
            </span>
          ))}
        </div>
      )}
    </div>
  )
}

/* ------------------------------------------------------------------ */
/*  DetectionStatusList (full list with optional search/filters)       */
/* ------------------------------------------------------------------ */

export interface DetectionStatusListProps extends React.ComponentProps<'div'> {
  rules: DetectionRule[]
  /** Show search input. */
  showSearch?: boolean
  /** Show status/severity filter dropdowns. */
  showFilters?: boolean
  /** Callback when a rule row is clicked. */
  onRuleClick?: (rule: DetectionRule) => void
}

function DetectionStatusList({
  className,
  rules,
  showSearch = false,
  showFilters = false,
  onRuleClick,
  ...props
}: DetectionStatusListProps) {
  const [search, setSearch] = React.useState('')
  const [statusFilter, setStatusFilter] = React.useState<DetectionRuleStatus | 'all'>('all')
  const [severityFilter, setSeverityFilter] = React.useState<DetectionSeverity | 'all'>('all')

  const filtered = React.useMemo(() => {
    let result = rules
    if (statusFilter !== 'all') {
      result = result.filter(r => r.status === statusFilter)
    }
    if (severityFilter !== 'all') {
      result = result.filter(r => r.severity === severityFilter)
    }
    if (search.length > 0) {
      const q = search.toLowerCase()
      result = result.filter(
        r => r.name.toLowerCase().includes(q) || r.source.toLowerCase().includes(q)
      )
    }
    return result
  }, [rules, statusFilter, severityFilter, search])

  const selectClass =
    'rounded-lg border border-border-glass bg-glass px-3 py-1.5 text-xs text-foreground backdrop-blur-[20px] outline-none focus:ring-1 focus:ring-accent-cyan/40'

  return (
    <div
      data-slot="detection-status-list"
      className={cn('flex flex-col gap-3', className)}
      {...props}
    >
      {/* Controls */}
      {(showSearch || showFilters) && (
        <div className="flex flex-wrap items-center gap-2">
          {showSearch && (
            <input
              type="text"
              placeholder="Search rules..."
              aria-label="Search detection rules"
              value={search}
              onChange={e => setSearch(e.target.value)}
              className={cn(
                'flex-1 rounded-lg border border-border-glass bg-glass px-3 py-1.5 text-sm text-foreground backdrop-blur-[20px]',
                'placeholder:text-foreground-muted outline-none focus:ring-1 focus:ring-accent-cyan/40'
              )}
            />
          )}
          {showFilters && (
            <>
              <select
                aria-label="Filter by status"
                value={statusFilter}
                onChange={e => setStatusFilter(e.target.value as DetectionRuleStatus | 'all')}
                className={selectClass}
              >
                <option value="all">All Statuses</option>
                <option value="active">Active</option>
                <option value="disabled">Disabled</option>
                <option value="testing">Testing</option>
                <option value="error">Error</option>
              </select>
              <select
                aria-label="Filter by severity"
                value={severityFilter}
                onChange={e => setSeverityFilter(e.target.value as DetectionSeverity | 'all')}
                className={selectClass}
              >
                <option value="all">All Severities</option>
                <option value="critical">Critical</option>
                <option value="high">High</option>
                <option value="medium">Medium</option>
                <option value="low">Low</option>
                <option value="info">Info</option>
              </select>
            </>
          )}
        </div>
      )}

      {/* Rule rows */}
      <div role="list" className="flex flex-col gap-2">
        {filtered.length === 0 ? (
          <div className="rounded-lg border border-border-glass bg-glass px-4 py-8 text-center text-sm text-foreground-muted backdrop-blur-[20px]">
            No detection rules found
          </div>
        ) : (
          filtered.map(rule => (
            <DetectionStatusRow key={rule.id} rule={rule} onClick={onRuleClick ?? undefined} />
          ))
        )}
      </div>
    </div>
  )
}

export {
  DetectionStatusBadge,
  DetectionStatusRow,
  DetectionStatusList,
  statusDotVariants,
  statusLabelVariants,
  severityBadgeVariants,
}
