import assert from 'node:assert/strict'
import test from 'node:test'

import {
  activateCommercialEntitlement,
  activateCommercialPlan,
  activateCommercialSubscription,
  buildCommercialAnalyticsSearch,
  buildCommercialPricingScenario,
  createCommercialPlan,
  createCommercialSubscription,
  fetchCommercialAccount,
  fetchCommercialAnalytics,
  fetchCommercialCostEvents,
  fetchCommercialEntitlements,
  fetchCommercialPlans,
  fetchCommercialSubscriptions,
  fetchCommercialUsageEvents,
  normalizeCommercialPayload,
  recordCommercialCost,
  recordCommercialUsage,
  serializeCommercialPayload,
  transitionCommercialSubscription,
  upsertCommercialEntitlement
} from '../src/services/commercial.js'

function installFetch(handler) {
  const original = globalThis.fetch
  globalThis.fetch = handler
  return () => { globalThis.fetch = original }
}

function jsonResponse(payload, status = 200) {
  return new Response(JSON.stringify(payload), {
    status,
    headers: { 'content-type': 'application/json' }
  })
}

test('商业接口递归转换 snake_case 与 camelCase 且保留数组和金额字符串', () => {
  const normalized = normalizeCommercialPayload({
    data_status: 'partial',
    customer_roi: { required_inputs: ['收费'], ratios: [{ reporting_currency: 'CNY', ratio: '1.20' }] }
  })
  assert.equal(normalized.dataStatus, 'partial')
  assert.equal(normalized.customerRoi.requiredInputs[0], '收费')
  assert.equal(normalized.customerRoi.ratios[0].reportingCurrency, 'CNY')
  assert.equal(normalized.customerRoi.ratios[0].ratio, '1.20')

  assert.deepEqual(serializeCommercialPayload({
    planCode: 'enterprise',
    configJson: { billingMode: 'overage' },
    requiredInputs: ['invoice']
  }), {
    plan_code: 'enterprise',
    config_json: { billing_mode: 'overage' },
    required_inputs: ['invoice']
  })
})

test('普通账号只读取自身账户，平台管理员显式选择租户后才使用跨租户路径', async () => {
  const urls = []
  const restore = installFetch(async (url) => {
    urls.push(String(url))
    return jsonResponse({ tenant_id: 'tenant-a', data_status: 'unavailable', quotas: [] })
  })
  try {
    await fetchCommercialAccount({ platformAdmin: false, tenantId: 'should-not-leak' })
    await fetchCommercialAccount({ platformAdmin: true, tenantId: 'tenant/a', asOf: '2026-07-16T00:00:00Z' })
  } finally {
    restore()
  }

  assert.equal(urls[0], '/api/v1/commercial/account')
  assert.match(urls[1], /\/commercial\/admin\/tenants\/tenant%2Fa\/account\?as_of=2026-07-16T00%3A00%3A00Z$/u)
})

test('商业分析时间参数显式序列化且不附加客户端汇率或合计字段', async () => {
  const search = buildCommercialAnalyticsSearch({
    start: '2026-04-01T00:00:00Z',
    end: '2026-07-01T00:00:00Z',
    asOf: '2026-07-01T00:00:00Z',
    fxRate: '7.2'
  })
  assert.equal(search.get('as_of'), '2026-07-01T00:00:00Z')
  assert.equal(search.has('fx_rate'), false)

  let requestedUrl = ''
  const restore = installFetch(async (url) => {
    requestedUrl = String(url)
    return jsonResponse({
      tenant_id: 'tenant-a',
      data_quality_status: 'unavailable',
      customer_charges: {},
      internal_costs: {},
      contribution_margin: {},
      verified_cash_savings: {},
      customer_roi: {},
      customer_labor_value: {}
    })
  })
  try {
    await fetchCommercialAnalytics('tenant-a', Object.fromEntries(search))
  } finally {
    restore()
  }
  assert.match(requestedUrl, /\/commercial\/admin\/tenants\/tenant-a\/analytics/u)
  assert.match(requestedUrl, /start=2026-04-01T00%3A00%3A00Z/u)
})

test('定价场景使用平台租户 POST 契约且只提交服务端 schema 字段', async () => {
  let request = null
  const restore = installFetch(async (url, options = {}) => {
    request = { url: String(url), method: options.method, body: JSON.parse(options.body) }
    return jsonResponse({
      tenant_id: 'tenant-a',
      recommended_model: 'pilot_collecting',
      evidence_status: 'unavailable',
      scenarios: [],
      notes: ['不会自动修改套餐']
    })
  })
  try {
    const response = await buildCommercialPricingScenario('tenant/a', {
      start: '2026-04-01T00:00:00Z',
      end: '2026-07-01T23:59:59Z',
      asOf: '2026-07-02T00:00:00Z',
      targetContributionMarginRate: '0.65',
      maxVerifiedSavingsShare: '0.25'
    })
    assert.equal(response.recommendedModel, 'pilot_collecting')
  } finally {
    restore()
  }

  assert.equal(request.method, 'POST')
  assert.match(request.url, /\/commercial\/admin\/tenants\/tenant%2Fa\/pricing-scenarios$/u)
  assert.deepEqual(Object.keys(request.body).sort(), [
    'as_of',
    'end',
    'max_verified_savings_share',
    'start',
    'target_contribution_margin_rate'
  ])
  assert.equal(request.body.target_contribution_margin_rate, '0.65')
  assert.equal(request.body.max_verified_savings_share, '0.25')
})

