<template>
  <div class="profit-breakdown">
    <!-- 第1行：营收 -->
    <div class="pb-row pb-row-top">
      <div class="pb-card pb-card-revenue">
        <div class="pb-label">营收</div>
        <div class="pb-value">{{ fmt(revenue) }}</div>
      </div>
      <div class="pb-arrow">−</div>
      <div class="pb-card pb-card-expense">
        <div class="pb-label">成本费用</div>
        <div class="pb-value pb-neg">{{ fmt(cost) }}</div>
      </div>
    </div>

    <!-- 等号 + 结果 -->
    <div class="pb-eq-row">
      <div class="pb-eq-line"></div>
      <div class="pb-eq-sign">=</div>
      <div class="pb-eq-line"></div>
    </div>

    <!-- 第2行：毛利额 -->
    <div class="pb-row">
      <div class="pb-card pb-card-gross">
        <div class="pb-label">毛利润</div>
        <div class="pb-value" :class="gross >= 0 ? 'pb-pos' : 'pb-neg'">{{ fmt(gross) }}</div>
        <div class="pb-sub">毛利率 {{ grossRate }}</div>
      </div>
    </div>

    <!-- 费用拆解 -->
    <div v-if="hasDetail" class="pb-detail">
      <div class="pb-detail-title">费用构成</div>
      <div class="pb-detail-grid">
        <div v-for="item in detailItems" :key="item.key" class="pb-detail-item">
          <span class="pb-dot" :style="{ background: item.color }"></span>
          <span class="pb-detail-label">{{ item.label }}</span>
          <span class="pb-detail-val" :class="item.val >= 0 ? 'pb-pos' : 'pb-neg'">{{ fmt(item.val) }}</span>
        </div>
      </div>
    </div>

    <!-- 分割线 -->
    <div class="pb-eq-row">
      <div class="pb-eq-line"></div>
      <div class="pb-eq-sign">=</div>
      <div class="pb-eq-line"></div>
    </div>

    <!-- 最终结果：净利润 -->
    <div class="pb-row">
      <div class="pb-card pb-card-net" :class="profit >= 0 ? 'pb-card-pos' : 'pb-card-neg'">
        <div class="pb-label">净利润</div>
        <div class="pb-value pb-big" :class="profit >= 0 ? 'pb-pos' : 'pb-neg'">{{ fmt(profit) }}</div>
        <div class="pb-sub">净利率 {{ netRate }}</div>
      </div>
    </div>

    <!-- 同期对比 -->
    <div v-if="prevRevenue" class="pb-compare">
      <div class="pb-compare-item">
        <span class="pb-compare-label">营收较上期</span>
        <span :class="revChg >= 0 ? 'pb-pos' : 'pb-neg'">
          {{ revChg >= 0 ? '↑' : '↓' }} {{ (Math.abs(revChg) * 100).toFixed(1) }}%
        </span>
      </div>
      <div class="pb-compare-item">
        <span class="pb-compare-label">净利润较上期</span>
        <span :class="profitChg >= 0 ? 'pb-pos' : 'pb-neg'">
          {{ profitChg >= 0 ? '↑' : '↓' }} {{ (Math.abs(profitChg) * 100).toFixed(1) }}%
        </span>
      </div>
      <div class="pb-compare-item">
        <span class="pb-compare-label">净利率较上期</span>
        <span :class="rateChg >= 0 ? 'pb-pos' : 'pb-neg'">
          {{ rateChg >= 0 ? '↑' : '↓' }} {{ (Math.abs(rateChg) * 100).toFixed(1) }}%
        </span>
      </div>
    </div>

    <!-- 小结 -->
    <div class="pb-summary">
      <div class="pb-bar-track">
        <div class="pb-bar-label">每100元营收中</div>
        <div class="pb-bar-wrap">
          <div class="pb-bar-seg" :style="barStyle.revenue">营收 100</div>
        </div>
        <div class="pb-bar-wrap">
          <div class="pb-bar-seg pb-bar-cost" :style="barStyle.cost">成本 {{ costRate }}</div>
        </div>
        <div class="pb-bar-wrap">
          <div class="pb-bar-seg" :class="profit >= 0 ? 'pb-bar-profit' : 'pb-bar-loss'" :style="barStyle.profit">
            利润 {{ netRate }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'

const props = defineProps<{
  revenue: number
  cost: number       // 成本费用合计
  profit: number      // 净利润
  // 可选：费用明细
  detail?: { key: string; label: string; val: number; color?: string }[]
  // 可选：上期数据
  prevRevenue?: number
  prevProfit?: number
}>()

const hasDetail = computed(() => props.detail && props.detail.length > 0)

const gross = computed(() => props.revenue - props.cost)
const grossRate = computed(() => {
  if (!props.revenue) return '—'
  return ((props.revenue - props.cost) / props.revenue * 100).toFixed(1) + '%'
})
const netRate = computed(() => {
  if (!props.revenue) return '—'
  return (props.profit / props.revenue * 100).toFixed(1) + '%'
})
const costRate = computed(() => {
  if (!props.revenue) return '—'
  return (props.cost / props.revenue * 100).toFixed(1) + '%'
})

const revChg = computed(() => {
  if (!props.prevRevenue) return 0
  return (props.revenue - props.prevRevenue) / props.prevRevenue
})
const profitChg = computed(() => {
  if (!props.prevProfit) return 0
  return (props.profit - props.prevProfit) / Math.abs(props.prevProfit)
})
const rateChg = computed(() => {
  if (!props.prevRevenue || !props.prevProfit) return 0
  const cur = props.profit / props.revenue
  const prev = props.prevProfit / props.prevRevenue
  return (cur - prev) / Math.abs(prev || 0.01)
})

const detailItems = computed(() => {
  const colors = ['#f56c6c', '#e6a23c', '#909399', '#f8983b', '#d48265']
  return (props.detail || []).map((d, i) => ({
    ...d,
    color: d.color || colors[i % colors.length],
  }))
})

const barStyle = computed(() => {
  const max = props.revenue || 1
  const costPct = Math.min(props.cost / max * 100, 100)
  const profitPct = Math.max(Math.min(props.profit / max * 100, 100), 0)
  return {
    revenue: { width: '100%' },
    cost: { width: costPct + '%' },
    profit: { width: profitPct + '%' },
  }
})

function fmt(v: number | undefined | null): string {
  if (v == null) return '—'
  return '¥' + Math.abs(v).toLocaleString(undefined, { maximumFractionDigits: 0 })
}
</script>

<style scoped>
.profit-breakdown {
  padding: 12px 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* 卡片行（横向） */
.pb-row { display: flex; align-items: stretch; gap: 12px; justify-content: center; flex-wrap: wrap; margin: 8px 0; }
.pb-row-top { }

.pb-card {
  padding: 14px 22px;
  border-radius: 10px;
  min-width: 140px;
  text-align: center;
  background: #f8f9fa;
  border: 1px solid #e8eaed;
  transition: all 0.2s;
}
.pb-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.08); }

