import adminClient from "./client"
import type { ApiResponse } from "../../types"

export type DiagnosticStatus = "ok" | "warning" | "error" | "disabled"
export type DiagnosticIssueLevel = "error" | "warning"

export interface DiagnosticAction {
  label: string
  path: string
}

export interface PluginDiagnosticSummary {
  generated_at: string
  total_plugins: number
  notification_plugins: number
  provision_plugins: number
  enabled_plugins: number
  issue_count: number
  error_count: number
  warning_count: number
  recent_failed_instances: number
  pending_redirect_verifications: number
  product_binding_issues: number
  plaintext_secret_count: number
}

export interface PluginLite {
  id: string
  type?: string
  name?: string
  version?: string
  provider?: string
  enabled?: boolean
  current?: boolean
  capabilities?: string[]
}

export interface MissingField {
  plugin_id?: string
  plugin_name?: string
  key: string
  label: string
}

export interface NotificationChannelDiagnostic {
  type: string
  label: string
  status: DiagnosticStatus
  total_plugins: number
  enabled_count: number
  current_count: number
  current_plugins: PluginLite[]
  enabled_plugins: PluginLite[]
  missing_required: MissingField[]
  warnings: string[]
  actions: DiagnosticAction[]
}

export interface ProvisionPluginDiagnostic {
  id: string
  name: string
  version?: string | null
  status?: string | null
  capabilities: string[]
  interface_count: number
  enabled_interface_count: number
  product_count: number
  active_product_count: number
  config_field_count: number
  purchase_field_count: number
  manage_action_count: number
}

export interface ProvisionInterfaceDiagnostic {
  id: number
  name: string
  plugin_id: string
  plugin_name: string
  enabled: boolean
  status: DiagnosticStatus
  missing_required: MissingField[]
  warnings: string[]
  last_test_ok?: boolean | null
  last_test_message?: string | null
  updated_at?: string | null
}

export interface ProductBindingIssue {
  product_id: number
  product_name: string
  sku: string
  status: string
  auto_provision: boolean
  plugin_id?: string | null
  interface_id?: number | null
  issues: string[]
}

export interface RecentProvisionFailure {
  instance_id: number
  product_id: number
  product_name: string
  plugin_id?: string | null
  order_id: number
  out_order_no: string
  user_id: number
  username: string
  status: string
  status_label: string
  attempts: number
  last_provision_at?: string | null
  updated_at?: string | null
  provision_log?: string | null
}

export interface ProvisionDiagnostics {
  summary: {
    plugin_count: number
    interface_count: number
    enabled_interfaces: number
    product_count: number
    active_product_count: number
    product_binding_issues: number
    failed_instances: number
    stuck_provisioning: number
  }
  plugins: ProvisionPluginDiagnostic[]
  interfaces: ProvisionInterfaceDiagnostic[]
  product_issues: ProductBindingIssue[]
  recent_failures: RecentProvisionFailure[]
  instance_status_counts: Record<string, number>
  actions: DiagnosticAction[]
}

export interface VerificationRecordDiagnostic {
  id: number
  user_id: number
  username: string
  provider: string
  mode: string
  status: string
  external_id?: string | null
  created_at?: string | null
  updated_at?: string | null
}

export interface VerificationDiagnostics {
  pending_redirect: number
  processing_records: VerificationRecordDiagnostic[]
  status_counts: Record<string, number>
  actions: DiagnosticAction[]
}

export interface SecretDiagnosticItem {
  scope: "system_setting" | "provision_interface" | string
  key: string
  label: string
  plugin?: string | null
  interface_id?: number
  interface_name?: string
  status: "encrypted" | "plaintext" | "empty" | string
}

export interface SecurityDiagnostics {
  secret_count: number
  encrypted_secret_count: number
  plaintext_secret_count: number
  items: SecretDiagnosticItem[]
}

export interface PluginDiagnosticWarning {
  level: DiagnosticIssueLevel
  scope: string
  message: string
  suggestion?: string | null
  path?: string
}

export interface PluginDiagnostics {
  summary: PluginDiagnosticSummary
  warnings: PluginDiagnosticWarning[]
  channels: NotificationChannelDiagnostic[]
  provision: ProvisionDiagnostics
  verification: VerificationDiagnostics
  security: SecurityDiagnostics
}

function arrayValue<T>(value: unknown): T[] {
  return Array.isArray(value) ? value as T[] : []
}

function recordValue(value: unknown): Record<string, number> {
  if (!value || typeof value !== "object" || Array.isArray(value)) return {}
  return value as Record<string, number>
}

