<template>
	<view class="home-container">
		<site-switch-header :site-id="siteId" :site-type-options="siteTypeOptions" :site-address="baseInfo.siteAddress"
			:running-time="baseInfo.runningTime" :site-count="siteOptions.length" @change="selectedSite" />

		<view class="base-info">
			<view class="map-card">
				<image v-if="mapUrl" class="site-map" :src="mapUrl" mode="aspectFill"></image>
				<view v-else class="map-empty">暂无站点位置</view>
			</view>
			<view class="total-card">
				<view class="total-header">
					<view class="title">总累计运行数据</view>
					<view class="total-revenue">
						<text class="label">总收入</text>
						<text class="value">{{ format2(totalRevenueDisplayValue) }}</text>
						<text class="unit">元</text>
					</view>
				</view>
				<uni-grid :column="2" :showBorder="false" :square="false" :highlight="false">
					<uni-grid-item v-for="(item, index) in runningDataCards" :key="index + 'sjglData'">
						<view class="grid-item-box">
							<view class="title">{{ item.title }}</view>
							<view class="text" :style="{ color: item.color }">
								{{ format2(item.value) }}
							</view>
						</view>
					</uni-grid-item>
				</uni-grid>
			</view>

			<uni-section title="收入曲线" type="line" class="sections-list">
				<view style="width:100%;height: 220px;">
					<qiun-data-charts type="column" :chartData="revenueChartData" :optsWatch='true'
						:inScrollView="true" :pageScrollTop="pageScrollTop" :opts="revenueOptions" :ontouch="true" />
				</view>
			</uni-section>

		</view>
	</view>
</template>

