import { apiRequest } from './api.js'
import {
  buildApplicationPreviewRows,
  buildApplicationPreviewSubmitText,
  normalizeApplicationPreview
} from '../utils/expenseApplicationPreview.js'

export const AI_APPLICATION_ACTION_SAVE_DRAFT = 'ai_application_save_draft'
export const AI_APPLICATION_ACTION_SUBMIT = 'ai_application_submit'
const AI_APPLICATION_MEMORY_FIELD_LABELS = {
  amount: '预计金额',
  application_type: '申请类型',
  applicationType: '申请类型',
  days: '出差天数',
  location: '出差地点',
  reason: '申请事由',
  time: '出差时间',
  time_range: '出差时间',
  transport_mode: '出行方式',
  transportMode: '出行方式'
}
const AI_APPLICATION_MEMORY_SCOPE_DEFAULTS = {
  enterprise: {
    label: '企业制度',
    priority: 300,
    source: 'admin_managed_org'
  },
  department: {
    label: '部门基线',
    priority: 200,
    source: 'admin_managed_org'
  },
  user: {
    label: '个人偏好',
    priority: 100,
    source: 'verified_user_history'
  }
}

function normalizeOptionalNumber(value) {
  if (value === '' || value === null || value === undefined) return null
  const normalized = Number(value)
  return Number.isFinite(normalized) ? normalized : null
}

function normalizeBoolean(value, fallback = false) {
  if (value === true || value === 1 || value === 'true' || value === '1') return true
  if (value === false || value === 0 || value === 'false' || value === '0') return false
  return fallback
}

function normalizeMemoryConflicts(value) {
  if (!Array.isArray(value)) return []
  return value.filter((item) => {
    if (item && typeof item === 'object') return true
    return Boolean(normalizeText(item))
  })
}

export function normalizeAiApplicationMemory(item = {}) {
  if (!item || typeof item !== 'object') return null
  const memoryId = normalizeText(item.memoryId || item.memory_id)
  const fieldKey = normalizeText(item.fieldKey || item.field_key)
  const rawStatus = normalizeText(item.status).toLowerCase()
  const status = rawStatus === 'active' ? 'applied' : rawStatus
  const scopeType = normalizeText(item.scopeType || item.scope_type).toLowerCase() || 'user'
  const scopeDefaults = AI_APPLICATION_MEMORY_SCOPE_DEFAULTS[scopeType]
    || AI_APPLICATION_MEMORY_SCOPE_DEFAULTS.user
  const explicitCanRevoke = Object.prototype.hasOwnProperty.call(item, 'canRevoke')
    ? item.canRevoke
    : item.can_revoke
  if (!memoryId || !fieldKey || !status) return null
  return {
    memoryId,
    fieldKey,
    fieldLabel:
      normalizeText(item.fieldLabel || item.field_label)
      || AI_APPLICATION_MEMORY_FIELD_LABELS[fieldKey]
      || fieldKey,
    value: normalizeText(item.value),
    status,
    evidenceCount: Number(item.evidenceCount ?? item.evidence_count ?? 0) || 0,
    approvedEvidenceCount:
      Number(item.approvedEvidenceCount ?? item.approved_evidence_count ?? 0) || 0,
    scopeType,
    scopeId: normalizeText(item.scopeId || item.scope_id),
    scopeLabel: normalizeText(item.scopeLabel || item.scope_label) || scopeDefaults.label,
    source: normalizeText(item.source) || scopeDefaults.source,
    priority:
      normalizeOptionalNumber(item.priority) ?? scopeDefaults.priority,
    effectiveConfidence: normalizeOptionalNumber(
      item.effectiveConfidence ?? item.effective_confidence
    ),
    conflicts: normalizeMemoryConflicts(item.conflicts),
    canRevoke: normalizeBoolean(explicitCanRevoke, scopeType === 'user'),
    message: normalizeText(item.message)
  }
}

export function normalizeAiApplicationMemories(items = []) {
  return (Array.isArray(items) ? items : [])
    .map((item) => normalizeAiApplicationMemory(item))
    .filter(Boolean)
}

export function resolveAiApplicationPreviewMemories(preview = {}) {
  const items = Array.isArray(preview?.memoryApplications)
    ? preview.memoryApplications
    : preview?.memory_applications
  return normalizeAiApplicationMemories(items)
}

