<template>
	<view class="report">
		<view class="modes">
			<view class="mode-tab" :class="{active: mode==='sale'}" @click="setMode('sale')">销售统计</view>
			<view class="mode-tab" :class="{active: mode==='purchase'}" @click="setMode('purchase')">进货统计</view>
			<view class="mode-tab" :class="{active: mode==='inventory'}" @click="setMode('inventory')">库存统计</view>
			<view class="mode-tab" :class="{active: mode==='arap'}" @click="setMode('arap')">应收/应付对账</view>
		</view>

		<view class="toolbar">
			<picker mode="date" :value="startDate" @change="onStartChange"><view class="date">{{ startDate }}</view></picker>
			<text style="margin: 0 8rpx;">—</text>
			<picker mode="date" :value="endDate" @change="onEndChange"><view class="date">{{ endDate }}</view></picker>
		</view>

        <view class="tabs" v-if="mode==='sale'">
            <view class="tab" :class="{active: dim==='customer'}" @click="dim='customer'; refresh()">按客户</view>
            <view class="tab" :class="{active: dim==='product'}" @click="dim='product'; refresh()">按货品</view>
        </view>
        <view class="tabs" v-else-if="mode==='purchase'">
            <view class="tab" :class="{active: dim==='supplier'}" @click="dim='supplier'; refresh()">按供应商</view>
            <view class="tab" :class="{active: dim==='product'}" @click="dim='product'; refresh()">按货品</view>
        </view>
        <view class="tabs" v-else-if="mode==='inventory'">
            <view class="tab" :class="{active: dim==='qty'}" @click="dim='qty'; refresh()">按数量</view>
            <view class="tab" :class="{active: dim==='amount'}" @click="dim='amount'; refresh()">按金额</view>
        </view>
        <view class="tabs" v-else-if="mode==='arap'">
            <view class="tab" :class="{active: dim==='ar'}" @click="dim='ar'; refresh()">应收对账</view>
            <view class="tab" :class="{active: dim==='ap'}" @click="dim='ap'; refresh()">应付对账</view>
        </view>

		<view class="summary">
			<view class="item"><text class="label">销售额</text><text class="value">￥ {{ fmt(total.sales) }}</text></view>
			<view class="item"><text class="label">成本</text><text class="value">￥ {{ fmt(total.cost) }}</text></view>
			<view class="item"><text class="label">利润</text><text class="value">￥ {{ fmt(total.profit) }}</text></view>
			<view class="item"><text class="label">利润率</text><text class="value">{{ profitRate }}</text></view>
		</view>

		<view v-for="(row, idx) in rows" :key="idx" class="card">
			<view class="row-head">
				<image v-if="row.avatar" class="thumb" :src="row.avatar" />
				<view class="title">{{ row.name }}</view>
			</view>
			<view class="row-body">
				<text>销售额：￥ {{ fmt(row.sales) }}</text>
				<text style="margin-left: 18rpx;">成本：￥ {{ fmt(row.cost) }}</text>
				<text style="margin-left: 18rpx;">利润：￥ {{ fmt(row.profit) }}</text>
			</view>
		</view>
	</view>
</template>

<script>
import { get } from '../../common/http.js'

function formatDate(d) {
	const y = d.getFullYear()
	const m = String(d.getMonth()+1).padStart(2, '0')
	const day = String(d.getDate()).padStart(2, '0')
	return `${y}-${m}-${day}`
}

