import { apiRequest, pickSafeHeaderValue } from './api.js'

const AUTH_USER_STORAGE_KEY = 'x-financial-auth-user'

function readActorName() {
  if (typeof window === 'undefined') {
    return 'system'
  }

  const raw = window.sessionStorage.getItem(AUTH_USER_STORAGE_KEY)
  if (!raw) {
    return 'system'
  }

  try {
    const payload = JSON.parse(raw)
    return (
      pickSafeHeaderValue(payload?.name, payload?.username) ||
      pickSafeHeaderValue(payload?.username, 'system') ||
      'system'
    )
  } catch {
    return 'system'
  }
}

function buildWriteHeaders(options = {}) {
  const actor = String(options.actor || readActorName()).trim() || 'system'
  const headers = {
    'x-actor': actor
  }

  if (options.requestId) {
    headers['x-request-id'] = String(options.requestId).trim()
  }

  return headers
}

function buildQuery(params = {}) {
  const search = new URLSearchParams()

  if (params.assetType) {
    search.set('asset_type', params.assetType)
  }

  if (params.status) {
    search.set('status', params.status)
  }

  if (params.domain) {
    search.set('domain', params.domain)
  }

  if (params.keyword) {
    search.set('keyword', params.keyword)
  }

  if (params.limit) {
    search.set('limit', String(params.limit))
  }

  const page = params.page
  const pageSize = params.pageSize || params.page_size

  if (page) {
    search.set('page', String(page))
  }

  if (pageSize) {
    search.set('page_size', String(pageSize))
  }

  if (params.version) {
    search.set('version', String(params.version))
  }

  if (params.agent) {
    search.set('agent', params.agent)
  }

  if (params.source) {
    search.set('source', params.source)
  }

  const query = search.toString()
  return query ? `?${query}` : ''
}

export function fetchAgentAssets(params = {}) {
  return apiRequest(`/agent-assets${buildQuery(params)}`)
}

export function fetchAgentAssetDetail(assetId) {
  return apiRequest(`/agent-assets/${assetId}`)
}

export function fetchAgentAssetSpreadsheetOnlyOfficeConfig(assetId) {
  return apiRequest(`/agent-assets/${assetId}/spreadsheet/onlyoffice-config`)
}

export function fetchAgentAssetSpreadsheetBlob(assetId, disposition = 'inline') {
  const search = new URLSearchParams()
  if (disposition) {
    search.set('disposition', String(disposition).trim())
  }
  const query = search.toString()
  return apiRequest(`/agent-assets/${assetId}/spreadsheet/content${query ? `?${query}` : ''}`, {
    responseType: 'blob',
    contentType: null
  })
}

export function uploadAgentAssetSpreadsheet(assetId, file, options = {}) {
  return apiRequest(
    `/agent-assets/${assetId}/spreadsheet/upload?filename=${encodeURIComponent(file.name)}`,
    {
      method: 'POST',
      body: file,
      contentType: file.type || 'application/octet-stream',
      headers: buildWriteHeaders(options)
    }
  )
}

export function importAgentAssetSpreadsheetContent(assetId, file, options = {}) {
  return apiRequest(
    `/agent-assets/${assetId}/spreadsheet/import-content?filename=${encodeURIComponent(file.name)}`,
    {
      method: 'POST',
      body: file,
      contentType: file.type || 'application/octet-stream',
      headers: buildWriteHeaders(options)
    }
  )
}

export function fetchAgentAssetVersions(assetId, limit = 5) {
  return apiRequest(`/agent-assets/${assetId}/versions${buildQuery({ limit })}`)
}

export function fetchAgentAssetVersionTimeline(assetId) {
  return apiRequest(`/agent-assets/${assetId}/version-timeline`)
}

export function fetchAgentAssetRuleJson(assetId) {
  return apiRequest(`/agent-assets/${assetId}/rule-json`)
}

