/**
 * AWOOOI API Client
 * ADR-005: 所有請求經過 BFF
 *
 * 統帥鐵律: 禁止任何 Fallback IP，環境變數缺失即噴錯
 */

// 絕對純化: 環境變數缺失時直接拋出致命錯誤，嚴禁任何 Fallback
const getApiBaseUrl = (): string => {
  const url = process.env.NEXT_PUBLIC_API_URL
  if (!url) {
    const fatalMsg = '[AWOOOI FATAL] Missing NEXT_PUBLIC_API_URL configuration.'
    console.error(fatalMsg)
    if (typeof window !== 'undefined') {
      console.error('%c' + fatalMsg, 'color: #ef4444; font-weight: bold; font-size: 16px;')
    }
    throw new Error(fatalMsg)
  }
  return url.endsWith('/api/v1') ? url : `${url}/api/v1`
}

const API_BASE_URL = getApiBaseUrl()

export class ApiError extends Error {
  constructor(
    public status: number,
    public code: string,
    message: string
  ) {
    super(message)
    this.name = 'ApiError'
  }
}

async function handleResponse<T>(response: Response): Promise<T> {
  if (!response.ok) {
    const error = await response.json().catch(() => ({}))
    throw new ApiError(
      response.status,
      error.code || 'UNKNOWN_ERROR',
      error.message || response.statusText
    )
  }
  return response.json()
}

