import { useState } from 'react'
import { useParams, Link } from 'react-router-dom'
import { useSecretLeaks, useDismissSecretLeak } from '../api/queries/security'
import { useVulnerabilities, useScanVulnerabilities, useDismissVulnerability } from '../api/queries/security'
import { useLatestSBOM, useGenerateSBOM, getLatestSBOMDocumentURL } from '../api/queries/sbom'
import { Skeleton } from '../ui/Skeleton'
import { cn } from '../lib/utils'

const SEVERITY_COLORS: Record<string, string> = {
  critical: 'bg-red-100 text-red-800 dark:bg-red-900/40 dark:text-red-300',
  high:     'bg-orange-100 text-orange-800 dark:bg-orange-900/40 dark:text-orange-300',
  medium:   'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-300',
  low:      'bg-green-100 text-green-800 dark:bg-green-900/40 dark:text-green-300',
}

function cvssSeverity(score: number): { label: string; color: string } {
  if (score >= 9) return { label: 'CRITICAL', color: SEVERITY_COLORS.critical }
  if (score >= 7) return { label: 'HIGH', color: SEVERITY_COLORS.high }
  if (score >= 4) return { label: 'MEDIUM', color: SEVERITY_COLORS.medium }
  return { label: 'LOW', color: SEVERITY_COLORS.low }
}

// ── SBOM Section ──────────────────────────────────────────────────────────────

function SBOMSection({ owner, repo }: { owner: string; repo: string }) {
  const { data: sbom, isLoading } = useLatestSBOM(owner, repo)
  const generateSBOM = useGenerateSBOM(owner, repo)
  const [ref, setRef] = useState('main')

  if (isLoading) {
    return (
      <section className="border border-[var(--c-border)] rounded-lg bg-[var(--c-surface)] p-4">
        <Skeleton className="h-5 w-48 rounded" />
      </section>
    )
  }

  if (sbom) {
    return (
      <section className="border border-[var(--c-border)] rounded-lg bg-[var(--c-surface)] p-4">
        <div className="flex items-center justify-between gap-4">
          <div>
            <h2 className="text-xs font-semibold uppercase tracking-wider text-[var(--c-muted)] mb-1">
              SBOM — {sbom.format}
            </h2>
            <div className="flex items-center gap-3 text-xs text-[var(--c-muted)]">
              <span>{sbom.componentCount} components</span>
              <span className="font-mono">{sbom.sha.slice(0, 7)}</span>
              <span>{new Date(sbom.generatedAt).toLocaleString()}</span>
            </div>
          </div>
          <a
            href={getLatestSBOMDocumentURL(owner, repo)}
            download="bom.json"
            className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium border border-[var(--c-border)] rounded-lg text-[var(--c-text)] hover:bg-[var(--c-surface-muted)] transition-colors shrink-0"
          >
            <svg width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
            </svg>
            Download BOM
          </a>
        </div>
      </section>
    )
  }

  return (
    <section className="border border-[var(--c-border)] rounded-lg bg-[var(--c-surface)] p-4">
      <div className="flex items-center justify-between gap-4 flex-wrap">
        <div>
          <h2 className="text-xs font-semibold uppercase tracking-wider text-[var(--c-muted)] mb-1">
            SBOM
          </h2>
          <p className="text-xs text-[var(--c-muted)]">
            No SBOM generated yet. Generate one to enable vulnerability scanning.
          </p>
        </div>
        <div className="flex items-center gap-2">
          <input
            value={ref}
            onChange={e => setRef(e.target.value)}
            placeholder="branch or SHA"
            className="w-36 px-2.5 py-1.5 text-xs border border-[var(--c-border)] rounded-lg bg-[var(--c-surface-muted)] text-[var(--c-text)] placeholder:text-[var(--c-muted)] focus:outline-none focus:border-[var(--c-brand-focus)] font-mono"
          />
          <button
            onClick={() => generateSBOM.mutate({ ref })}
            disabled={generateSBOM.isPending || !ref.trim()}
            className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium bg-[var(--c-brand)] hover:bg-[var(--c-brand-hover)] text-white rounded-lg transition-colors disabled:opacity-50 shrink-0"
          >
            {generateSBOM.isPending ? 'Generating…' : 'Generate SBOM'}
          </button>
        </div>
      </div>
      {generateSBOM.isError && (
        <p className="mt-2 text-xs text-[var(--c-danger)]">{(generateSBOM.error as Error).message}</p>
      )}
    </section>
  )
}