export function saveAgentAssetRuleJson(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/rule-json`, {
    method: 'PUT',
    body: JSON.stringify(payload),
    headers: buildWriteHeaders(options)
  })
}

export function generateRiskRuleAsset(payload, options = {}) {
  return apiRequest('/agent-assets/risk-rules/generate', {
    method: 'POST',
    body: JSON.stringify(payload),
    headers: buildWriteHeaders(options),
    timeoutMs: options.timeoutMs || 60000,
    timeoutMessage: '风险规则生成时间较长，请稍后查看是否已生成草稿。'
  })
}

export function fetchRiskRuleTemplates() {
  return apiRequest('/agent-assets/risk-rules/templates')
}

export function updateRiskRuleDraft(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rules/draft`, {
    method: 'PATCH',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options)
  })
}

export function createRiskRuleRevision(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rules/revisions`, {
    method: 'POST',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options)
  })
}

export function regenerateRiskRuleAsset(assetId, payload = {}, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rules/regenerate`, {
    method: 'POST',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options),
    timeoutMs: options.timeoutMs || 60000,
    timeoutMessage: '风险规则重新生成时间较长，请稍后查看最新结果。'
  })
}

export function submitRiskRuleFeedback(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rules/feedback`, {
    method: 'POST',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options)
  })
}

export function fetchRiskRuleFeedback(assetId, params = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rules/feedback${buildQuery(params)}`)
}

export function fetchRiskRuleLatestTest(assetId) {
  return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/latest`)
}

export function runRiskRuleSampleTest(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/sample`, {
    method: 'POST',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options)
  })
}

export function simulateRiskRuleTest(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/simulate`, {
    method: 'POST',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options)
  })
}

export function runRiskRuleScenarioTest(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/scenario`, {
    method: 'POST',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options)
  })
}

export function confirmRiskRuleTestReport(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rule-tests/report`, {
    method: 'POST',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options)
  })
}

export function deleteAgentAsset(assetId, options = {}) {
  return apiRequest(`/agent-assets/${assetId}`, {
    method: 'DELETE',
    headers: buildWriteHeaders(options)
  })
}

export function returnRiskRuleAsset(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/return`, {
    method: 'POST',
    body: JSON.stringify(payload || {}),
    headers: buildWriteHeaders(options)
  })
}