export const apiClient = {
  // Health
  async getHealth() {
    const res = await fetch(`${API_BASE_URL}/health`)
    return handleResponse<{
      status: 'healthy' | 'degraded' | 'unhealthy'
      version: string
      timestamp: string
      components: Record<string, 'up' | 'down'>
    }>(res)
  },

  // Agent
  async getAgentStatus() {
    const res = await fetch(`${API_BASE_URL}/agent/status`)
    return handleResponse<{
      status: 'idle' | 'thinking' | 'executing' | 'waiting_approval'
      active_conversations: number
      current_task: string | null
      last_activity: string | null
    }>(res)
  },

  async chat(message: string, conversationId?: string) {
    const res = await fetch(`${API_BASE_URL}/agent/chat`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ message, conversation_id: conversationId }),
    })
    return handleResponse<{
      message: string
      conversation_id: string
      requires_approval: boolean
      approval_id?: string
    }>(res)
  },

  // Plugins
  async listPlugins(category?: string) {
    const params = category ? `?category=${category}` : ''
    const res = await fetch(`${API_BASE_URL}/plugins${params}`)
    return handleResponse<Array<{
      id: string
      name: string
      version: string
      category: string
      enabled: boolean
      description?: string
    }>>(res)
  },

  // Approvals
  async listApprovals(status?: string) {
    const params = status ? `?status=${status}` : ''
    const res = await fetch(`${API_BASE_URL}/approvals${params}`)
    return handleResponse<{
      items: Array<{
        id: string
        type: string
        status: string
        action: {
          plugin_id: string
          operation: string
          risk_level: string
        }
        requested_at: string
      }>
    }>(res)
  },

  async signApproval(approvalId: string, signer: string = 'commander', comment?: string, csrfToken?: string | null) {
    // Phase 22 P0: 加入 CSRF token + credentials (2026-03-31 Claude Code)
    const headers: Record<string, string> = { 'Content-Type': 'application/json' }
    if (csrfToken) headers['X-CSRF-Token'] = csrfToken
    const res = await fetch(`${API_BASE_URL}/approvals/${approvalId}/sign`, {
      method: 'POST',
      headers,
      credentials: 'include',
      body: JSON.stringify({
        signer_id: signer,
        signer_name: signer,
        comment: comment,
      }),
    })
    // 🔧 Fix: 回傳型別與後端實際結構對齊
    return handleResponse<{
      success: boolean
      message: string
      approval: ApprovalResponse
      execution_triggered: boolean
      // 向下相容舊欄位 (deprecated)
      approval_id?: string
      status?: string
      current_signatures?: number
      required_signatures?: number
    }>(res)
  },

  async rejectApproval(approvalId: string, reason?: string, csrfToken?: string | null) {
    // Phase 22 P0: 加入 CSRF token + credentials (2026-03-31 Claude Code)
    const headers: Record<string, string> = { 'Content-Type': 'application/json' }
    if (csrfToken) headers['X-CSRF-Token'] = csrfToken
    const res = await fetch(`${API_BASE_URL}/approvals/${approvalId}/reject`, {
      method: 'POST',
      headers,
      credentials: 'include',
      body: JSON.stringify({
        rejector_id: 'commander',
        rejector_name: 'Commander',
        reason: reason || 'Rejected via WarRoom',
      }),
    })
    return handleResponse<{ id: string; status: string }>(res)
  },

  // =========================================================================
  // Phase 7: Incidents API (真實血脈)
  // =========================================================================

  async listIncidents() {
    const res = await fetch(`${API_BASE_URL}/incidents`)
    return handleResponse<IncidentListResponse>(res)
  },

  async getIncident(incidentId: string) {
    const res = await fetch(`${API_BASE_URL}/incidents/${incidentId}`)
    return handleResponse<IncidentResponse>(res)
  },

  async generateProposal(incidentId: string) {
    const res = await fetch(`${API_BASE_URL}/incidents/${incidentId}/proposal`, {
      method: 'POST',
    })
    return handleResponse<ProposalGenerateResponse>(res)
  },

  // =========================================================================
  // Phase 7: Pending Approvals API (真實血脈)
  // =========================================================================

  async getPendingApprovals() {
    const res = await fetch(`${API_BASE_URL}/approvals/pending`)
    return handleResponse<PendingApprovalsResponse>(res)
  },

  // =========================================================================
  // Phase 10: Sentry Errors API (#40 BFF)
  // =========================================================================

  async getErrorStats() {
    const res = await fetch(`${API_BASE_URL}/errors/stats`)
    return handleResponse<ErrorStatsResponse>(res)
  },

  async listErrors(params?: { status?: string; level?: string; limit?: number }) {
    const searchParams = new URLSearchParams()
    if (params?.status) searchParams.set('status', params.status)
    if (params?.level) searchParams.set('level', params.level)
    if (params?.limit) searchParams.set('limit', params.limit.toString())
    const query = searchParams.toString() ? `?${searchParams.toString()}` : ''
    const res = await fetch(`${API_BASE_URL}/errors/issues${query}`)
    return handleResponse<ErrorListResponse>(res)
  },

  async getErrorDetail(issueId: string) {
    const res = await fetch(`${API_BASE_URL}/errors/issues/${issueId}`)
    return handleResponse<ErrorDetailResponse>(res)
  },

  async getErrorTrends(period: '24h' | '7d' | '30d' = '24h') {
    const res = await fetch(`${API_BASE_URL}/errors/trends?period=${period}`)
    return handleResponse<ErrorTrendResponse>(res)
  },

  async analyzeError(issueId: string) {
    const res = await fetch(`${API_BASE_URL}/errors/issues/${issueId}/analyze`, {
      method: 'POST',
    })
    return handleResponse<ErrorAnalysisResponse>(res)
  },

  // =========================================================================
  // Phase 19: UX Audit / Session Replay (#126)
  // 2026-03-31 Claude Code - Frontend Replay UI Integration
  // =========================================================================

  async getUXAudit() {
    const res = await fetch(`${API_BASE_URL}/errors/ux-audit`)
    return handleResponse<UXAuditResponse>(res)
  },
}

// =========================================================================
// Type Definitions (Phase 7)
// =========================================================================

/**
 * Phase 6.5: 決策令牌資訊
 * 確保 UI 永遠有決策可操作
 */
export interface DecisionInfo {
  token: string
  state: 'init' | 'analyzing' | 'ready' | 'executing' | 'completed' | 'error'
  proposal_data: {
    action: string
    description: string
    reasoning: string
    risk_level: 'low' | 'medium' | 'critical'
    kubectl_command: string
    source: string
    confidence: number
  } | null
  proposal_id: string | null
}

