import { createHttpError, type HttpErrorLike } from '../../../utils/http.js'
import { cloudtentaclesRequest } from './http-client.js'
import { resolveCloudtentaclesConfig } from './helpers.js'
import type { JsonObject } from '../../../types/json.js'

export async function getCloudtentaclesAsset(payload: JsonObject = {}) {
  const token = requireToken(
    payload.token,
    'cloudtentacles 余额查询缺少 token',
    'cloudtentacles_asset_missing_token',
  )
  const config = resolveCloudtentaclesConfig(payload)

  const result = await cloudtentaclesRequest(config.assetPath, {
    ...config,
    method: 'GET',
    token,
    contentType: 'application/json',
    sourceKey: payload.sourceKey || payload.resolvedSourceKey,
    accountLabel: payload.accountLabel,
    context: {
      operation: 'asset_get',
      sourceKey: payload.sourceKey || payload.resolvedSourceKey || '',
    },
    businessErrorStatusCode: 401,
    businessErrorCode: 'cloudtentacles_asset_failed',
  })

  return {
    baseUrl: config.baseUrl,
    asset: Number(result.payload?.data || 0),
    raw: result.payload?.data ?? null,
  }
}

export async function getCloudtentaclesCategories(payload: JsonObject = {}) {
  const token = requireToken(
    payload.token,
    'cloudtentacles 分类查询缺少 token',
    'cloudtentacles_categories_missing_token',
  )
  const config = resolveCloudtentaclesConfig(payload)

  const result = await cloudtentaclesRequest(config.categoriesPath, {
    ...config,
    method: 'GET',
    token,
    contentType: 'application/json',
    sourceKey: payload.sourceKey || payload.resolvedSourceKey,
    accountLabel: payload.accountLabel,
    context: {
      operation: 'categories_list',
      sourceKey: payload.sourceKey || payload.resolvedSourceKey || '',
    },
    businessErrorStatusCode: 401,
    businessErrorCode: 'cloudtentacles_categories_failed',
  })

  const items = Array.isArray(result.payload?.data) ? result.payload.data.map(mapCategoryItem) : []

  return {
    baseUrl: config.baseUrl,
    itemCount: items.length,
    items,
    rawItems: Array.isArray(result.payload?.data) ? result.payload.data : [],
  }
}

export async function listCloudtentaclesSku(payload: JsonObject = {}) {
  const token = requireToken(
    payload.token,
    'cloudtentacles SKU 列表查询缺少 token',
    'cloudtentacles_sku_list_missing_token',
  )
  const config = resolveCloudtentaclesConfig(payload)

  const result = await cloudtentaclesRequest(config.skuListPath, {
    ...config,
    method: 'GET',
    token,
    contentType: 'application/json',
    sourceKey: payload.sourceKey || payload.resolvedSourceKey,
    accountLabel: payload.accountLabel,
    context: {
      operation: 'sku_list',
      sourceKey: payload.sourceKey || payload.resolvedSourceKey || '',
    },
    businessErrorStatusCode: 401,
    businessErrorCode: 'cloudtentacles_sku_list_failed',
  })

  const items = Array.isArray(result.payload?.data) ? result.payload.data.map(mapSkuItem) : []

  return {
    baseUrl: config.baseUrl,
    itemCount: items.length,
    items,
    rawItems: Array.isArray(result.payload?.data) ? result.payload.data : [],
  }
}

export async function buyCloudtentaclesSku(payload: JsonObject = {}) {
  const token = requireToken(
    payload.token,
    'cloudtentacles 购买 SKU 缺少 token',
    'cloudtentacles_sku_buy_missing_token',
  )
  const skuId = requireId(
    payload.id,
    'cloudtentacles 购买 SKU 缺少商品 id',
    'cloudtentacles_sku_buy_missing_id',
  )
  const count = requireCount(payload.count)
  const config = resolveCloudtentaclesConfig(payload)

  const result = await cloudtentaclesRequest(config.skuBuyPath, {
    ...config,
    method: 'POST',
    token,
    body: {
      id: skuId,
      count,
    },
    businessErrorStatusCode: 401,
    businessErrorCode: 'cloudtentacles_sku_buy_failed',
    sourceKey: payload.sourceKey || payload.resolvedSourceKey,
    accountLabel: payload.accountLabel,
    context: {
      operation: 'sku_buy',
      skuId,
      count,
      sourceKey: payload.sourceKey,
      accountLabel: payload.accountLabel,
    },
  })

  return {
    baseUrl: config.baseUrl,
    id: skuId,
    count,
    responseMessage: String(result.payload?.message || result.payload?.msg || 'success'),
  }
}

