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

const DEFAULT_TIMEOUT_MS = 12_000
const MUTATION_TIMEOUT_MS = 15_000
let requestSequence = 0

function camelizeKey(value) {
  return String(value || '').replace(/_([a-z0-9])/gu, (_, letter) => letter.toUpperCase())
}

function snakeCaseKey(value) {
  return String(value || '').replace(/[A-Z]/gu, (letter) => `_${letter.toLowerCase()}`)
}

export function normalizeCommercialPayload(value) {
  if (Array.isArray(value)) {
    return value.map((item) => normalizeCommercialPayload(item))
  }
  if (!value || typeof value !== 'object' || value instanceof Date) {
    return value
  }
  return Object.fromEntries(
    Object.entries(value).map(([key, item]) => [
      camelizeKey(key),
      normalizeCommercialPayload(item)
    ])
  )
}

export function serializeCommercialPayload(value) {
  if (Array.isArray(value)) {
    return value.map((item) => serializeCommercialPayload(item))
  }
  if (!value || typeof value !== 'object' || value instanceof Date) {
    return value
  }
  return Object.fromEntries(
    Object.entries(value)
      .filter(([, item]) => item !== undefined)
      .map(([key, item]) => [
        snakeCaseKey(key),
        serializeCommercialPayload(item)
      ])
  )
}

function requireTenantId(tenantId) {
  const normalized = String(tenantId || '').trim()
  if (!normalized) {
    throw new Error('请选择需要管理的租户。')
  }
  return normalized
}

function tenantAdminPath(tenantId, suffix = '') {
  return `/commercial/admin/tenants/${encodeURIComponent(requireTenantId(tenantId))}${suffix}`
}

function appendQuery(search, key, value) {
  if (value === undefined || value === null || value === '') {
    return
  }
  search.set(snakeCaseKey(key), String(value))
}

export function buildCommercialAnalyticsSearch(options = {}) {
  const search = new URLSearchParams()
  appendQuery(search, 'start', options.start)
  appendQuery(search, 'end', options.end)
  appendQuery(search, 'asOf', options.asOf)
  return search
}

function buildCommercialListSearch(options = {}, keys = []) {
  const search = new URLSearchParams()
  keys.forEach((key) => appendQuery(search, key, options[key]))
  appendQuery(search, 'limit', options.limit)
  appendQuery(search, 'offset', options.offset)
  return search
}

function withSearch(path, search) {
  return search.size ? `${path}?${search.toString()}` : path
}

async function readCommercial(path, options = {}) {
  const payload = await apiRequest(path, {
    timeoutMs: Number(options.timeoutMs || DEFAULT_TIMEOUT_MS),
    timeoutMessage: options.timeoutMessage || '商业账户加载超时，请稍后重试。'
  })
  return normalizeCommercialPayload(payload)
}

async function mutateCommercial(path, method, payload, timeoutMessage) {
  requestSequence += 1
  const requestId = `commercial-web-${Date.now().toString(36)}-${requestSequence.toString(36)}`
  const response = await apiRequest(path, {
    method,
    headers: { 'X-Request-Id': requestId },
    body: JSON.stringify(serializeCommercialPayload(payload)),
    timeoutMs: MUTATION_TIMEOUT_MS,
    timeoutMessage
  })
  return normalizeCommercialPayload(response)
}

export async function fetchCommercialAccount(options = {}) {
  const tenantId = String(options.tenantId || '').trim()
  const path = options.platformAdmin && tenantId
    ? tenantAdminPath(tenantId, '/account')
    : '/commercial/account'
  const search = new URLSearchParams()
  appendQuery(search, 'asOf', options.asOf)
  const suffix = search.size ? `?${search.toString()}` : ''
  return readCommercial(`${path}${suffix}`, options)
}

export async function fetchCommercialAnalytics(tenantId, options = {}) {
  const search = buildCommercialAnalyticsSearch(options)
  const suffix = search.size ? `?${search.toString()}` : ''
  return readCommercial(`${tenantAdminPath(tenantId, '/analytics')}${suffix}`, {
    ...options,
    timeoutMessage: '商业价值分析加载超时，请稍后重试。'
  })
}