<script>
	import {
		mapGetters
	} from 'vuex'
	import {
		formatDate
	} from '@/utils/filters'
	import {
		getAllSites,
		getSingleSiteBaseInfo,
		getDzjkHomeTotalView,
		getProjectDisplayData,
		getAmmeterRevenueData
	} from '@/api/ems/site.js'
	import SiteSwitchHeader from '@/components/SiteSwitchHeader/index.vue'
	const createSiteTypeOptions = () => ([{
			text: '储能',
			value: 'cn',
			children: []
		},
		{
			text: '光能',
			value: 'gn',
			children: []
		},
		{
			text: '岸电',
			value: 'ad',
			children: []
		}
	])

	export default {
		components: {
			SiteSwitchHeader
		},
		data() {
			return {
				pageScrollTop: 0,
				siteOptions: [],
				siteTypeOptions: createSiteTypeOptions(),
				siteId: '',
				mapUrl: '',
				baseInfo: {},
				runningInfo: {},
				runningDisplayData: [],
				revenueChartData: {},
				revenueOptions: {
					padding: [10, 5, 0, 10],
					dataLabel: false,
					enableScroll: false,
					xAxis: {
						scrollShow: false,
						itemCount: 5,
						disableGrid: true
					},
					yAxis: {
						disabled: false,
						splitNumber: 4
					},
					extra: {}
				},
				fallbackSjglData: [{
						title: "今日充电量（kWh）",
						attr: "dayChargedCap",
						color: '#4472c4'
					},
					{
						title: "今日放电量（kWh）",
						attr: "dayDisChargedCap",
						color: '#70ad47'
					},
					{
						title: "总充电量（kWh）",
						attr: "totalChargedCap",
						color: '#4472c4'
					},
					{
						title: "今日实时收入（元）",
						attr: "dayRevenue",
						color: '#f67438'
					},
					{
						title: "昨日充电量（kWh）",
						attr: "yesterdayChargedCap",
						color: '#4472c4'
					},
					{
						title: "昨日放电量（kWh）",
						attr: "yesterdayDisChargedCap",
						color: '#70ad47'
					},
					{
						title: "总放电量（kWh）",
						attr: "totalDischargedCap",
						color: '#70ad47'
					},
					{
						title: "昨日实时收入（元）",
						attr: "yesterdayRevenue",
						color: '#f67438'
					}
				]
			}
		},
		computed: {
			...mapGetters(['belongSite', 'currentSiteId']),
			totalRunningSectionData() {
				return (this.runningDisplayData || []).filter(item => item.sectionName === '总累计运行数据')
			},
			totalRevenueDisplayItem() {
				const sectionData = this.totalRunningSectionData || []
				const byFieldCode = sectionData.find(item => item.fieldCode === 'totalRevenue')
				if (byFieldCode) {
					return byFieldCode
				}
				return sectionData.find(item => item.fieldName === '总收入')
			},
			totalRevenueDisplayValue() {
				return this.totalRevenueDisplayItem ? this.totalRevenueDisplayItem.fieldValue : this.runningInfo.totalRevenue
			},
			runningDataCards() {
				const sectionData = this.totalRunningSectionData || []
				if (sectionData.length > 0) {
					const revenueFieldCode = this.totalRevenueDisplayItem ? this.totalRevenueDisplayItem.fieldCode : ''
					return sectionData
						.filter(item => item.fieldCode !== revenueFieldCode)
						.map((item, index) => ({
							title: item.fieldName,
							value: item.fieldValue,
							color: this.getCardColor(index)
						}))
				}
				return this.fallbackSjglData.map(item => ({
					title: item.title,
					value: this.runningInfo[item.attr],
					color: item.color
				}))
			}
		},
		methods: {
			isAvailableSite(siteId) {
				const site = this.siteOptions.find(item => item.value === siteId)
				return !!(site && !site.disable)
			},
			getCardColor(index) {
				const colors = ['#4472c4', '#70ad47', '#4472c4', '#f67438', '#4472c4', '#70ad47', '#70ad47', '#f67438']
				return colors[index % colors.length]
			},
			format2(value) {
				const num = Number(value || 0)
				return Number.isFinite(num) ? num.toFixed(2) : '0.00'
			},
			getLastDaysRange(days = 7) {
				const end = new Date()
				const start = new Date(end.getTime() - (days - 1) * 24 * 60 * 60 * 1000)
				return [formatDate(start), formatDate(end)]
			},
			buildDateList(start, end) {
				const list = []
				const startTime = new Date(start).getTime()
				const endTime = new Date(end).getTime()
				const dayMs = 24 * 60 * 60 * 1000
				for (let t = startTime; t <= endTime; t += dayMs) {
					list.push(formatDate(t))
				}
				return list
			},
			selectedSite(data) {
				const siteObj = (data.detail.value || [])[1]
				const value = siteObj?.value
				if (!value) return
				if (value === this.siteId) return
				this.siteId = value
				this.$store.commit('SET_CURRENTSITEID', value)
				this.updateSiteInfo()
			},
			updateSiteInfo() {
				if (!this.siteId) {
					this.baseInfo = {}
					this.runningInfo = {}
					this.runningDisplayData = []
					this.revenueChartData = {}
					this.mapUrl = ''
					return
				}
				this.updateMapCenter()
				this.getSiteBaseInfo()
				this.getRunningInfo()
				this.getRevenueChartData()
			},
			getSiteBaseInfo() {
				return getSingleSiteBaseInfo({
					siteId: this.siteId
				}).then(response => {
					this.baseInfo = response?.data || {}
				})
			},
			getSiteList() {
				getAllSites().then(response => {
					const data = response?.data || []
					const canAccessAll = !this.belongSite || this.belongSite.length === 0 || this.belongSite.includes('all')
					const siteTypeOptions = createSiteTypeOptions().map(item => ({
						...item,
						children: []
					}))
					data.forEach(item => {
						if (!canAccessAll && !this.belongSite.includes(item.siteId)) return
						const siteType = (item.siteType || item.type || 'cn').toString().toLowerCase()
						const typeOption = siteTypeOptions.find(i => i.value === siteType) || siteTypeOptions.find(i => i.value === 'cn')
						if (!typeOption) return
						typeOption.children.push({
							text: item.siteName,
							value: item.siteId,
							id: item.id,
							longitude: Number(item.longitude || 0),
							latitude: Number(item.latitude || 0)
						})
					})
					this.siteTypeOptions = siteTypeOptions.filter(item => (item.children || []).length > 0)
					this.siteOptions = this.siteTypeOptions.reduce((result, typeItem) => {
						return result.concat(typeItem.children || [])
					}, [])
					const defaultSiteId = this.isAvailableSite(this.currentSiteId) ? this.currentSiteId : (this.siteOptions[0]?.value || '')
					if (defaultSiteId) {
						this.siteId = defaultSiteId
						this.$store.commit('SET_CURRENTSITEID', defaultSiteId)
						this.updateSiteInfo()
					}
				})
			},
			updateMapCenter() {
				const site = this.siteOptions.find(item => item.value === this.siteId)
				if (!site || !site.latitude || !site.longitude) {
					this.mapUrl = ''
					return
				}
				const lat = Number(site.latitude)
				const lon = Number(site.longitude)
				const zoom = 12
				const width = 640
				const height = 360
				const tk = '01e99ab4472430e1c7dbfe4b5db99787'
				const layers = 'vec_c,cva_c'
				this.mapUrl = `https://api.tianditu.gov.cn/staticimage?center=${lon},${lat}&width=${width}&height=${height}&zoom=${zoom}&layers=${layers}&markers=${lon},${lat}&tk=${tk}`
			},
			getRunningInfo() {
				return Promise.all([
					getDzjkHomeTotalView(this.siteId),
					getProjectDisplayData(this.siteId)
				]).then(([homeResponse, displayResponse]) => {
					this.runningInfo = homeResponse?.data || {}
					this.runningDisplayData = displayResponse?.data || []
				})
			},
			getRevenueChartData() {
				const [startTime, endTime] = this.getLastDaysRange(7)
				const dateList = this.buildDateList(startTime, endTime)
				const requests = [getAmmeterRevenueData({
					siteId: this.siteId,
					startTime,
					endTime,
					pageSize: 200,
					pageNum: 1
				}).then(response => response?.rows || [])]
				Promise.all(requests).then(list => {
					const rows = list[0] || []
					const categories = dateList.map(day => day.slice(5))
					const sumMap = {}
					dateList.forEach(day => {
						sumMap[day] = 0
					})
					rows.forEach(row => {
						const day = row.dataTime || row.statisDate || row.date
						if (!day) return
						if (!Object.prototype.hasOwnProperty.call(sumMap, day)) {
							sumMap[day] = 0
						}
						const value = Number(row.actualRevenue || row.revenue || 0)
						sumMap[day] += Number.isFinite(value) ? value : 0
					})
					const series = [{
						name: '收入',
						data: dateList.map(day => Number((sumMap[day] || 0).toFixed(2)))
					}]
					const values = series[0].data
					let minVal = Math.min(...values)
					let maxVal = Math.max(...values)
					if (!Number.isFinite(minVal)) minVal = 0
					if (!Number.isFinite(maxVal)) maxVal = 0
					if (minVal === maxVal) {
						minVal -= 1
						maxVal += 1
					}
					const lower = Math.min(minVal, 0)
					const upper = Math.max(maxVal, 0)
					const padding = Math.max((upper - lower) * 0.1, 1)
					this.revenueOptions = {
						...this.revenueOptions,
						yAxis: {
							...(this.revenueOptions.yAxis || {}),
							data: [{
								min: lower - padding,
								max: upper + padding,
								format: (val) => Number(val).toFixed(2)
							}]
						},
						extra: {
							...(this.revenueOptions.extra || {}),
							markLine: {
								type: 'solid',
								data: [{
									value: 0,
									lineColor: '#ff4d4f',
									showLabel: true,
									labelText: '0',
									labelFontColor: '#ff4d4f',
									labelBgColor: '#fff1f0',
									labelBgOpacity: 0.9,
									labelAlign: 'left'
								}]
							}
						}
					}
					this.revenueChartData = JSON.parse(JSON.stringify({
						categories,
						series
					}))
				})
			}
		},
		watch: {
			currentSiteId(newSiteId) {
				if (!newSiteId || newSiteId === this.siteId) return
				if (!this.isAvailableSite(newSiteId)) return
				this.siteId = newSiteId
				this.updateSiteInfo()
			}
		},
		onLoad() {
			this.$nextTick(() => {
				this.getSiteList()
			})
		},
		onPageScroll(e) {
			this.pageScrollTop = e.scrollTop
		}
	}
