import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { z } from 'zod'
import { api, ApiError } from '../client'
import type { SBOMReport } from '../../types/api'

const sbomReportSchema = z.object({
  id: z.number(),
  repoId: z.number(),
  runId: z.number(),
  sha: z.string(),
  format: z.string(),
  componentCount: z.number(),
  generatedAt: z.string(),
})

/** SBOM metadata for a specific pipeline run. */
export function useRunSBOM(owner: string, repo: string, runId: number) {
  return useQuery<SBOMReport | null>({
    queryKey: ['repos', owner, repo, 'runs', runId, 'sbom'],
    queryFn: async () => {
      try {
        return await api.get<SBOMReport>(
          `/api/v1/repos/${owner}/${repo}/runs/${runId}/sbom`,
          sbomReportSchema,
        )
      } catch (err) {
        if (err instanceof ApiError && err.status === 404) return null
        throw err
      }
    },
    enabled: Boolean(owner && repo && runId),
    retry: false,
  })
}

/** Latest SBOM metadata for a repo. */
export function useLatestSBOM(owner: string, repo: string) {
  return useQuery({
    queryKey: ['repos', owner, repo, 'sbom'],
    queryFn: () =>
      api.get<SBOMReport>(
        `/api/v1/repos/${owner}/${repo}/sbom`,
        sbomReportSchema,
      ),
    enabled: Boolean(owner && repo),
    retry: false,
  })
}

/** Download SBOM document URL for a specific run. */
export function getRunSBOMDocumentURL(owner: string, repo: string, runId: number): string {
  return `/api/v1/repos/${owner}/${repo}/runs/${runId}/sbom/document`
}

/** Download latest SBOM document URL. */
export function getLatestSBOMDocumentURL(owner: string, repo: string): string {
  return `/api/v1/repos/${owner}/${repo}/sbom/document`
}

/** Trigger on-demand SBOM generation. */
export function useGenerateSBOM(owner: string, repo: string) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ ref, runId }: { ref: string; runId?: number }) => {
      let url = `/api/v1/repos/${owner}/${repo}/sbom/generate?ref=${encodeURIComponent(ref)}`
      if (runId) url += `&runID=${runId}`
      return api.post<SBOMReport>(url, sbomReportSchema, undefined)
    },
    onSuccess: (data, { runId }) => {
      qc.setQueryData(['repos', owner, repo, 'sbom'], data)
      if (runId) {
        qc.setQueryData(['repos', owner, repo, 'runs', runId, 'sbom'], data)
      }
    },
  })
}