export function buildCommercialPricingScenario(tenantId, payload) {
  return mutateCommercial(
    tenantAdminPath(tenantId, '/pricing-scenarios'),
    'POST',
    payload,
    '定价场景计算超时，本次计算不会自动创建或修改套餐，请确认后重试。'
  )
}

export function fetchCommercialPlans(tenantId, options = {}) {
  return readCommercial(withSearch(
    tenantAdminPath(tenantId, '/plans'),
    buildCommercialListSearch(options, ['planStatus'])
  ), options)
}

export function fetchCommercialSubscriptions(tenantId, options = {}) {
  return readCommercial(withSearch(
    tenantAdminPath(tenantId, '/subscriptions'),
    buildCommercialListSearch(options, ['subscriptionStatus'])
  ), options)
}

export function fetchCommercialEntitlements(tenantId, options = {}) {
  return readCommercial(withSearch(
    tenantAdminPath(tenantId, '/entitlements'),
    buildCommercialListSearch(options, ['subscriptionId', 'entitlementStatus'])
  ), options)
}

export function fetchCommercialUsageEvents(tenantId, options = {}) {
  return readCommercial(withSearch(
    tenantAdminPath(tenantId, '/usage-events'),
    buildCommercialListSearch(options, ['subscriptionId', 'start', 'end'])
  ), options)
}

export function fetchCommercialCostEvents(tenantId, options = {}) {
  return readCommercial(withSearch(
    tenantAdminPath(tenantId, '/cost-events'),
    buildCommercialListSearch(options, ['subscriptionId', 'start', 'end'])
  ), options)
}

export function createCommercialPlan(tenantId, payload) {
  return mutateCommercial(
    tenantAdminPath(tenantId, '/plans'),
    'POST',
    payload,
    '套餐创建超时，请刷新账户确认结果后再重试。'
  )
}

export function activateCommercialPlan(tenantId, planId, expectedVersion, reason) {
  return mutateCommercial(
    tenantAdminPath(tenantId, `/plans/${encodeURIComponent(planId)}/activate`),
    'POST',
    { expectedVersion, reason },
    '套餐激活超时，请刷新版本状态后再重试。'
  )
}

export function createCommercialSubscription(tenantId, payload) {
  return mutateCommercial(
    tenantAdminPath(tenantId, '/subscriptions'),
    'POST',
    payload,
    '订阅创建超时，请刷新账户确认结果后再重试。'
  )
}

export function activateCommercialSubscription(tenantId, subscriptionId, expectedVersion, reason) {
  return mutateCommercial(
    tenantAdminPath(tenantId, `/subscriptions/${encodeURIComponent(subscriptionId)}/activate`),
    'POST',
    { expectedVersion, reason },
    '订阅激活超时，请刷新版本状态后再重试。'
  )
}

export function transitionCommercialSubscription(tenantId, subscriptionId, payload) {
  return mutateCommercial(
    tenantAdminPath(tenantId, `/subscriptions/${encodeURIComponent(subscriptionId)}/transition`),
    'POST',
    payload,
    '订阅状态变更超时，请刷新版本状态后再重试。'
  )
}

export function upsertCommercialEntitlement(tenantId, payload) {
  return mutateCommercial(
    tenantAdminPath(tenantId, '/entitlements'),
    'PUT',
    payload,
    '权益保存超时，请刷新账户确认结果后再重试。'
  )
}

export function activateCommercialEntitlement(tenantId, entitlementId, expectedVersion, reason) {
  return mutateCommercial(
    tenantAdminPath(tenantId, `/entitlements/${encodeURIComponent(entitlementId)}/activate`),
    'POST',
    { expectedVersion, reason },
    '权益激活超时，请刷新版本状态后再重试。'
  )
}

export function recordCommercialUsage(tenantId, payload) {
  return mutateCommercial(
    tenantAdminPath(tenantId, '/usage-events'),
    'POST',
    payload,
    '用量事件写入超时，可使用相同幂等键安全重试。'
  )
}

export function recordCommercialCost(tenantId, payload) {
  return mutateCommercial(
    tenantAdminPath(tenantId, '/cost-events'),
    'POST',
    payload,
    '成本事件写入超时，可使用相同幂等键安全重试。'
  )
}