</script>

<style lang="scss" scoped>
	/* #ifndef APP-NVUE */
	page {
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		background-color: #fff;
		min-height: 100%;
		height: auto;
		font-size: 26rpx;
		line-height: 30rpx;
	}

	view {
		line-height: inherit;
	}

	/* #endif */

	.home-container {
		background-color: #fff;
		padding-top: 0;
	}

	.base-info {
		margin-top: -80rpx;
		border-radius: 80rpx 80rpx 0 0;
		padding: 30rpx;
		background-color: #fff;

		.map-card {
			border-radius: 16rpx;
			overflow: hidden;
			box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.08);
			margin-top: 30rpx;
			background: #f3f5f8;

			.site-map {
				width: 100%;
				height: 220px;
			}

			.map-empty {
				height: 220px;
				display: flex;
				align-items: center;
				justify-content: center;
				color: #8a8f98;
				font-size: 24rpx;
			}
		}

		.total-card {
			margin-top: 30rpx;
			border-radius: 16rpx;
			box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.08);
			padding: 20rpx;

			.total-header {
				display: flex;
				justify-content: space-between;
				align-items: center;
				margin-bottom: 20rpx;

				.title {
					font-weight: 700;
					font-size: 28rpx;
				}

				.total-revenue {
					display: flex;
					align-items: baseline;
					gap: 6rpx;
					font-size: 22rpx;
					color: #19242d;

					.value {
						font-size: 28rpx;
						font-weight: 700;
						color: #f67438;
					}
				}
			}

			.grid-item-box {
				padding-top: 6rpx;
				padding-bottom: 6rpx;
				text-align: left;

				.title {
					font-size: 22rpx;
					color: #666;
				}

				.text {
					margin-top: 10rpx;
					font-size: 26rpx;
					font-weight: 600;
				}
			}
		}

		.sections-list {
			margin-bottom: 10rpx;

			::v-deep &>.uni-section-header {
				font-weight: 700;
				font-size: 26rpx;
				line-height: 30rpx;
			}
		}

		.sections-list:not(:first-child) {
			margin-top: 40rpx;
		}
	}
</style>