// ── Secret Leaks Section ──────────────────────────────────────────────────────

function SecretLeaksSection({ owner, repo }: { owner: string; repo: string }) {
  const { data: leaks, isLoading } = useSecretLeaks(owner, repo)
  const dismissLeak = useDismissSecretLeak(owner, repo)

  return (
    <section className="border border-[var(--c-border)] rounded-lg bg-[var(--c-surface)] overflow-hidden">
      <div className="px-4 py-3 border-b border-[var(--c-border)] bg-[var(--c-surface-raised)] flex items-center justify-between">
        <div className="flex items-center gap-2">
          <svg width="14" height="14" fill="none" stroke="var(--c-danger)" strokeWidth="1.5" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 0 1 21.75 8.25Z" />
          </svg>
          <h2 className="text-sm font-semibold text-[var(--c-text)]">Secret Leaks</h2>
          {!isLoading && leaks && leaks.length > 0 && (
            <span className="text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-[var(--c-danger-tint)] text-[var(--c-danger)]">
              {leaks.length}
            </span>
          )}
        </div>
      </div>

      {isLoading ? (
        <div className="p-4 space-y-3">
          {[1, 2].map(i => <Skeleton key={i} className="h-12 rounded" />)}
        </div>
      ) : !leaks?.length ? (
        <div className="px-4 py-8 text-center text-sm text-[var(--c-muted)]">
          No secret leaks detected.
        </div>
      ) : (
        <div className="divide-y divide-[var(--c-border)]">
          {leaks.map(leak => (
            <div key={leak.id} className="flex items-start gap-3 px-4 py-3">
              <span className={cn(
                'text-[10px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded-full mt-0.5 shrink-0',
                SEVERITY_COLORS[leak.severity] ?? SEVERITY_COLORS.medium,
              )}>
                {leak.severity}
              </span>
              <div className="flex-1 min-w-0">
                <p className="text-sm font-medium text-[var(--c-text)]">{leak.patternName}</p>
                <p className="text-xs text-[var(--c-muted)] mt-0.5">{leak.description}</p>
                <div className="flex items-center gap-2.5 mt-1 text-[10px] text-[var(--c-subtle)] font-mono">
                  <span>{leak.commitSha}</span>
                  <span>{leak.ref.replace('refs/heads/', '')}</span>
                  <span>{new Date(leak.detectedAt).toLocaleDateString()}</span>
                </div>
                {leak.matchSample && (
                  <code className="inline-block mt-1 px-2 py-0.5 bg-[var(--c-surface-muted)] border border-[var(--c-border)] rounded text-[10px] font-mono text-[var(--c-muted)]">
                    {leak.matchSample}
                  </code>
                )}
              </div>
              <button
                onClick={() => dismissLeak.mutate(leak.id)}
                disabled={dismissLeak.isPending}
                className="shrink-0 px-2.5 py-1 text-[10px] font-medium border border-[var(--c-border)] rounded text-[var(--c-muted)] hover:text-[var(--c-text)] hover:bg-[var(--c-surface-muted)] transition-colors disabled:opacity-50"
              >
                Dismiss
              </button>
            </div>
          ))}
        </div>
      )}
    </section>
  )
}

// ── Vulnerabilities Section ───────────────────────────────────────────────────