export async function useCloudtentaclesSku(payload: JsonObject = {}) {
  const token = requireToken(
    payload.token,
    'cloudtentacles 发货缺少 token',
    'cloudtentacles_sku_use_missing_token',
  )
  const skuId = requireId(
    payload.id,
    'cloudtentacles 发货缺少商品 id',
    'cloudtentacles_sku_use_missing_id',
  )
  const virtualNumberId = requireId(
    payload.virtualNumberId,
    'cloudtentacles 发货缺少虚拟号 id',
    'cloudtentacles_sku_use_missing_virtual_number_id',
  )
  const phone = String(payload.phone || '').trim()
  if (!phone) {
    throw createHttpError('cloudtentacles 发货缺少手机号', {
      statusCode: 400,
      errorCode: 'cloudtentacles_sku_use_missing_phone',
    })
  }

  const config = resolveCloudtentaclesConfig(payload)
  const result = await useCloudtentaclesSkuRequest({
    ...config,
    token,
    skuId,
    virtualNumberId,
    phone,
    sourceKey: payload.sourceKey,
    accountLabel: payload.accountLabel,
  })

  const responseData = isPlainObject(result.payload?.data) ? result.payload.data : {}

  return {
    baseUrl: config.baseUrl,
    id: skuId,
    virtualNumberId,
    phone,
    sendType: Number(responseData.send_type || 0),
    note: String(responseData.note || '').trim(),
    responseMessage: String(result.payload?.message || result.payload?.msg || 'success'),
    raw: result.payload ?? null,
  }
}

async function useCloudtentaclesSkuRequest(payload: JsonObject) {
  try {
    return await cloudtentaclesRequest(payload.skuUsePath, {
      ...payload,
      method: 'POST',
      token: payload.token,
      body: {
        id: payload.skuId,
        virtual_number_id: payload.virtualNumberId,
        phone: payload.phone,
      },
      businessErrorStatusCode: 401,
      businessErrorCode: 'cloudtentacles_sku_use_failed',
      context: {
        operation: 'sku_use',
        skuId: payload.skuId,
        virtualNumberId: payload.virtualNumberId,
        phoneMasked: maskPhone(payload.phone),
        sourceKey: payload.sourceKey,
        accountLabel: payload.accountLabel,
      },
    })
  } catch (error) {
    if (isCloudtentaclesSkuUseLimitMessage(error instanceof Error ? error.message : '')) {
      const currentError = error as Error & HttpErrorLike
      currentError.statusCode = 409
      currentError.errorCode = 'cloudtentacles_sku_use_limit_reached'
    }

    throw error
  }
}

function isCloudtentaclesSkuUseLimitMessage(message: unknown) {
  const normalized = String(message || '').trim()
  return normalized.includes('最大领取次数') || normalized.includes('领取次数')
}

function maskPhone(value: unknown) {
  const text = String(value || '').trim()
  if (text.length <= 4) {
    return text ? '****' : ''
  }

  return `${text.slice(0, 3)}****${text.slice(-4)}`
}

function mapCategoryItem(item: unknown) {
  const source = isPlainObject(item) ? item : {}

  return {
    id: Number(source.id || 0),
    name: String(source.name || '').trim(),
    supplierTag: String(source.supplier_tag || '').trim(),
    description: String(source.description || '').trim(),
    notes: String(source.notes || '').trim(),
    expire: Number(source.expire || 0),
    sendType: Number(source.send_type || 0),
    exchangeUrl: String(source.exchange_url || '').trim(),
    createdAt: String(source.c_time || '').trim(),
    updatedAt: String(source.l_update_time || '').trim(),
    raw: source,
  }
}

function mapSkuItem(item: unknown) {
  const source = isPlainObject(item) ? item : {}

  return {
    id: Number(source.id || 0),
    categoriesId: Number(source.categories_id || 0),
    name: String(source.name || '').trim(),
    description: String(source.desc || '').trim(),
    image: String(source.image || '').trim(),
    inventory: Number(source.inventory || 0),
    price: Number(source.price || 0),
    listingTime: String(source.listing_time || '').trim(),
    delistingTime: String(source.delisting_time || '').trim(),
    buyLimitMin: Number(source.buy_limit_min || 0),
    buyLimitMax: Number(source.buy_limit_max || 0),
    raw: source,
  }
}

function requireToken(value: unknown, message: string, errorCode: string) {
  const token = String(value || '').trim()
  if (!token) {
    throw createHttpError(message, {
      statusCode: 400,
      errorCode,
    })
  }

  return token
}

function requireId(value: unknown, message: string, errorCode: string) {
  const id = Number(value)
  if (!Number.isInteger(id) || id <= 0) {
    throw createHttpError(message, {
      statusCode: 400,
      errorCode,
    })
  }

  return id
}

function requireCount(value: unknown) {
  const count = Number(value)
  if (!Number.isInteger(count) || count <= 0) {
    throw createHttpError('cloudtentacles 购买数量无效', {
      statusCode: 400,
      errorCode: 'cloudtentacles_sku_buy_invalid_count',
    })
  }

  return count
}

function isPlainObject(value: unknown): value is JsonObject {
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
}