export default {
	data() {
		const now = new Date()
		const start = new Date(now.getFullYear(), now.getMonth(), 1)
		return {
			startDate: formatDate(start),
			endDate: formatDate(now),
			mode: 'sale',
            dim: 'customer',
			rows: [],
			total: { sales: 0, cost: 0, profit: 0 }
		}
	},
    onLoad(query) {
        try {
            const m = query && query.mode
            const d = query && query.dim
            if (m) this.mode = m
            if (d) this.dim = d
        } catch(e){}
        this.refresh()
    },
	computed: {
		profitRate() {
			const { sales, profit } = this.total
			if (!sales) return '0.00%'
			return ((profit / sales) * 100).toFixed(2) + '%'
		}
	},
	methods: {
		fmt(n) { return Number(n || 0).toFixed(2) },
		setMode(m) {
			this.mode = m
			this.dim = m === 'sale' ? 'customer' : m === 'purchase' ? 'supplier' : m === 'inventory' ? 'qty' : 'ar'
			this.refresh()
		},
		onStartChange(e) { this.startDate = e.detail.value; this.refresh() },
		onEndChange(e) { this.endDate = e.detail.value; this.refresh() },
		async refresh() {
            if (this.mode === 'sale') {
                if (this.dim === 'customer') return this.loadByCustomer()
                if (this.dim === 'product') return this.loadByProduct()
            }
            if (this.mode === 'purchase') {
                if (this.dim === 'supplier') return this.loadPurchaseBySupplier()
                if (this.dim === 'product') return this.loadPurchaseByProduct()
            }
            if (this.mode === 'inventory') {
                if (this.dim === 'qty') return this.loadInventoryByQty()
                if (this.dim === 'amount') return this.loadInventoryByAmount()
            }
            if (this.mode === 'arap') {
                if (this.dim === 'ar') return this.loadAR()
                if (this.dim === 'ap') return this.loadAP()
            }
		},
		async loadByCustomer() {
			// 数据来源：/api/orders?biz=sale&type=out 与 /api/products/{id} 获取成本(近似)，或由订单明细返回单价与估算成本
			// 当前后端列表返回字段包含 amount、customerName，缺少明细成本；采用二段法：
			// 1) 列表聚合销售额；2) 如存在 productId 与单位进价可获取成本；暂以 0 成本占位，保留接口演进点。
			try {
				const listResp = await get('/api/orders', { biz: 'sale', type: 'out', startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 })
				const list = (listResp && (listResp.list || listResp)) || []
				const map = new Map()
				let totalSales = 0
				for (const it of list) {
					const name = it.customerName || '未知客户'
					const amount = Number(it.amount || 0)
					totalSales += amount
					if (!map.has(name)) map.set(name, { name, sales: 0, cost: 0, profit: 0 })
					const row = map.get(name)
					row.sales += amount
				}
				const rows = Array.from(map.values()).map(r => ({ ...r, profit: r.sales - r.cost }))
				const total = { sales: totalSales, cost: 0, profit: totalSales }
				this.rows = rows
				this.total = total
			} catch (e) {
				uni.showToast({ title: '加载失败', icon: 'none' })
			}
		},
		async loadByProduct() {
			try {
				const listResp = await get('/api/orders', { biz: 'sale', type: 'out', startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 })
				const list = (listResp && (listResp.list || listResp)) || []
				// 订单详情接口包含明细，逐单补拉详情聚合（规模较小时可接受；后端如提供汇总接口可替换）
				const agg = new Map()
				for (const it of list) {
					try {
						const d = await get(`/api/orders/${it.id}`)
						const items = d && d.items || []
						for (const m of items) {
							const key = String(m.productId || m.name)
							if (!agg.has(key)) agg.set(key, { name: m.name || ('#'+key), sales: 0, cost: 0, profit: 0 })
							const row = agg.get(key)
							const sales = Number(m.amount || 0)
							// 近似成本：缺后端返回进价，暂以 0（待后端扩展返回 purchasePrice）
							row.sales += sales
						}
					} catch(_) {}
				}
				const rows = Array.from(agg.values()).map(r => ({ ...r, profit: r.sales - r.cost }))
				const totalSales = rows.reduce((s, r) => s + r.sales, 0)
				this.rows = rows
				this.total = { sales: totalSales, cost: 0, profit: totalSales }
            } catch (e) {
                uni.showToast({ title: '加载失败', icon: 'none' })
            }
            },
        async loadPurchaseBySupplier() {
            try {
                const listResp = await get('/api/purchase-orders', { startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 })
                const list = (listResp && (listResp.list || listResp)) || []
                const map = new Map(); let total = 0
                for (const it of list) {
                    const name = it.supplierName || '未知供应商'
                    const amount = Number(it.amount || 0)
                    total += amount
                    if (!map.has(name)) map.set(name, { name, sales: 0, cost: 0, profit: 0 })
                    const row = map.get(name)
                    // 在进货统计语境里：sales 用来展示“进货额”，cost/profit 保持 0
                    row.sales += amount
                }
                this.rows = Array.from(map.values())
                this.total = { sales: total, cost: 0, profit: 0 }
            } catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }
        },
        async loadPurchaseByProduct() {
            try {
                const listResp = await get('/api/purchase-orders', { startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 })
                const list = (listResp && (listResp.list || listResp)) || []
                const agg = new Map()
                for (const it of list) {
                    try {
                        const d = await get(`/api/purchase-orders/${it.id}`)
                        for (const m of (d?.items || [])) {
                            const key = String(m.productId || m.name)
                            if (!agg.has(key)) agg.set(key, { name: m.name || ('#'+key), sales: 0, cost: 0, profit: 0 })
                            const row = agg.get(key)
                            row.sales += Number(m.amount || 0) // 这里的 sales 表示“进货额”
                        }
                    } catch(_){}
                }
                const rows = Array.from(agg.values())
                const total = rows.reduce((s, r)=> s + r.sales, 0)
                this.rows = rows; this.total = { sales: total, cost: 0, profit: 0 }
            } catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }
        },
        async loadInventoryByQty() {
            try {
                const resp = await get('/api/inventories/logs', { startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 })
                const list = (resp && (resp.list || resp)) || []
                const map = new Map(); let totalQty = 0
                for (const it of list) {
                    const key = it.productId || '未知'
                    if (!map.has(key)) map.set(key, { name: String(key), sales: 0, cost: 0, profit: 0 })
                    const row = map.get(key)
                    const q = Number(it.qtyDelta || 0)
                    row.sales += q
                    totalQty += q
                }
                this.rows = Array.from(map.values())
                this.total = { sales: totalQty, cost: 0, profit: 0 }
            } catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }
        },
        async loadInventoryByAmount() {
            try {
                const resp = await get('/api/inventories/logs', { startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 })
                const list = (resp && (resp.list || resp)) || []
                const map = new Map(); let totalAmt = 0
                for (const it of list) {
                    const key = it.productId || '未知'
                    if (!map.has(key)) map.set(key, { name: String(key), sales: 0, cost: 0, profit: 0 })
                    const row = map.get(key)
                    const a = Number(it.amount || it.amountDelta || 0)
                    row.sales += a
                    totalAmt += a
                }
                this.rows = Array.from(map.values())
                this.total = { sales: totalAmt, cost: 0, profit: 0 }
            } catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }
        },
        async loadAR() {
            // 读取客户列表含 receivable 字段，作为对账口径（期末=期初+增加-收回-抹零）；后端如提供期间变动接口再替换
            try {
                const res = await get('/api/customers', { page: 1, size: 100, debtOnly: false })
                const list = Array.isArray(res?.list) ? res.list : (Array.isArray(res) ? res : [])
                const rows = list.map(c => ({ name: c.name, sales: Number(c.receivable || 0), cost: 0, profit: 0 }))
                const total = rows.reduce((s, r)=> s + r.sales, 0)
                this.rows = rows; this.total = { sales: total, cost: 0, profit: 0 }
            } catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }
        },
        async loadAP() {
            // 供应商暂未返回应付字段，先展示总览为0并提示后端扩展（遵循“不开假数据”）
            try {
                const res = await get('/api/suppliers', { page: 1, size: 100 })
                const list = Array.isArray(res?.list) ? res.list : (Array.isArray(res) ? res : [])
                const rows = list.map(s => ({ name: s.name, sales: Number(s.apPayable || 0), cost: 0, profit: 0 }))
                const total = rows.reduce((s, r)=> s + r.sales, 0)
                this.rows = rows; this.total = { sales: total, cost: 0, profit: 0 }
            } catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }
        }
}
}
</script>

