import { type ActionFunction, redirect } from "react-router";
import { z } from "zod";
import { BUILD_SORT_IDENTIFIERS } from "~/db/tables";
import { requireUser } from "~/features/auth/core/user.server";
import * as BuildRepository from "~/features/builds/BuildRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import { errorToastIfFalsy, parseRequestPayload } from "~/utils/remix.server";
import { assertUnreachable } from "~/utils/types";
import { userBuildsPage } from "~/utils/urls";
import {
	_action,
	actualNumber,
	emptyArrayToNull,
	id,
	processMany,
	removeDuplicates,
	safeJSONParse,
} from "~/utils/zod";

export const action: ActionFunction = async ({ request }) => {
	const user = requireUser();
	const data = await parseRequestPayload({
		request,
		schema: buildsActionSchema,
	});

	switch (data._action) {
		case "DELETE_BUILD": {
			const ownerId = await BuildRepository.ownerIdById(data.buildToDeleteId);

			errorToastIfFalsy(ownerId === user.id, "Build to delete not found");

			await BuildRepository.deleteById(data.buildToDeleteId);

			break;
		}
		case "UPDATE_SORTING": {
			await UserRepository.updateOwnBuildSorting(data.buildSorting);

			break;
		}
		default: {
			assertUnreachable(data);
		}
	}

	return redirect(userBuildsPage(user));
};

const buildsActionSchema = z.union([
	z.object({
		_action: _action("DELETE_BUILD"),
		buildToDeleteId: z.preprocess(actualNumber, id),
	}),

	z.object({
		_action: _action("UPDATE_SORTING"),
		buildSorting: z.preprocess(
			processMany(safeJSONParse, removeDuplicates, emptyArrayToNull),
			z.array(z.enum(BUILD_SORT_IDENTIFIERS)).nullable(),
		),
	}),
]);