function numberValue(value: unknown): number {
  const n = Number(value ?? 0)
  return Number.isFinite(n) ? n : 0
}

function normalizePluginDiagnostics(value: PluginDiagnostics | null): PluginDiagnostics {
  const data = (value ?? {}) as Partial<PluginDiagnostics>
  const summary = (data.summary ?? {}) as Partial<PluginDiagnosticSummary>
  const provision = (data.provision ?? {}) as Partial<ProvisionDiagnostics>
  const provisionSummary = (provision.summary ?? {}) as Partial<ProvisionDiagnostics["summary"]>
  const verification = (data.verification ?? {}) as Partial<VerificationDiagnostics>
  const security = (data.security ?? {}) as Partial<SecurityDiagnostics>

  return {
    summary: {
      generated_at: summary.generated_at ?? "",
      total_plugins: numberValue(summary.total_plugins),
      notification_plugins: numberValue(summary.notification_plugins),
      provision_plugins: numberValue(summary.provision_plugins),
      enabled_plugins: numberValue(summary.enabled_plugins),
      issue_count: numberValue(summary.issue_count),
      error_count: numberValue(summary.error_count),
      warning_count: numberValue(summary.warning_count),
      recent_failed_instances: numberValue(summary.recent_failed_instances),
      pending_redirect_verifications: numberValue(summary.pending_redirect_verifications),
      product_binding_issues: numberValue(summary.product_binding_issues),
      plaintext_secret_count: numberValue(summary.plaintext_secret_count),
    },
    warnings: arrayValue<PluginDiagnosticWarning>(data.warnings),
    channels: arrayValue<NotificationChannelDiagnostic>(data.channels).map((channel) => ({
      ...channel,
      current_plugins: arrayValue<PluginLite>(channel.current_plugins),
      enabled_plugins: arrayValue<PluginLite>(channel.enabled_plugins),
      missing_required: arrayValue<MissingField>(channel.missing_required),
      warnings: arrayValue<string>(channel.warnings),
      actions: arrayValue<DiagnosticAction>(channel.actions),
    })),
    provision: {
      summary: {
        plugin_count: numberValue(provisionSummary.plugin_count),
        interface_count: numberValue(provisionSummary.interface_count),
        enabled_interfaces: numberValue(provisionSummary.enabled_interfaces),
        product_count: numberValue(provisionSummary.product_count),
        active_product_count: numberValue(provisionSummary.active_product_count),
        product_binding_issues: numberValue(provisionSummary.product_binding_issues),
        failed_instances: numberValue(provisionSummary.failed_instances),
        stuck_provisioning: numberValue(provisionSummary.stuck_provisioning),
      },
      plugins: arrayValue<ProvisionPluginDiagnostic>(provision.plugins).map((plugin) => ({
        ...plugin,
        capabilities: arrayValue<string>(plugin.capabilities),
      })),
      interfaces: arrayValue<ProvisionInterfaceDiagnostic>(provision.interfaces).map((item) => ({
        ...item,
        missing_required: arrayValue<MissingField>(item.missing_required),
        warnings: arrayValue<string>(item.warnings),
      })),
      product_issues: arrayValue<ProductBindingIssue>(provision.product_issues).map((item) => ({
        ...item,
        issues: arrayValue<string>(item.issues),
      })),
      recent_failures: arrayValue<RecentProvisionFailure>(provision.recent_failures),
      instance_status_counts: recordValue(provision.instance_status_counts),
      actions: arrayValue<DiagnosticAction>(provision.actions),
    },
    verification: {
      pending_redirect: numberValue(verification.pending_redirect),
      processing_records: arrayValue<VerificationRecordDiagnostic>(verification.processing_records),
      status_counts: recordValue(verification.status_counts),
      actions: arrayValue<DiagnosticAction>(verification.actions),
    },
    security: {
      secret_count: numberValue(security.secret_count),
      encrypted_secret_count: numberValue(security.encrypted_secret_count),
      plaintext_secret_count: numberValue(security.plaintext_secret_count),
      items: arrayValue<SecretDiagnosticItem>(security.items),
    },
  }
}

export async function getPluginDiagnostics(): Promise<ApiResponse<PluginDiagnostics>> {
  const { data } = await adminClient.get<ApiResponse<PluginDiagnostics>>("/v1/admin/settings/plugin-diagnostics")
  return { ...data, data: normalizePluginDiagnostics(data.data) }
}