<style>
.report { padding: 20rpx; }
.modes { display: flex; gap: 12rpx; margin-bottom: 14rpx; }
.mode-tab { flex: 1; text-align: center; padding: 16rpx 0; border-radius: 999rpx; background: #f4f4f4; color: #666; border: 1rpx solid #e9e9e9; }
.mode-tab.active { background: #1aad19; color: #fff; border-color: #1aad19; font-weight: 700; }
.toolbar { display: flex; align-items: center; gap: 8rpx; background: #fff; padding: 14rpx 16rpx; border-radius: 12rpx; }
.date { padding: 10rpx 16rpx; border: 1rpx solid #eee; border-radius: 8rpx; }
.tabs { display: flex; gap: 16rpx; margin-top: 14rpx; }
.tab { padding: 12rpx 18rpx; border-radius: 999rpx; background: #f4f4f4; color: #666; }
.tab.active { background: #1aad19; color: #fff; }
.summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8rpx; margin-top: 14rpx; }
.summary .item { background: #fff; border-radius: 12rpx; padding: 16rpx; }
.summary .label { font-size: 22rpx; color: #888; }
.summary .value { display: block; margin-top: 8rpx; font-weight: 700; color: #333; }
.card { margin-top: 16rpx; background: #fff; border-radius: 12rpx; padding: 16rpx; }
.row-head { display: flex; align-items: center; gap: 12rpx; }
.thumb { width: 72rpx; height: 72rpx; border-radius: 8rpx; background: #f2f2f2; }
.title { font-size: 28rpx; font-weight: 700; }
.row-body { margin-top: 10rpx; color: #666; }
</style>