export interface IncidentResponse {
  incident_id: string
  status: 'investigating' | 'mitigating' | 'resolved' | 'closed'
  severity: 'P0' | 'P1' | 'P2' | 'P3'
  signal_count: number
  affected_services: string[]
  proposal_count: number
  created_at: string
  updated_at: string
  /** Phase 6.5: 決策令牌 (確保 UI 永不鎖死) */
  decision: DecisionInfo | null
}

export interface IncidentListResponse {
  count: number
  incidents: IncidentResponse[]
}

export interface BlastRadius {
  affected_pods: number
  estimated_downtime: string
  related_services: string[]
  data_impact: 'none' | 'read_only' | 'write' | 'destructive'
}

export interface DryRunCheck {
  name: string
  passed: boolean
  message: string
}

export interface ApprovalResponse {
  id: string
  action: string
  description: string
  status: 'pending' | 'approved' | 'rejected' | 'expired'
  risk_level: 'low' | 'medium' | 'high' | 'critical'
  blast_radius: BlastRadius
  dry_run_checks: DryRunCheck[]
  required_signatures: number
  current_signatures: number
  signatures: Array<{ signer: string; signed_at: string }>
  requested_by: string
  created_at: string
  expires_at: string | null
}

export interface PendingApprovalsResponse {
  count: number
  approvals: ApprovalResponse[]
}

export interface ProposalGenerateResponse {
  success: boolean
  message: string
  incident_id: string
  proposal: ApprovalResponse | null
  incident_status: string | null
}

// =========================================================================
// Phase 10: Sentry Error Types (#40 BFF)
// =========================================================================

export interface SentryIssue {
  id: string
  short_id: string
  title: string
  culprit: string | null
  level: 'error' | 'warning' | 'info' | 'fatal'
  status: 'unresolved' | 'resolved' | 'ignored'
  count: number
  user_count: number
  first_seen: string
  last_seen: string
  permalink: string | null
}

export interface ErrorStatsResponse {
  total_issues: number
  unresolved_issues: number
  error_count_24h: number
  critical_count: number
  projects: string[]
}

export interface ErrorListResponse {
  issues: SentryIssue[]
  total: number
  has_more: boolean
}

export interface ErrorDetailResponse {
  issue: Record<string, unknown>
  latest_event: Record<string, unknown> | null
  sentry_url: string
}

export interface ErrorTrendPoint {
  timestamp: string
  count: number
}

export interface ErrorTrendResponse {
  period: '24h' | '7d' | '30d'
  data: ErrorTrendPoint[]
  total_count: number
  change_percent: number
}

export interface FixRecommendation {
  summary: string
  steps: string[]
  code_suggestion: string | null
}

export interface PreventionMeasure {
  type: string
  description: string
}

export interface ErrorAnalysis {
  root_cause: string
  category: string
  severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
  impact_assessment: string
  fix_recommendation: FixRecommendation
  prevention: PreventionMeasure[]
  related_files: string[]
  confidence: number
  reasoning: string
}

export interface ErrorAnalysisResponse {
  status: 'completed' | 'failed'
  issue_id: string
  provider: string
  analysis?: ErrorAnalysis
  analyzed_at?: string
  sentry_url: string
  message?: string
}

// =========================================================================
// Phase 19: UX Audit / Session Replay Types (#126)
// 2026-03-31 Claude Code - Frontend Replay UI Integration
// =========================================================================

export interface UXAuditDetail {
  type: 'replay_with_errors' | 'ui_error'
  replay_id?: string
  issue_id?: string
  url: string
  error_count?: number
  title?: string
  count?: number
  urls?: string[]
}

export interface UXAuditResponse {
  replays_with_errors: number
  rage_clicks: number
  dead_clicks: number
  ui_errors: number
  health_score: 'good' | 'moderate' | 'poor'
  details: UXAuditDetail[]
  replay_dashboard_url: string
}
