import type { ActionFunction } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import { notify } from "~/features/notifications/core/notify.server";
import { parseFormData } from "~/form/parse.server";
import { errorToastIfFalsy } from "~/utils/remix.server";
import * as FriendRepository from "../FriendRepository.server";
import { FRIEND } from "../friends-constants";
import { friendsActionSchema } from "../friends-schemas.server";

export const action: ActionFunction = async ({ request }) => {
	const user = requireUser();

	const result = await parseFormData({
		request,
		schema: friendsActionSchema,
	});

	if (!result.success) {
		return { fieldErrors: result.fieldErrors };
	}

	switch (result.data._action) {
		case "SEND_REQUEST": {
			const pendingCount = await FriendRepository.countPendingSentRequests(
				user.id,
			);
			errorToastIfFalsy(
				pendingCount < FRIEND.MAX_PENDING_REQUESTS,
				"Maximum pending friend requests reached",
			);

			await FriendRepository.insertFriendRequest({
				senderId: user.id,
				receiverId: result.data.userId,
			});

			await notify({
				userIds: [result.data.userId],
				notification: {
					type: "FRIEND_REQUEST_RECEIVED",
					meta: { senderUsername: user.username },
				},
			});

			break;
		}
		case "CANCEL_REQUEST": {
			await FriendRepository.deleteFriendRequest({
				id: result.data.friendRequestId,
				senderId: user.id,
			});

			break;
		}
		case "DELETE_FRIEND": {
			await FriendRepository.deleteOwnFriendshipById(result.data.friendshipId);

			break;
		}
		case "ACCEPT_REQUEST": {
			const friendRequest =
				await FriendRepository.findFriendRequestByIdAndReceiver({
					id: result.data.friendRequestId,
					receiverId: user.id,
				});
			if (!friendRequest) break;

			await FriendRepository.insertFriendship({
				userOneId: user.id,
				userTwoId: friendRequest.senderId,
				friendRequestId: result.data.friendRequestId,
			});

			break;
		}
		case "DECLINE_REQUEST": {
			await FriendRepository.deleteFriendRequestByReceiver({
				id: result.data.friendRequestId,
				receiverId: user.id,
			});

			break;
		}
	}

	return null;
};
