'use client'

import React, { useEffect, useState, useCallback, use, useRef } from 'react'

interface SBOMItem {
  id: string
  filename: string
  format: string
  spec_version: string | null
  component_count: number
  summary: Record<string, unknown>
  scan_status: string
  scan_summary: Record<string, unknown>
  uploaded_at: string
  scanned_at: string | null
}

interface SBOMListResponse {
  project_id: string
  total: number
  items: SBOMItem[]
}

export default function SBOMPage({
  params,
}: {
  params: Promise<{ projectId: string }>
}) {
  const { projectId } = use(params)
  const [data, setData] = useState<SBOMListResponse | null>(null)
  const [loading, setLoading] = useState(true)
  const [uploading, setUploading] = useState(false)
  const [error, setError] = useState('')
  const fileRef = useRef<HTMLInputElement>(null)
  const tenant = '9282a473-5c95-4b3a-bf78-0ecc0ec71d3e'

  const load = useCallback(async () => {
    try {
      const res = await fetch(`/api/sdk/v1/cra/projects/${projectId}/sbom`, {
        headers: { 'X-Tenant-ID': tenant },
      })
      if (!res.ok) throw new Error(await res.text())
      setData(await res.json())
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden')
    } finally {
      setLoading(false)
    }
  }, [projectId])

  useEffect(() => { load() }, [load])

  const onUpload = async () => {
    const f = fileRef.current?.files?.[0]
    if (!f) return
    setUploading(true)
    setError('')
    try {
      const fd = new FormData()
      fd.append('file', f)
      const res = await fetch(`/api/sdk/v1/cra/projects/${projectId}/sbom`, {
        method: 'POST',
        headers: { 'X-Tenant-ID': tenant },
        body: fd,
      })
      if (!res.ok) throw new Error(await res.text())
      if (fileRef.current) fileRef.current.value = ''
      await load()
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Upload fehlgeschlagen')
    } finally {
      setUploading(false)
    }
  }

  if (loading) return <div className="min-h-screen bg-gray-50 p-8"><p className="text-gray-500">Laedt...</p></div>

  return (
    <div className="min-h-screen bg-gray-50 py-8">
      <div className="max-w-5xl mx-auto px-4">
        <div className="mb-6">
          <a href={`/sdk/cra/${projectId}`} className="text-sm text-blue-600 hover:underline">
            &larr; Zurueck zum Projekt
          </a>
          <h1 className="text-2xl font-bold text-gray-900 mt-2">SBOM — Software Bill of Materials</h1>
          <p className="text-sm text-gray-600 mt-1">
            CycloneDX oder SPDX hochladen. Verknuepft mit Annex-I Requirement 23 (SBOM-Pflicht).
          </p>
        </div>

        {error && (
          <div className="mb-4 bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-700">
            <pre className="whitespace-pre-wrap">{error}</pre>
            <button onClick={() => setError('')} className="text-red-500 mt-1 underline text-xs">Schliessen</button>
          </div>
        )}

        <div className="bg-white rounded-xl shadow-sm border border-gray-200 p-5 mb-6">
          <h3 className="text-sm font-semibold text-gray-700 mb-3">Neue Version hochladen</h3>
          <div className="flex items-center gap-3">
            <input
              ref={fileRef}
              type="file"
              accept=".json,application/json"
              className="flex-1 text-sm file:mr-3 file:py-1.5 file:px-3 file:rounded file:border-0 file:text-sm file:bg-blue-100 file:text-blue-700 hover:file:bg-blue-200"
            />
            <button
              onClick={onUpload}
              disabled={uploading}
              className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:bg-gray-300 text-sm font-medium"
            >
              {uploading ? 'Laedt hoch...' : 'Upload'}
            </button>
          </div>
          <p className="text-xs text-gray-500 mt-2">
            Format: CycloneDX-JSON (mit <code>bomFormat: &quot;CycloneDX&quot;</code>) oder SPDX-JSON (mit <code>spdxVersion</code>).
            Generieren z.B. via <code>npx @cyclonedx/cyclonedx-npm</code> oder <code>cyclonedx-py</code>.
          </p>
        </div>

        {data && data.items.length === 0 && (
          <div className="bg-gray-100 rounded-xl p-8 text-center text-gray-500">
            Noch kein SBOM hochgeladen.
          </div>
        )}

        {data && data.items.length > 0 && (
          <div className="space-y-3">
            <h3 className="text-sm font-semibold text-gray-700">Versionen ({data.total})</h3>
            {data.items.map(s => (
              <div key={s.id} className="bg-white rounded-xl shadow-sm border border-gray-200 p-4">
                <div className="flex items-center justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                      <span className="font-semibold text-gray-900">{s.filename}</span>
                      <span className="px-2 py-0.5 text-xs rounded bg-blue-100 text-blue-700 uppercase">{s.format}</span>
                      {s.spec_version && (
                        <span className="text-xs text-gray-500">v{s.spec_version}</span>
                      )}
                    </div>
                    <div className="text-xs text-gray-500 mt-1">
                      {s.component_count} Komponenten · hochgeladen {new Date(s.uploaded_at).toLocaleString('de-DE')}
                    </div>
                  </div>
                  <span className={`px-2 py-1 text-xs rounded-full ${
                    s.scan_status === 'scanned' ? 'bg-green-100 text-green-700' :
                    s.scan_status === 'failed' ? 'bg-red-100 text-red-700' :
                    'bg-gray-100 text-gray-600'
                  }`}>
                    Scan: {s.scan_status}
                  </span>
                </div>
                {s.summary && Object.keys(s.summary).length > 0 && (
                  <details className="mt-3 text-xs">
                    <summary className="cursor-pointer text-gray-600 hover:text-gray-900">Summary-Details</summary>
                    <pre className="mt-2 p-2 bg-gray-50 rounded overflow-x-auto text-xs">{JSON.stringify(s.summary, null, 2)}</pre>
                  </details>
                )}
              </div>
            ))}
          </div>
        )}

        <div className="mt-6 bg-blue-50 border border-blue-200 rounded-xl p-4 text-sm text-blue-900">
          <strong>Hinweis:</strong> Der osv.dev-Vulnerability-Scan wird durch ein separates Tool im Team durchgefuehrt.
          Diese Seite akzeptiert SBOM-Uploads und persistiert sie versioniert.
        </div>
      </div>
    </div>
  )
}