test('商业写接口覆盖套餐、订阅、权益、激活、用量与成本并统一递归序列化', async () => {
  const requests = []
  const restore = installFetch(async (url, options = {}) => {
    requests.push({ url: String(url), method: options.method, headers: options.headers, body: JSON.parse(options.body) })
    return jsonResponse({ id: 'resource-1', created: true })
  })
  try {
    await createCommercialPlan('tenant-a', { planCode: 'enterprise', contractTermsJson: { approvedBy: 'cfo' } })
    await activateCommercialPlan('tenant-a', 'plan-1', 2, '启用新套餐版本')
    await createCommercialSubscription('tenant-a', { subscriptionKey: 'sub-1', autoRenew: true })
    await activateCommercialSubscription('tenant-a', 'sub-1', 3, '恢复客户订阅')
    await transitionCommercialSubscription('tenant-a', 'sub-1', { expectedVersion: 4, targetStatus: 'suspended', reason: '合同暂停' })
    await upsertCommercialEntitlement('tenant-a', { entitlementKey: 'ocr', configJson: { billingMode: 'all_usage' } })
    await activateCommercialEntitlement('tenant-a', 'ent-1', 4, '恢复 OCR 权益')
    await recordCommercialUsage('tenant-a', { idempotencyKey: 'usage-1', subjectType: 'claim' })
    await recordCommercialCost('tenant-a', { idempotencyKey: 'cost-1', originalCurrency: 'CNY' })
  } finally {
    restore()
  }

  assert.deepEqual(requests.map((item) => item.method), ['POST', 'POST', 'POST', 'POST', 'POST', 'PUT', 'POST', 'POST', 'POST'])
  assert.match(requests[0].url, /\/plans$/u)
  assert.equal(requests[0].body.contract_terms_json.approved_by, 'cfo')
  assert.equal(requests[1].body.expected_version, 2)
  assert.equal(requests[1].body.reason, '启用新套餐版本')
  assert.ok(requests.every((item) => item.headers['X-Request-Id']))
  assert.equal(requests[2].body.auto_renew, true)
  assert.match(requests[4].url, /\/subscriptions\/sub-1\/transition$/u)
  assert.equal(requests[4].body.target_status, 'suspended')
  assert.equal(requests[5].body.config_json.billing_mode, 'all_usage')
  assert.match(requests[7].url, /\/usage-events$/u)
  assert.match(requests[8].url, /\/cost-events$/u)
})

test('五类商业历史按最终分资源契约读取并正确序列化筛选', async () => {
  const urls = []
  const restore = installFetch(async (url) => {
    urls.push(String(url))
    return jsonResponse([])
  })
  try {
    await fetchCommercialPlans('tenant-a', { planStatus: 'active', limit: 20, offset: 1 })
    await fetchCommercialSubscriptions('tenant-a', { subscriptionStatus: 'suspended' })
    await fetchCommercialEntitlements('tenant-a', { subscriptionId: 'sub-1', entitlementStatus: 'active' })
    await fetchCommercialUsageEvents('tenant-a', { subscriptionId: 'sub-1', start: '2026-07-01T00:00:00Z', end: '2026-08-01T00:00:00Z' })
    await fetchCommercialCostEvents('tenant-a', { limit: 50 })
  } finally {
    restore()
  }
  assert.match(urls[0], /\/plans\?plan_status=active&limit=20&offset=1$/u)
  assert.match(urls[1], /\/subscriptions\?subscription_status=suspended$/u)
  assert.match(urls[2], /\/entitlements\?subscription_id=sub-1&entitlement_status=active$/u)
  assert.match(urls[3], /\/usage-events\?subscription_id=sub-1&start=.*&end=.*/u)
  assert.match(urls[4], /\/cost-events\?limit=50$/u)
})

test('后端权限和冲突错误保留状态与可执行提示', async () => {
  const restore = installFetch(async () => jsonResponse({ detail: '只有平台管理员可以执行该操作。' }, 403))
  try {
    await assert.rejects(
      () => fetchCommercialAnalytics('tenant-a'),
      (error) => error.status === 403 && /平台管理员/u.test(error.message)
    )
  } finally {
    restore()
  }
})
