'use client'

/**
 * Shared SEO UI primitives — token-only, accessible building blocks used across
 * the five SEO tabs. No raw palette colours: status uses the theme's
 * success / warning / destructive / muted tokens.
 */
import type { ReactNode } from 'react'
import { AlertTriangle, Loader2 } from 'lucide-react'
import type { SeoGrade, SeoSeverity } from '../../lib/seo-service.js'

// ─── Grade + severity styling ────────────────────────────────────────

export interface GradeMeta {
  label: string
  text: string
  bg: string
  dot: string
}

export function gradeMeta(grade: SeoGrade): GradeMeta {
  switch (grade) {
    case 'good':
      return { label: 'Good', text: 'text-success', bg: 'bg-success/10', dot: 'bg-success' }
    case 'fair':
      return { label: 'Fair', text: 'text-warning', bg: 'bg-warning/10', dot: 'bg-warning' }
    case 'poor':
      return {
        label: 'Poor',
        text: 'text-destructive',
        bg: 'bg-destructive/10',
        dot: 'bg-destructive',
      }
    default:
      return {
        label: 'Critical',
        text: 'text-destructive',
        bg: 'bg-destructive/15',
        dot: 'bg-destructive',
      }
  }
}

/** Grade band from a numeric 0-100 score. */
export function gradeFromScore(score: number): SeoGrade {
  if (score >= 80) return 'good'
  if (score >= 60) return 'fair'
  if (score >= 1) return 'poor'
  return 'critical'
}

export function severityMeta(severity: SeoSeverity): GradeMeta {
  switch (severity) {
    case 'critical':
      return {
        label: 'Critical',
        text: 'text-destructive',
        bg: 'bg-destructive/10',
        dot: 'bg-destructive',
      }
    case 'warning':
      return { label: 'Warning', text: 'text-warning', bg: 'bg-warning/10', dot: 'bg-warning' }
    default:
      return {
        label: 'Info',
        text: 'text-muted-foreground',
        bg: 'bg-muted',
        dot: 'bg-muted-foreground',
      }
  }
}

// ─── Badges + bars ───────────────────────────────────────────────────

export function SeoStatusBadge({
  label,
  tone,
}: {
  label: string
  tone: 'good' | 'fair' | 'poor' | 'critical' | 'neutral'
}) {
  const cls =
    tone === 'good'
      ? 'bg-success/10 text-success'
      : tone === 'fair'
        ? 'bg-warning/10 text-warning'
        : tone === 'poor' || tone === 'critical'
          ? 'bg-destructive/10 text-destructive'
          : 'bg-muted text-muted-foreground'
  return (
    <span
      className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium ${cls}`}
    >
      <span
        className={`h-1.5 w-1.5 rounded-full ${
          tone === 'good'
            ? 'bg-success'
            : tone === 'fair'
              ? 'bg-warning'
              : tone === 'neutral'
                ? 'bg-muted-foreground'
                : 'bg-destructive'
        }`}
        aria-hidden
      />
      {label}
    </span>
  )
}

/** A horizontal score bar (0-100), coloured by grade. */
export function SeoScoreBar({ score, className = '' }: { score: number; className?: string }) {
  const grade = gradeFromScore(score)
  const fill = grade === 'good' ? 'bg-success' : grade === 'fair' ? 'bg-warning' : 'bg-destructive'
  const clamped = Math.max(0, Math.min(100, Math.round(score)))
  return (
    <div
      className={`bg-muted h-2 w-full overflow-hidden rounded-full ${className}`}
      role="progressbar"
      aria-label="SEO score"
      aria-valuenow={clamped}
      aria-valuemin={0}
      aria-valuemax={100}
      aria-valuetext={`${clamped} out of 100`}
    >
      <div
        className={`h-full rounded-full transition-[width] duration-300 motion-reduce:transition-none ${fill}`}
        style={{ width: `${Math.max(0, Math.min(100, score))}%` }}
      />
    </div>
  )
}

export function ScorePill({ score }: { score: number }) {
  const meta = gradeMeta(gradeFromScore(score))
  return (
    <span
      className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium ${meta.bg} ${meta.text}`}
    >
      <span className={`h-1.5 w-1.5 rounded-full ${meta.dot}`} aria-hidden />
      {score}
    </span>
  )
}

// ─── Layout cards + states ───────────────────────────────────────────

export function SectionCard({
  title,
  description,
  action,
  children,
  className = '',
}: {
  title?: string
  description?: string
  action?: ReactNode
  children: ReactNode
  className?: string
}) {
  return (
    <section className={`border-border bg-card rounded-lg border ${className}`}>
      {(title || action) && (
        <header className="border-border flex items-center justify-between gap-3 border-b px-4 py-3">
          <div className="min-w-0">
            {title && <h3 className="text-foreground text-base font-medium">{title}</h3>}
            {description && <p className="text-muted-foreground mt-0.5 text-sm">{description}</p>}
          </div>
          {action}
        </header>
      )}
      <div className="p-4">{children}</div>
    </section>
  )
}

export function SeoLoading({ label = 'Loading…' }: { label?: string }) {
  return (
    <div className="flex h-64 items-center justify-center" role="status" aria-live="polite">
      <Loader2 className="text-muted-foreground h-6 w-6 animate-spin" aria-hidden />
      <span className="sr-only">{label}</span>
    </div>
  )
}

export function SeoEmptyState({
  icon,
  title,
  description,
  action,
}: {
  icon?: ReactNode
  title: string
  description?: string
  action?: ReactNode
}) {
  return (
    <div className="border-border flex flex-col items-center justify-center rounded-lg border border-dashed px-6 py-12 text-center">
      {icon && (
        <div className="text-muted-foreground mb-3" aria-hidden>
          {icon}
        </div>
      )}
      <h3 className="text-foreground text-base font-medium">{title}</h3>
      {description && <p className="text-muted-foreground mt-1 max-w-md text-sm">{description}</p>}
      {action && <div className="mt-4">{action}</div>}
    </div>
  )
}

export function SeoErrorState({ message, onRetry }: { message: string; onRetry?: () => void }) {
  return (
    <div
      className="border-destructive/30 bg-destructive/5 flex items-center gap-3 rounded-lg border p-3"
      role="alert"
    >
      <AlertTriangle className="text-destructive h-5 w-5 shrink-0" aria-hidden />
      <span className="text-destructive flex-1 text-sm">{message}</span>
      {onRetry && (
        <button
          onClick={onRetry}
          className="border-border text-foreground hover:bg-accent rounded-md border px-3 py-1 text-sm transition-colors"
        >
          Retry
        </button>
      )}
    </div>
  )
}

// ─── Button helpers (token-only) ─────────────────────────────────────

export const btnPrimary =
  'inline-flex items-center justify-center gap-2 rounded-md bg-primary px-4 py-2 text-base font-medium text-primary-foreground transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-60'

export const btnSecondary =
  'inline-flex items-center justify-center gap-2 rounded-md border border-border bg-card px-4 py-2 text-base font-medium text-foreground transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-60'

export const btnGhostIcon =
  'inline-flex items-center justify-center rounded-md p-2 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring'