export function publishRiskRuleAsset(assetId, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/publish`, {
    method: 'POST',
    headers: buildWriteHeaders(options)
  })
}

export function fetchAgentAssetReleaseState(assetId) {
  return apiRequest(`/agent-assets/${assetId}/release`)
}

const RELEASE_REVIEW_METRIC_KEYS = [
  'observed_count',
  'runtime_failure_count',
  'runtime_failure_rate',
  'negative_sample_count',
  'negative_labeled_count',
  'negative_pending_label_count',
  'false_negative_count',
  'estimated_false_negative_count',
  'false_negative_upper_bound',
  'random_negative_population_count',
  'random_negative_sample_count',
  'random_negative_labeled_count',
  'recall',
  'recall_lower_bound',
  'recall_confidence_level',
  'recall_method',
  'negative_ground_truth_status'
]
const RELEASE_REVIEW_LABELS = new Set(['risk_present', 'risk_absent'])

export function normalizeAgentAssetReleaseReviewQueue(payload = {}) {
  const metrics = payload?.metrics && typeof payload.metrics === 'object' ? payload.metrics : {}
  return {
    asset_id: text(payload.asset_id),
    release_id: text(payload.release_id),
    stage: text(payload.stage),
    version: text(payload.version),
    pending_total: count(payload.pending_total),
    telemetry_status: text(payload.telemetry_status),
    reasons: Array.isArray(payload.reasons) ? payload.reasons.map(text).filter(Boolean) : [],
    metrics: Object.fromEntries(
      RELEASE_REVIEW_METRIC_KEYS
        .filter((key) => Object.hasOwn(metrics, key))
        .map((key) => [key, metrics[key]])
    ),
    alerts: (Array.isArray(payload.alerts) ? payload.alerts : []).map((alert) => ({
      code: text(alert?.code),
      severity: text(alert?.severity),
      message: text(alert?.message),
      recommended_action: text(alert?.recommended_action)
    })),
    items: (Array.isArray(payload.items) ? payload.items : []).map((item) => ({
      sample_id: text(item?.sample_id),
      observation_id: text(item?.observation_id),
      source_document_id: text(item?.source_document_id),
      rule_code: text(item?.rule_code),
      business_stage: text(item?.business_stage),
      prediction_blinded: item?.prediction_blinded === true,
      reviewer_count: count(item?.reviewer_count),
      required_reviewers: Math.max(1, count(item?.required_reviewers, 1)),
      conflicted: item?.conflicted === true,
      created_at: text(item?.created_at)
    }))
  }
}

export function normalizeAgentAssetReleaseReviewLabel(label) {
  const normalized = text(label)
  if (!RELEASE_REVIEW_LABELS.has(normalized)) {
    throw new TypeError('盲审结论必须是 risk_present 或 risk_absent。')
  }
  return normalized
}

export async function fetchAgentAssetReleaseReviewQueue(assetId, limit = 50) {
  const payload = await apiRequest(
    `/agent-assets/${assetId}/release/review-queue${buildQuery({ limit })}`
  )
  return normalizeAgentAssetReleaseReviewQueue(payload)
}

export function labelAgentAssetReleaseObservation(
  assetId,
  observationId,
  label,
  options = {}
) {
  const reviewLabel = normalizeAgentAssetReleaseReviewLabel(label)
  return apiRequest(
    `/agent-assets/${assetId}/release/review-queue/${observationId}/labels`,
    {
      method: 'POST',
      body: JSON.stringify({ label: reviewLabel }),
      headers: buildWriteHeaders(options)
    }
  )
}

export function setRiskRuleAssetEnabled(assetId, enabled, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rule-enabled`, {
    method: 'POST',
    body: JSON.stringify({ enabled: Boolean(enabled) }),
    headers: buildWriteHeaders(options)
  })
}

function text(value) {
  return String(value || '').trim()
}

function count(value, fallback = 0) {
  const parsed = Number(value)
  return Number.isInteger(parsed) && parsed >= 0 ? parsed : fallback
}

export function setRiskRuleAssetLevel(assetId, riskLevel, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/risk-rule-level`, {
    method: 'POST',
    body: JSON.stringify({ risk_level: riskLevel }),
    headers: buildWriteHeaders(options)
  })
}

export function fetchAgentAssetSpreadsheetChangeRecords(assetId, limit = 30) {
  return apiRequest(
    `/agent-assets/${assetId}/spreadsheet/change-records${buildQuery({ limit })}`
  )
}

export function updateAgentAsset(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}`, {
    method: 'PATCH',
    body: JSON.stringify(payload),
    headers: buildWriteHeaders(options)
  })
}

export function createAgentAssetVersion(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/versions`, {
    method: 'POST',
    body: JSON.stringify(payload),
    headers: buildWriteHeaders(options)
  })
}

export function createAgentAssetReview(assetId, payload, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/reviews`, {
    method: 'POST',
    body: JSON.stringify(payload),
    headers: buildWriteHeaders(options)
  })
}

export function activateAgentAsset(assetId, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/activate`, {
    method: 'POST',
    headers: buildWriteHeaders(options)
  })
}

export function restoreAgentAssetVersion(assetId, version, options = {}) {
  return apiRequest(`/agent-assets/${assetId}/versions/${encodeURIComponent(version)}/restore`, {
    method: 'POST',
    headers: buildWriteHeaders(options)
  })
}

export function fetchAgentRuns(params = {}) {
  return apiRequest(`/agent-runs${buildQuery(params)}`)
}

export function fetchAgentRunDetail(runId) {
  return apiRequest(`/agent-runs/${encodeURIComponent(runId)}`)
}
