import { computed, type Ref } from 'vue' import type { ChargeMode, ListingPublishOptions, PublishSalePriceConfig, QuantityKey, ScreenshotKey } from '@/api/listingOptions' import type { PublishForm } from '@/types/publish' import { buildDepositBreakdownItems, calculateConsumablePrice, calculateDailyLossRatioAdjustment, calculatePlatformPricing, calculateRecommendedDeposit, calculateSellerReferenceRatio, formatNumber, hasAcceleratedSaleRatioInput as hasAcceleratedSaleRatioValue, isQuantityItemDisabledForInsurance, readFinalSaleRatio, roundMoney, roundRatio, } from '@/utils/pricing' export function usePricingCalculator(options: { publishOptions: Ref salePriceConfig: Ref form: PublishForm quantityValues: Record quantityModes: Record screenshotFiles: Record selectedSkins: Ref }) { const serverOptions = computed(() => options.publishOptions.value.server_options) const faceOptions = computed(() => options.publishOptions.value.face_options) const rankOptions = computed(() => options.publishOptions.value.rank_options) const insuranceOptions = computed(() => options.publishOptions.value.insurance_options) const levelOptions = computed(() => options.publishOptions.value.level_options) const loginMethodOptions = computed(() => options.publishOptions.value.login_method_options) const regionOptions = computed(() => options.publishOptions.value.region_options) const banRecordOptions = computed(() => options.publishOptions.value.ban_record_options) const banEvidenceOptions = computed(() => options.publishOptions.value.ban_evidence_options) const skinGroups = computed(() => options.publishOptions.value.skin_groups) const quantityItems = computed(() => options.publishOptions.value.quantity_items) const screenshotSlots = computed(() => options.publishOptions.value.screenshot_slots) const priceConfig = computed(() => options.publishOptions.value.price_config) const depositRecommendConfig = computed(() => options.publishOptions.value.deposit_recommend_config) const fireLevelMin = computed(() => options.publishOptions.value.fire_level_min || 38) const fireLevelPlaceholder = computed(() => `等级低于${fireLevelMin.value}级的号无法发布`) const coinMAmount = computed(() => Number(options.form.haf_coin_amount || 0)) const coinWanAmount = computed(() => coinMAmount.value * 100) const dailyLossMAmount = computed(() => Number(options.form.daily_loss_m || 10)) const dailyLossRatioAdjustment = computed(() => calculateDailyLossRatioAdjustment(dailyLossMAmount.value)) const screenshotUrls = computed(() => screenshotSlots.value.map((item) => options.screenshotFiles?.[item.key]).filter((url): url is string => Boolean(url)), ) function hasAcceleratedSaleRatioInput() { return hasAcceleratedSaleRatioValue(options.form.accelerated_sale_ratio) } function isQuantityItemDisabled(item: { key: string; label: string }) { return isQuantityItemDisabledForInsurance(item, options.form.season_insurance) } const calculatedSellerReferenceRatio = computed(() => calculateSellerReferenceRatio({ coinMAmount: coinMAmount.value, form: options.form, ratioConfig: options.publishOptions.value.ratio_config, skinGroups: skinGroups.value, selectedSkins: options.selectedSkins.value, levelOptions: levelOptions.value, dailyLossRatioAdjustment: dailyLossRatioAdjustment.value, }), ) const calculatedDefaultSaleRatio = computed(() => calculatedSellerReferenceRatio.value) const maxAcceleratedSaleRatio = computed(() => calculatedDefaultSaleRatio.value > 0 ? roundRatio(calculatedDefaultSaleRatio.value + 10) : 0, ) const calculatedRatio = computed(() => readFinalSaleRatio( calculatedDefaultSaleRatio.value, options.form.accelerated_sale_ratio, maxAcceleratedSaleRatio.value, ), ) const calculatedCoinBasePrice = computed(() => { if (calculatedRatio.value <= 0) return 0 return roundMoney(coinWanAmount.value / calculatedRatio.value) }) const calculatedConsumablePrice = computed(() => calculateConsumablePrice({ quantityItems: quantityItems.value, quantityValues: options.quantityValues, quantityModes: options.quantityModes, seasonInsurance: options.form.season_insurance, }), ) const calculatedSellerPrice = computed(() => calculatedRatio.value > 0 ? roundMoney(calculatedCoinBasePrice.value + calculatedConsumablePrice.value) : 0, ) const calculatedPlatformPricing = computed(() => calculatePlatformPricing({ coinMAmount: coinMAmount.value, coinWanAmount: coinWanAmount.value, sellerRatio: calculatedRatio.value, sellerCoinBasePrice: calculatedCoinBasePrice.value, sellerTotalPrice: calculatedSellerPrice.value, consumablePrice: calculatedConsumablePrice.value, salePriceConfig: options.salePriceConfig.value, }), ) const calculatedFinalPrice = computed(() => calculatedPlatformPricing.value.buyerTotalPrice) const calculatedRatioText = computed(() => (calculatedRatio.value > 0 ? `1:${formatNumber(calculatedRatio.value)}` : '--')) const calculatedDefaultSaleRatioText = computed(() => calculatedDefaultSaleRatio.value > 0 ? `1:${formatNumber(calculatedDefaultSaleRatio.value)}` : '--', ) const saleRatioRangeText = computed(() => { if (calculatedDefaultSaleRatio.value <= 0) return '完成基础信息后自动计算参考比例' return `可设置 1:${formatNumber(calculatedDefaultSaleRatio.value)} ~ 1:${formatNumber(maxAcceleratedSaleRatio.value)}` }) const acceleratedSaleRatioPlaceholder = computed(() => { if (calculatedDefaultSaleRatio.value <= 0) return '填写资料后自动生成可设置范围' return `默认 ${formatNumber(calculatedDefaultSaleRatio.value)},最高 ${formatNumber(maxAcceleratedSaleRatio.value)}` }) const recommendedDepositAmount = computed(() => calculateRecommendedDeposit({ depositRecommendConfig: depositRecommendConfig.value, skinGroups: skinGroups.value, selectedSkins: options.selectedSkins.value, }), ) const depositBreakdownItems = computed(() => buildDepositBreakdownItems({ depositRecommendConfig: depositRecommendConfig.value, skinGroups: skinGroups.value, selectedSkins: options.selectedSkins.value, }), ) const platformRuleLabel = computed(() => { const labels: Record = { fixed_markup: '固定加价', ratio_subtract: '比例修正', none: '无加价', } return labels[calculatedPlatformPricing.value.ruleType] || calculatedPlatformPricing.value.ruleType }) const publishTitle = computed(() => { const parts = [ options.form.server_region, options.form.rank_level, coinMAmount.value ? `${coinMAmount.value}M哈夫币` : '', ].filter(Boolean) return parts.length ? parts.join(' ') : '待完善账号信息' }) return { serverOptions, faceOptions, rankOptions, insuranceOptions, levelOptions, loginMethodOptions, regionOptions, banRecordOptions, banEvidenceOptions, skinGroups, quantityItems, screenshotSlots, priceConfig, depositRecommendConfig, fireLevelMin, fireLevelPlaceholder, coinMAmount, coinWanAmount, dailyLossMAmount, dailyLossRatioAdjustment, screenshotUrls, calculatedSellerReferenceRatio, calculatedDefaultSaleRatio, maxAcceleratedSaleRatio, calculatedRatio, calculatedCoinBasePrice, calculatedConsumablePrice, calculatedSellerPrice, calculatedPlatformPricing, calculatedFinalPrice, calculatedRatioText, calculatedDefaultSaleRatioText, saleRatioRangeText, acceleratedSaleRatioPlaceholder, recommendedDepositAmount, depositBreakdownItems, platformRuleLabel, publishTitle, hasAcceleratedSaleRatioInput, isQuantityItemDisabled, } }