import { api } from './client'

export type OntologyLayer = 'M3' | 'M2' | 'M1' | 'M0'
export type OntologyProfile = 'meta' | 'upper' | 'business' | 'software' | 'governance' | 'cross'

export interface GovernanceProject {
  id: string
  name: string
  description: string
  namespace: string
  version: string
  status: string
  updated_at: string
}

export interface OntologyElement {
  id: string
  project_id: string
  uri: string
  layer: OntologyLayer
  profile: OntologyProfile
  kind: string
  name: string
  description: string
  status: 'candidate' | 'published' | 'deprecated' | 'retired'
  version: string
  attributes: Record<string, unknown>
  source: string
}

export interface GovernanceAssertion {
  id: string
  subject_id: string
  subject_name?: string
  predicate: string
  object_id?: string
  object_name?: string
  object_value: string
  assertion_type: 'declared' | 'extracted' | 'observed' | 'inferred'
  confidence: number
  evidence_ids: string[]
  generated_by: string
  valid_from?: string
  valid_to?: string
  review_status: 'pending' | 'accepted' | 'rejected' | 'expired'
  reviewer: string
  review_note: string
  updated_at: string
}

export interface GovernanceIssue {
  id: string
  rule_id: string
  target_id: string
  assertion_id: string
  severity: 'low' | 'medium' | 'high' | 'critical'
  title: string
  description: string
  status: 'open' | 'acknowledged' | 'resolved' | 'waived'
  assigned_to: string
  evidence_ids: string[]
}

export interface GovernanceRule {
  id: string
  name: string
  description: string
  rule_type: string
  severity: string
  expression: Record<string, unknown>
  enabled: boolean
}

export interface GovernanceEvidence {
  id: string
  kind: string
  uri: string
  title: string
  content: string
  content_hash: string
  source: string
  observed_at: string
  valid_from?: string
  valid_to?: string
  metadata: Record<string, unknown>
  created_at: string
}

export interface GovernanceOverview {
  project: GovernanceProject
  layers: Record<OntologyLayer, number>
  profiles: Record<OntologyProfile, number>
  totals: {
    elements: number
    assertions: number
    pending_reviews: number
    evidence: number
    rules: number
    open_issues: number
    agent_runs: number
  }
}

export interface GovernanceGraph {
  nodes: OntologyElement[]
  edges: GovernanceAssertion[]
}

export interface ValidationResult {
  valid: boolean
  findings: Array<{
    code: string
    severity: string
    title: string
    description: string
    target_id: string
    assertion_id: string
  }>
  counts: Record<string, number>
  checked: { elements: number; assertions: number }
}

export interface GovernanceAgentRun {
  id: string
  source_type: string
  status: string
  result_json: Record<string, unknown>
  trace_json: Array<{ term_name: string; duration_ms: number }>
  error: string
  created_at: string
  completed_at?: string
}

function qs(params: Record<string, string | number | boolean | undefined>) {
  const search = new URLSearchParams()
  Object.entries(params).forEach(([key, value]) => {
    if (value !== undefined && value !== '') search.set(key, String(value))
  })
  const encoded = search.toString()
  return encoded ? `?${encoded}` : ''
}

export const governanceApi = {
  projects: (): Promise<{ projects: GovernanceProject[] }> => api.get('/governance/projects'),
  createProject: (body: { name: string; description: string; namespace: string }): Promise<GovernanceProject> =>
    api.post('/governance/projects', body),
  bootstrap: (): Promise<{ project: GovernanceProject; overview: GovernanceOverview; validation: ValidationResult }> =>
    api.post('/governance/bootstrap/tenant-isolation'),
  overview: (projectId: string): Promise<GovernanceOverview> =>
    api.get(`/governance/projects/${projectId}/overview`),
  elements: (projectId: string, filters: { layer?: string; profile?: string; q?: string } = {}): Promise<{ items: OntologyElement[]; total: number }> =>
    api.get(`/governance/projects/${projectId}/elements${qs({ ...filters, limit: 500 })}`),
  graph: (projectId: string): Promise<GovernanceGraph> =>
    api.get(`/governance/projects/${projectId}/graph?limit=500&include_pending=true`),
  evidence: (projectId: string): Promise<{ evidence: GovernanceEvidence[] }> =>
    api.get(`/governance/projects/${projectId}/evidence?limit=500`),
  impact: (elementId: string): Promise<{ center: OntologyElement; nodes: Array<OntologyElement & { distance: number }>; edges: GovernanceAssertion[] }> =>
    api.get(`/governance/elements/${elementId}/impact?max_depth=4`),
  assertions: (projectId: string, reviewStatus = ''): Promise<{ assertions: GovernanceAssertion[] }> =>
    api.get(`/governance/projects/${projectId}/assertions${qs({ review_status: reviewStatus, limit: 500 })}`),
  reviewAssertion: (assertionId: string, status: 'accepted' | 'rejected', reviewer: string, note = ''): Promise<GovernanceAssertion> =>
    api.post(`/governance/assertions/${assertionId}/review`, { status, reviewer, note }),
  issues: (projectId: string, status = 'open'): Promise<{ issues: GovernanceIssue[] }> =>
    api.get(`/governance/projects/${projectId}/issues${qs({ status })}`),
  updateIssue: (issueId: string, status: GovernanceIssue['status'], assignedTo = ''): Promise<GovernanceIssue> =>
    api.put(`/governance/issues/${issueId}`, { status, assigned_to: assignedTo }),
  rules: (projectId: string): Promise<{ rules: GovernanceRule[] }> =>
    api.get(`/governance/projects/${projectId}/rules`),
  validate: (projectId: string): Promise<ValidationResult> =>
    api.post(`/governance/projects/${projectId}/validate`),
  agentRuns: (projectId: string): Promise<{ runs: GovernanceAgentRun[] }> =>
    api.get(`/governance/projects/${projectId}/agent-runs`),
  analyze: (projectId: string, body: { source_type: string; content: string; source_name: string; environment: string; persist: boolean }) =>
    api.post<{
      run_id: string
      status: string
      result: { summary: { elements: number; assertions: number; issues: number }; agents: string[] }
      trace: Array<{ term_name: string; duration_ms: number }>
    }>(`/governance/projects/${projectId}/agent-runs/analyze`, body),
}