export function resolveAiApplicationLearningReceipts(payload = {}) {
  const result = payload?.result && typeof payload.result === 'object' ? payload.result : payload
  const items = Array.isArray(result?.learning_receipts)
    ? result.learning_receipts
    : result?.learningReceipts
  return normalizeAiApplicationMemories(items)
}

export function createAiApplicationRequestId(prefix = 'application') {
  const normalizedPrefix = normalizeText(prefix) || 'application'
  if (typeof globalThis.crypto?.randomUUID === 'function') {
    return `${normalizedPrefix}:${globalThis.crypto.randomUUID()}`
  }
  return `${normalizedPrefix}:${Date.now()}:${Math.random().toString(16).slice(2)}`
}

export function resolveAiApplicationPreviewDecisionId(preview = {}) {
  return normalizeText(preview?.decisionId || preview?.decision_id)
}

export async function registerAiApplicationPreviewDecision({
  applicationPreview,
  conversationId = '',
  message = '',
  requestId = ''
} = {}, options = {}) {
  const normalizedPreview = normalizeApplicationPreview(applicationPreview || {})
  const issueRequestId = normalizeText(requestId) || createAiApplicationRequestId('preview')
  const payload = await apiRequest('/reimbursements/application-previews', {
    method: 'POST',
    body: JSON.stringify({
      message: normalizeText(message),
      conversation_id: normalizeText(conversationId) || null,
      request_id: issueRequestId
    }),
    timeoutMs: 30000,
    timeoutMessage: '申请预览校验超时，已切换为普通核对模式。',
    ...options
  })
  const serverPreview = payload?.application_preview && typeof payload.application_preview === 'object'
    ? payload.application_preview
    : {}
  const memoryApplications = resolveAiApplicationPreviewMemories({
    memoryApplications:
      serverPreview.memoryApplications
      ?? serverPreview.memory_applications
      ?? normalizedPreview.memoryApplications
      ?? normalizedPreview.memory_applications
  })
  return normalizeApplicationPreview({
    ...normalizedPreview,
    ...serverPreview,
    fields: {
      ...(normalizedPreview.fields || {}),
      ...(serverPreview.fields || {})
    },
    decisionId: normalizeText(payload?.decision_id || serverPreview.decisionId),
    decisionSource: normalizeText(payload?.decision_source || serverPreview.decisionSource),
    decisionExpiresAt: normalizeText(payload?.expires_at || serverPreview.decisionExpiresAt),
    memoryApplications,
    decisionTrackingStatus: 'registered'
  })
}

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

function resolveUserValue(user = {}, ...keys) {
  for (const key of keys) {
    const value = normalizeText(user?.[key])
    if (value) return value
  }
  return ''
}

function buildClientTimeContext() {
  const now = new Date()
  const locale =
    typeof navigator !== 'undefined' && typeof navigator.language === 'string'
      ? navigator.language
      : 'zh-CN'

  return {
    client_now_iso: now.toISOString(),
    client_timezone_offset_minutes: now.getTimezoneOffset(),
    client_locale: locale
  }
}

function buildApplicationPreviewSaveText(preview = {}) {
  const rows = buildApplicationPreviewRows(preview)
  return [
    '费用申请保存草稿',
    ...rows.map((row) => `${row.label}：${row.value}`),
    '',
    '保存草稿'
  ].join('\n')
}

export function buildAiApplicationPreviewActionText(actionType, preview = {}) {
  const normalized = normalizeApplicationPreview(preview)
  return actionType === AI_APPLICATION_ACTION_SUBMIT
    ? buildApplicationPreviewSubmitText(normalized)
    : buildApplicationPreviewSaveText(normalized)
}

