// API Response Types for StemeDB Dashboard

export interface HealthResponse {
  status: string;
  version: string;
  assertions_count: number;
}

export interface SourceMetadata {
  label: string;
  tier: number;
  tier_label: string;
  url?: string;
  status: string;
}

export interface SourceSummary {
  source_hash: string;
  visual_hash?: string;
  source_metadata?: SourceMetadata;
}

export interface AgentSummary {
  agent_id: string;
  trust_score: number;
}

export interface ClaimSummary {
  value: { type: string; value: string | number | boolean };
  weight_share: number;
  assertion_count: number;
  representative_hash: string;
  source: SourceSummary;
  supporting_agents: AgentSummary[];
}

export interface SkepticResponse {
  subject: string;
  predicate: string;
  status: "Unanimous" | "Agreed" | "Contested";
  conflict_score: number;
  claims: ClaimSummary[];
  candidates_count: number;
  computed_at: number;
  lens_name: string;
}

// Assertion object returned by API
export interface AssertionObject {
  hash: string;
  subject: string;
  predicate: string;
  object: { type: string; value: string | number | boolean };
  source_hash: string;
  source_class: string;
  lifecycle: string;
  confidence: number;
  timestamp: number;
  signatures: Array<{
    agent_id: string;
    signature: string;
    timestamp: number;
    version: number;
  }>;
}

export interface LayeredTier {
  tier: number;
  source_class: string;
  winner?: AssertionObject;
  candidates_count: number;
  conflict_score: number;
  resolution_confidence: number;
}

export interface LayeredResponse {
  subject: string;
  predicate: string;
  tiers: LayeredTier[];
  overall_winner?: AssertionObject;
  overall_conflict_score: number;
  total_candidates: number;
  computed_at: number;
  lens_name: string;
}

// Quarantine DTOs matching backend
export interface QuarantineEventDto {
  hash: string;
  assertion_bytes_hex?: string;
  assertion_bytes_base64?: string;
  reason: "low_quality" | "duplicate" | "untrusted_high_confidence" | "pattern_match";
  reason_description: string;
  quality: {
    score: number;
    entropy: number;
    structured: boolean;
    duplicate: boolean;
  };
  timestamp: number;
  reviewed: boolean;
  approved?: boolean;
  similar_to?: string;
  agent_id?: string;
}

// Legacy type for backward compatibility with existing components
export interface QuarantinedAssertion {
  hash: string;
  subject: string;
  predicate: string;
  value: string;
  reason: string;
  quarantined_at: number;
  quarantined_by: string;
  can_restore: boolean;
}

// Actual backend response
export interface QuarantineListResponse {
  quarantined: QuarantineEventDto[];
  count: number;
  pending_count: number;
}

// For backward compatibility, also export as QuarantineResponse
export type QuarantineResponse = QuarantineListResponse;

// Circuit breaker DTOs matching backend
export interface CircuitBreakerStatusDto {
  agent_id: string;
  state: "closed" | "open" | "half_open";
  state_name: string;
  failure_count: number;
  trip_count: number;
  last_trip_time?: number;
  last_failure_time?: number;
  retry_after_secs?: number;
  recent_failures: Array<{
    failure_type: "invalid_signature" | "input_validation" | "pow_error" | "quota_exceeded" | "application_error";
    timestamp: number;
  }>;
  failure_counts_by_type: {
    invalid_signature: number;
    input_validation: number;
    pow_error: number;
    quota_exceeded: number;
    application_error: number;
  };
}

// Legacy type for backward compatibility
export interface CircuitBreakerStatus {
  name: string;
  state: "closed" | "open" | "half_open";
  failure_count: number;
  success_count: number;
  last_failure?: string;
  last_state_change: number;
  timeout_seconds: number;
}

// Actual backend response
export interface TrippedCircuitsResponse {
  circuits: CircuitBreakerStatusDto[];
  count: number;
}

// For backward compatibility
export type CircuitBreakerResponse = TrippedCircuitsResponse;

// Query audit types matching backend QueryAuditResponse
export interface QueryParamsAudit {
  subject?: string;
  predicate?: string;
  lifecycle?: string;
  epoch?: string;
  lens?: string;
}