function VulnerabilitiesSection({ owner, repo }: { owner: string; repo: string }) {
  const { data: findings, isLoading } = useVulnerabilities(owner, repo)
  const scanMut = useScanVulnerabilities(owner, repo)
  const dismissVuln = useDismissVulnerability(owner, repo)
  const { data: sbom } = useLatestSBOM(owner, repo)

  return (
    <section className="border border-[var(--c-border)] rounded-lg bg-[var(--c-surface)] overflow-hidden">
      <div className="px-4 py-3 border-b border-[var(--c-border)] bg-[var(--c-surface-raised)] flex items-center justify-between">
        <div className="flex items-center gap-2">
          <svg width="14" height="14" fill="none" stroke="var(--c-danger)" strokeWidth="1.5" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126Z M12 15.75h.007v.008H12v-.008Z" />
          </svg>
          <h2 className="text-sm font-semibold text-[var(--c-text)]">Vulnerabilities</h2>
          {!isLoading && findings && findings.length > 0 && (
            <span className="text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-[var(--c-danger-tint)] text-[var(--c-danger)]">
              {findings.length}
            </span>
          )}
        </div>
        <div className="flex items-center gap-2">
          {!sbom && (
            <span className="text-[10px] text-[var(--c-muted)]">No SBOM available</span>
          )}
          <button
            onClick={() => scanMut.mutate()}
            disabled={scanMut.isPending || !sbom}
            className="flex items-center gap-1 px-2.5 py-1 text-[10px] font-medium border border-[var(--c-border)] rounded text-[var(--c-text)] hover:bg-[var(--c-surface-muted)] transition-colors disabled:opacity-50"
          >
            <svg width="10" height="10" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
            </svg>
            {scanMut.isPending ? 'Scanning…' : 'Scan now'}
          </button>
        </div>
      </div>

      {scanMut.isError && (
        <div className="px-4 py-2 text-xs text-[var(--c-danger)] bg-[var(--c-danger-tint)]/30">
          Scan failed: {(scanMut.error as Error).message}
        </div>
      )}

      {scanMut.isSuccess && findings && findings.length === 0 && (
        <div className="px-4 py-2 text-xs text-[var(--c-success)] bg-[#E3FCEF] dark:bg-green-900/20">
          Scan complete — no vulnerabilities found.
        </div>
      )}

      {isLoading ? (
        <div className="p-4 space-y-3">
          {[1, 2].map(i => <Skeleton key={i} className="h-16 rounded" />)}
        </div>
      ) : !findings?.length ? (
        <div className="px-4 py-8 text-center text-sm text-[var(--c-muted)]">
          {sbom
            ? 'No vulnerability findings. Run a scan to check dependencies.'
            : 'No SBOM available. Push a commit with a supported manifest (package.json, go.mod, etc.) or trigger a pipeline run to generate one.'}
        </div>
      ) : (
        <div className="divide-y divide-[var(--c-border)]">
          {findings.map(f => {
            const sev = cvssSeverity(f.cvssScore)
            return (
              <div key={f.id} className="flex items-start gap-3 px-4 py-3">
                <span className={cn(
                  'text-[10px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded-full mt-0.5 shrink-0',
                  sev.color,
                )}>
                  {sev.label}
                </span>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2">
                    <span className="text-sm font-medium text-[var(--c-text)]">{f.vulnId}</span>
                    <span className="text-[10px] text-[var(--c-subtle)] font-mono">CVSS {f.cvssScore.toFixed(1)}</span>
                  </div>
                  <p className="text-xs text-[var(--c-text)] mt-0.5">{f.summary}</p>
                  <div className="flex items-center gap-2.5 mt-1 text-[10px] text-[var(--c-subtle)] font-mono">
                    <span>{f.purl}</span>
                    <span>v{f.version}</span>
                    {f.fixedVersion && <span>→ fix: {f.fixedVersion}</span>}
                  </div>
                </div>
                <button
                  onClick={() => dismissVuln.mutate(f.id)}
                  disabled={dismissVuln.isPending}
                  className="shrink-0 px-2.5 py-1 text-[10px] font-medium border border-[var(--c-border)] rounded text-[var(--c-muted)] hover:text-[var(--c-text)] hover:bg-[var(--c-surface-muted)] transition-colors disabled:opacity-50"
                >
                  Dismiss
                </button>
              </div>
            )
          })}
        </div>
      )}
    </section>
  )
}

// ── Page ──────────────────────────────────────────────────────────────────────

export default function RepoSecurityPage() {
  const { owner = '', repo = '' } = useParams()

  return (
    <div className="max-w-4xl mx-auto px-4 md:px-6 py-5 space-y-6">
      {/* Breadcrumb */}
      <div>
        <div className="flex items-center gap-1.5 text-xs text-[var(--c-muted)] mb-1">
          <Link to="/repos" className="hover:text-[var(--c-brand)]">Repositories</Link>
          <span>/</span>
          <Link to={`/repos/${owner}/${repo}`} className="hover:text-[var(--c-brand)]">{owner}/{repo}</Link>
          <span>/</span>
          <span className="text-[var(--c-text)]">Security</span>
        </div>
        <h1 className="text-lg font-semibold text-[var(--c-text)]">Security</h1>
        <p className="text-xs text-[var(--c-muted)] mt-0.5">
          Secret leak detection and dependency vulnerability scanning.
        </p>
      </div>

      <SBOMSection owner={owner} repo={repo} />
      <SecretLeaksSection owner={owner} repo={repo} />
      <VulnerabilitiesSection owner={owner} repo={repo} />
    </div>
  )
}
