import { computed, reactive, ref, toValue, watch } from 'vue'

import {
  activateCommercialEntitlement,
  activateCommercialPlan,
  activateCommercialSubscription,
  buildCommercialPricingScenario,
  createCommercialPlan,
  createCommercialSubscription,
  fetchCommercialAccount,
  fetchCommercialAnalytics,
  fetchCommercialCostEvents,
  fetchCommercialEntitlements,
  fetchCommercialPlans,
  fetchCommercialSubscriptions,
  fetchCommercialUsageEvents,
  recordCommercialCost,
  recordCommercialUsage,
  transitionCommercialSubscription,
  upsertCommercialEntitlement
} from '../services/commercial.js'
import {
  buildAnalyticsWindow,
  buildCommercialMutation,
  buildCommercialValueLedgers,
  buildPricingScenarioPayload,
  buildPricingScenarioView,
  buildQuotaRows,
  classifyCommercialAccountState,
  createDefaultCommercialRange
} from '../components/commercial/commercialWorkspaceModel.js'

function resolveBoolean(value) {
  return Boolean(toValue(value))
}

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

export function useCommercialWorkspace(options = {}) {
  const account = ref(null)
  const accountLoading = ref(false)
  const accountError = ref(null)
  const analytics = ref(null)
  const analyticsLoading = ref(false)
  const analyticsError = ref(null)
  const mutationLoading = ref(false)
  const mutationError = ref(null)
  const mutationMessage = ref('')
  const pricingScenario = ref(null)
  const pricingLoading = ref(false)
  const pricingError = ref(null)
  const history = reactive({ plans: [], subscriptions: [], entitlements: [], usageEvents: [], costEvents: [] })
  const historyLoading = ref(false)
  const historyError = ref(null)
  const historyLoaded = ref(false)
  const range = reactive(createDefaultCommercialRange())
  let accountRequestSeq = 0
  let analyticsRequestSeq = 0
  let historyRequestSeq = 0
  let pricingRequestSeq = 0

  const tenantId = computed(() => resolveText(options.tenantId))
  const platformAdmin = computed(() => resolveBoolean(options.platformAdmin))
  const active = computed(() => options.active === undefined || resolveBoolean(options.active))
  const canManage = computed(() => platformAdmin.value && Boolean(tenantId.value))
  const accountState = computed(() => classifyCommercialAccountState({
    loading: accountLoading.value,
    error: accountError.value,
    account: account.value
  }))
  const quotaRows = computed(() => buildQuotaRows(account.value))
  const ledgers = computed(() => buildCommercialValueLedgers(analytics.value))
  const pricingScenarioView = computed(() => buildPricingScenarioView(pricingScenario.value))

  async function loadAccount() {
    if (!active.value) return null
    const requestSeq = ++accountRequestSeq
    accountLoading.value = true
    accountError.value = null
    try {
      const payload = await fetchCommercialAccount({
        tenantId: tenantId.value,
        platformAdmin: platformAdmin.value
      })
      if (requestSeq === accountRequestSeq) account.value = payload
      return payload
    } catch (error) {
      if (requestSeq === accountRequestSeq) accountError.value = error
      throw error
    } finally {
      if (requestSeq === accountRequestSeq) accountLoading.value = false
    }
  }

  async function loadAnalytics() {
    if (!active.value || !platformAdmin.value || !tenantId.value) {
      analyticsRequestSeq += 1
      analytics.value = null
      analyticsError.value = null
      analyticsLoading.value = false
      return null
    }
    const requestSeq = ++analyticsRequestSeq
    analyticsLoading.value = true
    analyticsError.value = null
    try {
      const payload = await fetchCommercialAnalytics(
        tenantId.value,
        buildAnalyticsWindow(range)
      )
      if (requestSeq === analyticsRequestSeq) analytics.value = payload
      return payload
    } catch (error) {
      if (requestSeq === analyticsRequestSeq) analyticsError.value = error
      throw error
    } finally {
      if (requestSeq === analyticsRequestSeq) analyticsLoading.value = false
    }
  }

  async function reload() {
    const operations = [loadAccount()]
    if (platformAdmin.value && tenantId.value) operations.push(loadAnalytics())
    return Promise.allSettled(operations)
  }

  async function loadHistory() {
    if (!active.value || !platformAdmin.value || !tenantId.value) return null
    const requestSeq = ++historyRequestSeq
    historyLoading.value = true
    historyError.value = null
    const listOptions = { limit: 100, offset: 0 }
    const eventOptions = { limit: 200, offset: 0 }
    const requests = [
      ['plans', fetchCommercialPlans(tenantId.value, listOptions)],
      ['subscriptions', fetchCommercialSubscriptions(tenantId.value, listOptions)],
      ['entitlements', fetchCommercialEntitlements(tenantId.value, { ...listOptions, limit: 200 })],
      ['usageEvents', fetchCommercialUsageEvents(tenantId.value, eventOptions)],
      ['costEvents', fetchCommercialCostEvents(tenantId.value, eventOptions)]
    ]
    const results = await Promise.allSettled(requests.map(([, request]) => request))
    if (requestSeq !== historyRequestSeq) return null
    const failures = []
    results.forEach((result, index) => {
      const key = requests[index][0]
      if (result.status === 'fulfilled') history[key] = Array.isArray(result.value) ? result.value : []
      else {
        history[key] = []
        failures.push(`${key}: ${result.reason?.message || '加载失败'}`)
      }
    })
    historyLoaded.value = true
    historyLoading.value = false
    if (failures.length) {
      historyError.value = new Error(`部分商业历史加载失败：${failures.join('；')}`)
    }
    return history
  }

  async function calculatePricingScenario(rawForm) {
    if (!canManage.value) {
      const error = new Error('只有平台管理员可以为显式选择的租户计算定价场景。')
      error.status = 403
      pricingError.value = error
      throw error
    }
    const requestSeq = ++pricingRequestSeq
    pricingLoading.value = true
    pricingError.value = null
    try {
      const payload = buildPricingScenarioPayload(rawForm)
      const response = await buildCommercialPricingScenario(tenantId.value, payload)
      if (requestSeq === pricingRequestSeq) pricingScenario.value = response
      return response
    } catch (error) {
      if (requestSeq === pricingRequestSeq) pricingError.value = error
      throw error
    } finally {
      if (requestSeq === pricingRequestSeq) pricingLoading.value = false
    }
  }

  async function executeMutation(kind, rawForm) {
    if (!canManage.value) {
      const error = new Error('只有平台管理员可以修改商业配置和事实台账。')
      error.status = 403
      throw error
    }
    const payload = buildCommercialMutation(kind, rawForm, account.value)
    mutationLoading.value = true
    mutationError.value = null
    mutationMessage.value = ''
    try {
      let response
      if (kind === 'createPlan') {
        response = await createCommercialPlan(tenantId.value, payload)
      } else if (kind === 'activatePlan') {
        response = await activateCommercialPlan(tenantId.value, payload.resourceId, payload.expectedVersion, payload.reason)
      } else if (kind === 'createSubscription') {
        response = await createCommercialSubscription(tenantId.value, payload)
      } else if (kind === 'activateSubscription') {
        response = await activateCommercialSubscription(tenantId.value, payload.resourceId, payload.expectedVersion, payload.reason)
      } else if (kind === 'transitionSubscription') {
        response = await transitionCommercialSubscription(tenantId.value, payload.resourceId, {
          expectedVersion: payload.expectedVersion,
          targetStatus: payload.targetStatus,
          reason: payload.reason
        })
      } else if (kind === 'upsertEntitlement') {
        response = await upsertCommercialEntitlement(tenantId.value, payload)
      } else if (kind === 'activateEntitlement') {
        response = await activateCommercialEntitlement(tenantId.value, payload.resourceId, payload.expectedVersion, payload.reason)
      } else if (kind === 'recordUsage') {
        response = await recordCommercialUsage(tenantId.value, payload)
      } else if (kind === 'recordCost') {
        response = await recordCommercialCost(tenantId.value, payload)
      } else {
        throw new Error('不支持的商业管理操作。')
      }
      mutationMessage.value = response?.created === false
        ? '相同幂等事件已存在，本次返回原记录。'
        : '操作已完成，并已刷新商业账户与价值分析。'
      await reload()
      if (historyLoaded.value) await loadHistory()
      return response
    } catch (error) {
      mutationError.value = error
      throw error
    } finally {
      mutationLoading.value = false
    }
  }

  watch(
    () => [tenantId.value, platformAdmin.value, active.value],
    ([nextTenantId, nextPlatformAdmin, nextActive], previous = []) => {
      const [previousTenantId, previousPlatformAdmin, previousActive] = previous
      if (!nextActive) return
      if (
        nextTenantId !== previousTenantId
        || nextPlatformAdmin !== previousPlatformAdmin
        || nextActive !== previousActive
      ) {
        pricingRequestSeq += 1
        pricingScenario.value = null
        pricingLoading.value = false
        pricingError.value = null
        historyRequestSeq += 1
        historyLoaded.value = false
        historyLoading.value = false
        historyError.value = null
        Object.keys(history).forEach((key) => { history[key] = [] })
        void reload()
      }
    },
    { immediate: options.immediate !== false }
  )

  return {
    account,
    accountLoading,
    accountError,
    accountState,
    analytics,
    analyticsLoading,
    analyticsError,
    mutationLoading,
    mutationError,
    mutationMessage,
    pricingScenario,
    pricingScenarioView,
    pricingLoading,
    pricingError,
    history,
    historyLoading,
    historyError,
    historyLoaded,
    range,
    tenantId,
    platformAdmin,
    canManage,
    quotaRows,
    ledgers,
    loadAccount,
    loadAnalytics,
    reload,
    loadHistory,
    calculatePricingScenario,
    executeMutation
  }
}