.pb-card-revenue { background: #e6f7ff; border-color: #91d5ff; }
.pb-card-expense { background: #fff2f0; border-color: #ffccc7; }
.pb-card-gross { background: #f6ffed; border-color: #b7eb8f; min-width: 180px; }
.pb-card-net { min-width: 180px; }
.pb-card-pos { background: #f0f5ff; border-color: #adc6ff; }
.pb-card-neg { background: #fff1f0; border-color: #ffa39e; }

.pb-arrow { display: flex; align-items: center; font-size: 24px; color: #999; font-weight: 300; }

.pb-label { font-size: 12px; color: #666; margin-bottom: 4px; }
.pb-value { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pb-value.pb-big { font-size: 22px; }
.pb-pos { color: #389e0d; }
.pb-neg { color: #cf1322; }
.pb-sub { font-size: 11px; color: #999; margin-top: 2px; }

/* 等号行 */
.pb-eq-row { display: flex; align-items: center; gap: 10px; margin: 4px 0; justify-content: center; }
.pb-eq-line { flex: 0 1 80px; height: 1px; background: #e0e0e0; }
.pb-eq-sign { font-size: 18px; color: #999; font-weight: 300; }

/* 费用明细 */
.pb-detail { margin: 12px auto; max-width: 400px; background: #fafafa; border-radius: 8px; padding: 12px 16px; border: 1px solid #f0f0f0; }
.pb-detail-title { font-size: 12px; color: #999; margin-bottom: 8px; }
.pb-detail-grid { display: flex; flex-direction: column; gap: 6px; }
.pb-detail-item { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.pb-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.pb-detail-label { flex: 1; color: #555; }
.pb-detail-val { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 80px; text-align: right; }

/* 同期对比 */
.pb-compare { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; margin: 16px 0 0; }
.pb-compare-item { font-size: 12px; color: #666; background: #fafafa; padding: 6px 14px; border-radius: 20px; border: 1px solid #f0f0f0; }
.pb-compare-label { margin-right: 6px; }

/* 底部 100元拆解条 */
.pb-summary { margin: 16px auto 0; max-width: 380px; }
.pb-bar-track { }
.pb-bar-label { font-size: 11px; color: #999; margin-bottom: 6px; }
.pb-bar-wrap { height: 22px; margin-bottom: 3px; border-radius: 4px; overflow: hidden; background: #f5f5f5; }
.pb-bar-seg { height: 100%; border-radius: 4px; font-size: 11px; color: #fff; display: flex; align-items: center; padding-left: 8px; font-weight: 600; }
.pb-bar-cost { background: #ff7875; }
.pb-bar-profit { background: #69b1ff; }
.pb-bar-loss { background: #ff4d4f; }

/* 杜邦拆分树 */</style>
