"use client"

import { useQuery, keepPreviousData } from "@tanstack/react-query"

import { VulnerabilityService } from "@/services/vulnerability.service"
import type {
  Vulnerability,
  VulnerabilitySeverity,
  GetVulnerabilitiesParams,
} from "@/types/vulnerability.types"
import type { PaginationInfo } from "@/types/common.types"

export const vulnerabilityKeys = {
  all: ["vulnerabilities"] as const,
  list: (params: GetVulnerabilitiesParams, filter?: string) =>
    [...vulnerabilityKeys.all, "list", params, filter] as const,
  byScan: (scanId: number, params: GetVulnerabilitiesParams, filter?: string) =>
    [...vulnerabilityKeys.all, "scan", scanId, params, filter] as const,
  byTarget: (targetId: number, params: GetVulnerabilitiesParams, filter?: string) =>
    [...vulnerabilityKeys.all, "target", targetId, params, filter] as const,
}

/** 获取所有漏洞 */
export function useAllVulnerabilities(
  params?: GetVulnerabilitiesParams,
  options?: { enabled?: boolean },
  filter?: string,
) {
  const defaultParams: GetVulnerabilitiesParams = {
    page: 1,
    pageSize: 10,
    ...params,
  }

  return useQuery({
    queryKey: vulnerabilityKeys.list(defaultParams, filter),
    queryFn: () => VulnerabilityService.getAllVulnerabilities(defaultParams, filter),
    enabled: options?.enabled ?? true,
    select: (response: any) => {
      const items = (response?.results ?? []) as any[]

      const vulnerabilities: Vulnerability[] = items.map((item) => {
        let severity = (item.severity || "info") as
          | VulnerabilitySeverity
          | "unknown"
        if (severity === "unknown") {
          severity = "info"
        }

        let cvssScore: number | undefined
        if (typeof item.cvssScore === "number") {
          cvssScore = item.cvssScore
        } else if (item.cvssScore != null) {
          const num = Number(item.cvssScore)
          cvssScore = Number.isNaN(num) ? undefined : num
        }

        const createdAt: string = item.createdAt

        return {
          id: item.id,
          vulnType: item.vulnType || "unknown",
          url: item.url || "",
          description: item.description || "",
          severity: severity as VulnerabilitySeverity,
          source: item.source || "scan",
          cvssScore,
          rawOutput: item.rawOutput || {},
          createdAt,
        }
      })

      const pagination: PaginationInfo = {
        total: response?.total ?? 0,
        page: response?.page ?? defaultParams.page ?? 1,
        pageSize:
          response?.pageSize ??
          response?.page_size ??
          defaultParams.pageSize ??
          10,
        totalPages:
          response?.totalPages ??
          response?.total_pages ??
          0,
      }

      return { vulnerabilities, pagination }
    },
    placeholderData: keepPreviousData,
  })
}

export function useScanVulnerabilities(
  scanId: number,
  params?: GetVulnerabilitiesParams,
  options?: { enabled?: boolean },
  filter?: string,
) {
  const defaultParams: GetVulnerabilitiesParams = {
    page: 1,
    pageSize: 10,
    ...params,
  }

  return useQuery({
    queryKey: vulnerabilityKeys.byScan(scanId, defaultParams, filter),
    queryFn: () =>
      VulnerabilityService.getVulnerabilitiesByScanId(scanId, defaultParams, filter),
    enabled: options?.enabled !== undefined ? options.enabled : !!scanId,
    select: (response: any) => {
      const items = (response?.results ?? []) as any[]

      const vulnerabilities: Vulnerability[] = items.map((item) => {
        let severity = (item.severity || "info") as
          | VulnerabilitySeverity
          | "unknown"
        if (severity === "unknown") {
          severity = "info"
        }

        let cvssScore: number | undefined
        if (typeof item.cvssScore === "number") {
          cvssScore = item.cvssScore
        } else if (item.cvssScore != null) {
          const num = Number(item.cvssScore)
          cvssScore = Number.isNaN(num) ? undefined : num
        }

        const createdAt: string = item.createdAt

        return {
          id: item.id,
          vulnType: item.vulnType || "unknown",
          url: item.url || "",
          description: item.description || "",
          severity: severity as VulnerabilitySeverity,
          source: item.source || "scan",
          cvssScore,
          rawOutput: item.rawOutput || {},
          createdAt,
        }
      })

      const pagination: PaginationInfo = {
        total: response?.total ?? 0,
        page: response?.page ?? defaultParams.page ?? 1,
        pageSize:
          response?.pageSize ??
          response?.page_size ??
          defaultParams.pageSize ??
          10,
        totalPages:
          response?.totalPages ??
          response?.total_pages ??
          0,
      }

      return { vulnerabilities, pagination }
    },
    placeholderData: keepPreviousData,
  })
}

export function useTargetVulnerabilities(
  targetId: number,
  params?: GetVulnerabilitiesParams,
  options?: { enabled?: boolean },
  filter?: string,
) {
  const defaultParams: GetVulnerabilitiesParams = {
    page: 1,
    pageSize: 10,
    ...params,
  }

  return useQuery({
    queryKey: vulnerabilityKeys.byTarget(targetId, defaultParams, filter),
    queryFn: () =>
      VulnerabilityService.getVulnerabilitiesByTargetId(targetId, defaultParams, filter),
    enabled: options?.enabled !== undefined ? options.enabled : !!targetId,
    select: (response: any) => {
      const items = (response?.results ?? []) as any[]

      const vulnerabilities: Vulnerability[] = items.map((item) => {
        let severity = (item.severity || "info") as
          | VulnerabilitySeverity
          | "unknown"
        if (severity === "unknown") {
          severity = "info"
        }

        let cvssScore: number | undefined
        if (typeof item.cvssScore === "number") {
          cvssScore = item.cvssScore
        } else if (item.cvssScore != null) {
          const num = Number(item.cvssScore)
          cvssScore = Number.isNaN(num) ? undefined : num
        }

        const createdAt: string = item.createdAt

        return {
          id: item.id,
          vulnType: item.vulnType || "unknown",
          url: item.url || "",
          description: item.description || "",
          severity: severity as VulnerabilitySeverity,
          source: item.source || "scan",
          target: item.target ?? targetId,
          cvssScore,
          rawOutput: item.rawOutput || {},
          createdAt,
        }
      })

      const pagination: PaginationInfo = {
        total: response?.total ?? 0,
        page: response?.page ?? defaultParams.page ?? 1,
        pageSize:
          response?.pageSize ??
          response?.page_size ??
          defaultParams.pageSize ??
          10,
        totalPages:
          response?.totalPages ??
          response?.total_pages ??
          0,
      }

      return { vulnerabilities, pagination }
    },
    placeholderData: keepPreviousData,
  })
}
