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

import { cn } from './utils'

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

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

export type VulnerabilityStatus =
  | 'open'
  | 'in_progress'
  | 'resolved'
  | 'accepted'
  | 'false_positive'

export interface VulnerabilityReference {
  title: string
  url: string
}

export interface VulnerabilityData {
  id: string
  title: string
  description: string
  severity: VulnerabilitySeverity
  cvss?: number
  cvssVector?: string
  cwe?: string
  affected?: string[]
  published?: Date | string
  modified?: Date | string
  references?: VulnerabilityReference[]
  status?: VulnerabilityStatus
  tags?: string[]
}

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

const SEVERITY_LABELS: Record<VulnerabilitySeverity, string> = {
  critical: 'Critical',
  high: 'High',
  medium: 'Medium',
  low: 'Low',
  info: 'Info',
}

const STATUS_LABELS: Record<VulnerabilityStatus, string> = {
  open: 'Open',
  in_progress: 'In Progress',
  resolved: 'Resolved',
  accepted: 'Accepted',
  false_positive: 'False Positive',
}

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

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

const severityBadgeVariants = cva(
  'inline-flex items-center rounded-full px-2.5 py-0.5 text-[11px] font-bold shrink-0',
  {
    variants: {
      severity: {
        critical: 'bg-accent-rose/20 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',
    },
  }
)

const statusBadgeVariants = cva(
  'inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium shrink-0',
  {
    variants: {
      status: {
        open: 'bg-accent-rose/10 text-accent-rose',
        in_progress: 'bg-accent-amber/10 text-accent-amber',
        resolved: 'bg-accent-emerald/10 text-accent-emerald',
        accepted: 'bg-accent-cyan/10 text-accent-cyan',
        false_positive: 'bg-foreground-muted/10 text-foreground-muted',
      },
    },
    defaultVariants: {
      status: 'open',
    },
  }
)

/* ------------------------------------------------------------------ */
/*  VulnerabilityCard                                                  */
/* ------------------------------------------------------------------ */

export interface VulnerabilityCardProps extends Omit<React.ComponentProps<'div'>, 'onClick'> {
  data: VulnerabilityData
  /** Compact mode truncates description and collapses references. */
  compact?: boolean
  /** Show the references section. Defaults to true. */
  showReferences?: boolean
  /** Callback when the card is clicked. */
  onClick?: ((data: VulnerabilityData) => void) | undefined
}

function VulnerabilityCard({
  className,
  data,
  compact = false,
  showReferences = true,
  onClick,
  ...props
}: VulnerabilityCardProps) {
  const [refsExpanded, setRefsExpanded] = React.useState(false)

  const description =
    compact && data.description.length > 150
      ? data.description.slice(0, 150) + '...'
      : data.description

  const hasRefs = showReferences && data.references && data.references.length > 0

  return (
    <div
      data-slot="vulnerability-card"
      className={cn(
        'flex flex-col gap-3 rounded-xl border border-border-glass bg-glass p-5 backdrop-blur-[20px]',
        'transition-all duration-300 hover:shadow-glow',
        onClick && 'cursor-pointer',
        className
      )}
      onClick={onClick ? () => onClick(data) : undefined}
      {...props}
    >
      {/* Header */}
      <div className="flex flex-wrap items-center gap-2">
        <span className={severityBadgeVariants({ severity: data.severity })}>
          {SEVERITY_LABELS[data.severity]}
        </span>
        <span className="text-sm font-bold font-mono text-foreground">{data.id}</span>
        <span className="flex-1 truncate text-sm font-medium text-foreground-secondary">
          {data.title}
        </span>
        {data.status && (
          <span className={statusBadgeVariants({ status: data.status })}>
            {STATUS_LABELS[data.status]}
          </span>
        )}
      </div>

      {/* Description */}
      <p
        className="text-xs leading-relaxed text-foreground-secondary"
        title={compact && data.description.length > 150 ? data.description : undefined}
      >
        {description}
      </p>

      {/* CVSS row */}
      {data.cvss !== undefined && (
        <div className="flex items-center gap-2">
          <span className="text-xs font-medium text-foreground-muted">CVSS:</span>
          <span className="text-xs font-bold tabular-nums text-foreground">
            {data.cvss.toFixed(1)}
          </span>
          {data.cvssVector && (
            <span
              className="max-w-[200px] truncate text-[11px] font-mono text-foreground-muted"
              title={data.cvssVector}
            >
              {data.cvssVector}
            </span>
          )}
        </div>
      )}

      {/* CWE */}
      {data.cwe && (
        <div>
          <a
            href={`https://cwe.mitre.org/data/definitions/${data.cwe.replace('CWE-', '')}.html`}
            target="_blank"
            rel="noopener noreferrer"
            className="text-xs font-mono text-accent-cyan hover:underline"
            onClick={e => e.stopPropagation()}
          >
            {data.cwe}
          </a>
        </div>
      )}

      {/* Metadata */}
      <div className="flex flex-wrap items-center gap-x-4 gap-y-1 text-[11px] text-foreground-muted">
        {data.published && <span>Published: {formatDate(data.published)}</span>}
        {data.modified && <span>Modified: {formatDate(data.modified)}</span>}
      </div>

      {/* Affected components */}
      {data.affected && data.affected.length > 0 && (
        <div className="flex flex-wrap items-center gap-1.5">
          <span className="text-xs font-medium text-foreground-muted">Affected:</span>
          {data.affected.map(comp => (
            <span
              key={comp}
              className="rounded-full border border-border-glass bg-surface-secondary px-2 py-0.5 text-[10px] text-foreground-secondary"
            >
              {comp}
            </span>
          ))}
        </div>
      )}

      {/* Tags */}
      {data.tags && data.tags.length > 0 && (
        <div className="flex flex-wrap gap-1">
          {data.tags.map(tag => (
            <span
              key={tag}
              className="rounded-full border border-accent-violet/20 bg-accent-violet/5 px-2 py-0.5 text-[10px] font-medium text-accent-violet"
            >
              {tag}
            </span>
          ))}
        </div>
      )}

      {/* References */}
      {hasRefs && (
        <div className="flex flex-col gap-2 border-t border-border-glass pt-3">
          {compact ? (
            <>
              <button
                type="button"
                className="text-left text-xs font-medium text-accent-cyan hover:underline"
                onClick={e => {
                  e.stopPropagation()
                  setRefsExpanded(!refsExpanded)
                }}
              >
                {refsExpanded
                  ? `Hide References (${data.references!.length})`
                  : `Show References (${data.references!.length})`}
              </button>
              {refsExpanded && <ReferenceList references={data.references!} />}
            </>
          ) : (
            <>
              <div className="text-xs font-medium text-foreground-secondary">
                References ({data.references!.length})
              </div>
              <ReferenceList references={data.references!} />
            </>
          )}
        </div>
      )}
    </div>
  )
}

/* ------------------------------------------------------------------ */
/*  ReferenceList                                                      */
/* ------------------------------------------------------------------ */

function ReferenceList({ references }: { references: VulnerabilityReference[] }) {
  return (
    <ul className="flex flex-col gap-1">
      {references.map(ref => (
        <li key={ref.url}>
          <a
            href={ref.url}
            target="_blank"
            rel="noopener noreferrer"
            className="text-xs text-accent-cyan hover:underline"
            onClick={e => e.stopPropagation()}
          >
            {ref.title}
          </a>
        </li>
      ))}
    </ul>
  )
}

export { VulnerabilityCard, severityBadgeVariants, statusBadgeVariants }