export function buildAiApplicationPreviewActionPayload({
  actionType,
  applicationPreview,
  currentUser = {},
  conversationId = '',
  draftPayload = null,
  requestId = '',
  entrySource = 'workbench_ai_inline',
  source = 'workbench',
  requestSource = 'user_message'
} = {}) {
  const normalizedPreview = normalizeApplicationPreview(applicationPreview || {})
  const message = buildAiApplicationPreviewActionText(actionType, normalizedPreview)
  const username = resolveUserValue(currentUser, 'username', 'account', 'email', 'name') || 'anonymous'
  const name = resolveUserValue(currentUser, 'name', 'username')
  const employeeNo = resolveUserValue(currentUser, 'employeeNo', 'employee_no')
  const managerName = resolveUserValue(currentUser, 'managerName', 'manager_name', 'directManagerName', 'direct_manager_name')
  const departmentName = resolveUserValue(currentUser, 'departmentName', 'department_name', 'department')
  const position = resolveUserValue(currentUser, 'position', 'employeePosition', 'employee_position')
  const grade = resolveUserValue(currentUser, 'grade', 'employeeGrade', 'employee_grade')
  const roleCodes = Array.isArray(currentUser.roleCodes)
    ? currentUser.roleCodes.map((item) => normalizeText(item)).filter(Boolean)
    : []
  const draftClaimId = normalizeText(draftPayload?.claim_id || draftPayload?.claimId)
  const isSubmit = actionType === AI_APPLICATION_ACTION_SUBMIT
  const decisionId = resolveAiApplicationPreviewDecisionId(normalizedPreview)
  const actionRequestId = normalizeText(requestId || normalizedPreview.decisionActionRequestId)
  const applicationEditableFields = Array.isArray(normalizedPreview.editableFields)
    ? normalizedPreview.editableFields.map((field) => normalizeText(field)).filter(Boolean)
    : []

  return {
    source: normalizeText(requestSource) || 'user_message',
    user_id: username,
    conversation_id: normalizeText(conversationId) || null,
    action_type: isSubmit ? 'submit' : 'save_draft',
    ...(decisionId ? { decision_id: decisionId } : {}),
    ...(decisionId && actionRequestId ? { request_id: actionRequestId } : {}),
    message,
    context_json: {
      role_codes: roleCodes,
      is_admin: Boolean(currentUser.isAdmin),
      name,
      role: resolveUserValue(currentUser, 'role'),
      department: departmentName,
      department_name: departmentName,
      position,
      employee_position: position,
      employeePosition: position,
      grade,
      employee_grade: grade,
      employeeGrade: grade,
      employee_no: employeeNo,
      employeeNo,
      manager_name: managerName,
      managerName,
      direct_manager_name: managerName,
      directManagerName: managerName,
      cost_center: resolveUserValue(currentUser, 'costCenter', 'cost_center'),
      finance_owner_name: resolveUserValue(currentUser, 'financeOwnerName', 'finance_owner_name'),
      ...buildClientTimeContext(),
      session_type: 'application',
      entry_source: normalizeText(entrySource) || 'workbench_ai_inline',
      source: normalizeText(source) || 'workbench',
      document_type: 'expense_application',
      application_stage: 'expense_application',
      user_input_text: message,
      application_preview: normalizedPreview,
      ...(applicationEditableFields.length
        ? { application_editable_fields: applicationEditableFields }
        : {}),
      ...(isSubmit
        ? {}
        : {
            application_action: 'save_draft',
            application_save_mode: true
          }),
      ...(draftClaimId
        ? {
            application_edit_claim_id: draftClaimId,
            draft_claim_id: draftClaimId,
            selected_claim_id: draftClaimId,
            application_edit_mode: true
          }
        : {})
    }
  }
}

export function runAiApplicationPreviewAction(params = {}, options = {}) {
  const payload = buildAiApplicationPreviewActionPayload(params)
  const isSubmit = params.actionType === AI_APPLICATION_ACTION_SUBMIT
  return apiRequest('/reimbursements/application-preview-action', {
    method: 'POST',
    body: JSON.stringify(payload),
    timeoutMs: isSubmit ? 45000 : 30000,
    timeoutMessage: isSubmit ? '申请提交处理超时，请稍后重试。' : '申请草稿保存超时，请稍后重试。',
    ...options
  })
}

export function forgetAiApplicationMemory(memoryId, options = {}) {
  const normalizedMemoryId = normalizeText(memoryId)
  if (!normalizedMemoryId) {
    return Promise.reject(new Error('缺少要忘记的偏好标识。'))
  }
  return apiRequest(`/expense-application-memories/${encodeURIComponent(normalizedMemoryId)}`, {
    method: 'DELETE',
    ...options
  })
}
