import type { ScreenData, TimeRange } from './screen';
import { FieldTracker, resolveDataMode, type ScreenDataMode } from './screen-field-meta';
import { structureScreen } from './screen-structure';

export type { ScreenDataMode };

export interface ResolvedScreenData {
	data: ScreenData;
	mode: ScreenDataMode;
	demoFields: string[];
	liveFields: string[];
}

function num(v: unknown, fallback = 0) {
	const n = Number(v);
	return Number.isFinite(n) ? n : fallback;
}

function alignSeries(source: number[] | undefined, len: number) {
	const values = (source || []).map(v => num(v));
	if (!values.length) return Array.from({ length: len }, () => 0);
	if (values.length === len) return values;
	if (values.length > len) return values.slice(values.length - len);
	return [...Array.from({ length: len - values.length }, () => 0), ...values];
}

/** 用接口结果覆盖零值结构。缺字段保持 0 或空列表，不再回落到演示数据。 */
export function resolveScreenData(live: ScreenData | null | undefined, range: TimeRange): ResolvedScreenData {
	const base = structureScreen(range);
	const ctx = new FieldTracker();

	if (!live) {
		return {
			data: base,
			mode: 'live',
			demoFields: [],
			liveFields: []
		};
	}

	const axis = live.axis?.length ? live.axis : base.axis;
	ctx.markLive('axis');

	const kpis = { ...base.kpis };
	Object.keys(kpis).forEach(key => {
		if (live.kpis && live.kpis[key] != null) {
			kpis[key] = num(live.kpis[key]);
		}
		ctx.markLive(`kpis.${key}`);
	});

	const wasteMix = live.wasteMix?.length
		? live.wasteMix.map((item, i) => ({
				...base.wasteMix[i],
				...item,
				weight: num(item.weight),
				value: num(item.value),
				count: num(item.count),
				color: item.color || base.wasteMix[i]?.color
			}))
		: base.wasteMix;
	ctx.markLive('wasteMix');

	const recycleItems = live.recycleItems?.length
		? live.recycleItems.map((item, i) => ({
				...base.recycleItems[i],
				...item,
				weight: num(item.weight),
				value: num(item.value),
				carbon: num(item.carbon),
				color: item.color || base.recycleItems[i]?.color
			}))
		: base.recycleItems;
	ctx.markLive('recycleItems');

	const trend = {
		weight: alignSeries(live.trend?.weight, axis.length),
		value: alignSeries(live.trend?.value, axis.length),
		carbon: alignSeries(live.trend?.carbon, axis.length)
	};
	ctx.markLive('trend');

	const yearCarbon = live.yearCarbon?.length
		? alignSeries(live.yearCarbon, 12)
		: base.yearCarbon;
	ctx.markLive('yearCarbon');

	const deptRank = Array.isArray(live.deptRank) ? live.deptRank : [];
	const classRank = Array.isArray(live.classRank) ? live.classRank : [];
	const majorRank = Array.isArray(live.majorRank) ? live.majorRank : [];
	ctx.markLive('deptRank');
	ctx.markLive('classRank');
	ctx.markLive('majorRank');

	const pointFlow = {
		issued: num(live.pointFlow?.issued),
		transfer: num(live.pointFlow?.transfer),
		donate: num(live.pointFlow?.donate),
		mall: num(live.pointFlow?.mall),
		balance: num(live.pointFlow?.balance)
	};
	ctx.markLive('pointFlow');

	const participateTrend = alignSeries(live.participateTrend, axis.length);
	const deliverTrend = alignSeries(live.deliverTrend, axis.length);
	ctx.markLive('participateTrend');
	ctx.markLive('deliverTrend');

	const ordersByType = live.ordersByType?.axis?.length
		? {
				axis: live.ordersByType.axis,
				现场回收: alignSeries(live.ordersByType.现场回收, live.ordersByType.axis.length),
				预约上门: alignSeries(live.ordersByType.预约上门, live.ordersByType.axis.length),
				大屏投递: alignSeries(live.ordersByType.大屏投递, live.ordersByType.axis.length),
				活动回收: alignSeries(live.ordersByType.活动回收, live.ordersByType.axis.length)
			}
		: base.ordersByType;
	ctx.markLive('ordersByType');

	const appointmentFlow = live.appointmentFlow?.length ? live.appointmentFlow : base.appointmentFlow;
	const sorterStatus = live.sorterStatus?.length ? live.sorterStatus : base.sorterStatus;
	const vehicles = Array.isArray(live.vehicles) ? live.vehicles : [];
	const sites = Array.isArray(live.sites) ? live.sites : [];
	ctx.markLive('appointmentFlow');
	ctx.markLive('sorterStatus');
	ctx.markLive('vehicles');
	ctx.markLive('sites');

	const data: ScreenData = {
		range,
		axis,
		kpis,
		wasteMix,
		recycleItems,
		trend,
		yearCarbon,
		deptRank,
		classRank,
		majorRank,
		pointFlow,
		participateTrend,
		deliverTrend,
		ordersByType,
		appointmentFlow,
		sorterStatus,
		vehicles,
		sites,
		unavailable: live.unavailable || []
	};

	return {
		data,
		mode: resolveDataMode(live, ctx),
		demoFields: [],
		liveFields: ctx.listLive()
	};
}

/** 接口尚未返回时先展示零值，避免先闪出演示数字 */
export function initialScreenData(range: TimeRange = 'month') {
	return resolveScreenData(null, range);
}

export { structureScreen, buildScreenAxis } from './screen-structure';