export interface ContributingAssertion {
  assertion_hash: string;
  weight: number;
  source_hash: string;
  lifecycle: string;
}

export interface AuditEntry {
  query_id: string;
  agent_id?: string;
  timestamp: number;
  params: QueryParamsAudit;
  result_hash?: string;
  result_confidence: number;
  contributing_assertions: ContributingAssertion[];
}

export interface AuditResponse {
  audits: AuditEntry[];
  total_count: number;
}

// Source Registry types
export interface SourceRecordDto {
  hash: string;
  label: string;
  tier: number;
  tier_label: string;
  status: "active" | "deprecated" | "quarantined";
  url?: string;
  notes?: string;
  created_at: number;
  updated_at: number;
}

export interface ListSourcesResponse {
  sources: SourceRecordDto[];
  count: number;
}

export interface SourceImpactResponse {
  source_hash: string;
  label?: string;
  status: string;
  assertion_count: number;
  affected_assertions: string[];
  query_count: number;
  affected_agents: string[];
  summary: string;
}

export interface QuarantineSourceResponse {
  source_hash: string;
  status: string;
  impact: SourceImpactResponse;
  preview: boolean;
  message: string;
}

export interface RestoreSourceResponse {
  source_hash: string;
  status: string;
  restored_assertions: number;
  message: string;
}

// ============================================================================
// Aphoria DTOs
// ============================================================================

export interface PatternDto {
  subject: string;
  predicate: string;
  value: string;
  project_count: number;
  observation_count: number;
  first_seen: number;
  last_seen: number;
}

export interface GetPatternsResponse {
  patterns: PatternDto[];
  total_matching: number;
}

export interface FindingDto {
  concept_path: string;
  predicate: string;
  code_value: string;
  file: string;
  line: number;
  conflict_score: number;
  verdict: "BLOCK" | "FLAG" | "PASS" | "ACK";
  conflicts: ConflictingSourceDto[];
  acknowledgment?: AcknowledgmentDto;
  trace?: ConflictTraceDto;
}

export interface ConflictingSourceDto {
  path: string;
  source_class: string;
  value: string;
  citation?: string;
  policy_source?: PolicySourceDto;
}

export interface PolicySourceDto {
  pack_name: string;
  pack_version: string;
  issuer_hex: string;
}

export interface AcknowledgmentDto {
  timestamp: string;
  by: string;
  reason: string;
}

export interface ConflictTraceDto {
  code_claim: string;
  authority_match: string;
  authority_tier: string;
  resolution: string;
}

export interface ScanSummaryDto {
  total: number;
  blocked: number;
  flagged: number;
  passed: number;
  acknowledged: number;
}

export interface ScanResponse {
  project: string;
  scan_id: string;
  files_scanned: number;
  claims_extracted: number;
  findings: FindingDto[];
  summary: ScanSummaryDto;
}

export interface ScanRequest {
  target_path: string;
  format?: string;
  fail_on_flag?: boolean;
  debug?: boolean;
}

export interface ScanListItem {
  scan_id: string;
  project: string;
  files_scanned: number;
  claims_extracted: number;
  summary: ScanSummaryDto;
  timestamp: number;
  findings: FindingDto[];
}

export interface ListScansResponse {
  scans: ScanListItem[];
}

export class ApiError extends Error {
  public userMessage: string;

  constructor(
    public status: number,
    public body: string
  ) {
    super(`API Error ${status}: ${body}`);
    this.name = "ApiError";

    // Parse body to extract user-friendly message
    this.userMessage = ApiError.extractUserMessage(status, body);
  }

  private static extractUserMessage(status: number, body: string): string {
    try {
      const parsed = JSON.parse(body);
      if (parsed.error) {
        return parsed.error;
      }
    } catch {
      // Not JSON, use body as-is
    }

    // Fallback messages by status code
    if (status === 404) {
      return "No results found";
    }
    if (status === 400) {
      return "Invalid request parameters";
    }
    if (status === 500) {
      return "Server error. Please try again later.";
    }

    return body || `Request failed with status ${status}`;
  }
}
