import { redirect } from "@sveltejs/kit";
import type { PageServerLoad } from "./$types";
import { UserController } from "$lib/domains/user/domain/controller";
import { OrderController } from "$lib/domains/order/domain/controller";
import { OrderRepository } from "$lib/domains/order/data/repository";
import { db } from "@pkg/db";
import { CheckoutFlowRepository } from "$lib/domains/ckflow/repository";
import { CheckoutFlowUseCases } from "$lib/domains/ckflow/usecases";
import { OrderStatus } from "$lib/domains/order/data/entities";
import { SessionOutcome } from "$lib/domains/ckflow/data";

export const load: PageServerLoad = async ({ locals }) => {
	const sess = locals.session;
	if (!sess) {
		return redirect(302, "/auth/login");
	}

	// Load users data
	const userController = new UserController();
	const usersRes = await userController.listChildUsers(sess.userId.toString());

	// Load orders data
	const orderController = new OrderController(new OrderRepository(db));
	const ordersRes = await orderController.listAllOrders();
	const orders = ordersRes.data || [];
	const pendingOrders = orders.filter(
		(o) => o.status === OrderStatus.PENDING_FULLFILLMENT,
	).length;

	// Load checkout flow data
	const ckflowRepo = new CheckoutFlowRepository(db);
	const ckUseCases = new CheckoutFlowUseCases(ckflowRepo);

	// Get active sessions
	const activeSessionsRes = await ckUseCases.getActiveSessionsList();
	const activeSessions = activeSessionsRes.data || [];

	// Get all sessions for historical data
	const historySessionsRes = await ckUseCases.getAllSessionsList(true);
	const historySessions = historySessionsRes.data || [];

	// Calculate session metrics
	const completed = historySessions.filter(
		(s) => s.sessionOutcome === SessionOutcome.COMPLETED,
	).length;
	const abandoned = historySessions.filter(
		(s) => s.sessionOutcome !== SessionOutcome.COMPLETED,
	).length;
	const total = historySessions.length;
	const conversionRate = total > 0 ? Math.round((completed / total) * 100) : 0;

	// Group sessions by day for the chart (last 7 days)
	const sessionsByDay = processSessionsByTimeFrame(historySessions, "week");

	return {
		users: usersRes.error ? [] : usersRes.data,
		orders: {
			total: orders.length,
			pending: pendingOrders,
		},
		sessions: {
			active: activeSessions.length,
			metrics: {
				total,
				completed,
				abandoned,
				conversionRate,
			},
			byTimeFrame: {
				week: sessionsByDay,
			},
		},
		error: usersRes.error,
	};
};

function processSessionsByTimeFrame(sessions: any, timeframe = "week") {
	const groupedData = {} as any;

	if (timeframe === "week") {
		// Group by day of week
		const days = [
			"Sunday",
			"Monday",
			"Tuesday",
			"Wednesday",
			"Thursday",
			"Friday",
			"Saturday",
		];
		const shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

		// Initialize all days
		shortDays.forEach((day) => {
			groupedData[day] = {
				name: day,
				total: 0,
				completed: 0,
				abandoned: 0,
			};
		});

		// Fill with actual data
		sessions.forEach((session: any) => {
			const date = new Date(session.createdAt);
			const day = shortDays[date.getDay()];

			groupedData[day].total++;

			if (session.sessionOutcome === SessionOutcome.COMPLETED) {
				groupedData[day].completed++;
			} else if (session.sessionOutcome !== SessionOutcome.COMPLETED) {
				groupedData[day].abandoned++;
			}
		});

		// Convert to array ordered by days of week
		return shortDays.map((day) => groupedData[day]);
	}

	// Default return if timeframe not handled
	return Object.values(groupedData);
}
