import { json, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { db } from '$lib/server/db';
import { friendship, user } from '$lib/server/db/schema';
import { eq } from 'drizzle-orm';
import { notificationService } from '$lib/server/notifications';
import { pushService } from '$lib/server/push';

export const PUT: RequestHandler = async ({ params, request, locals }) => {
	if (!locals.user) {
		throw error(401, 'Unauthorized');
	}

	const { friendshipId } = params;
	const data = await request.json();
	const { action } = data; // 'accept', 'decline', 'block'

	if (!friendshipId) {
		throw error(400, 'Friendship ID is required');
	}

	if (!action || !['accept', 'decline', 'block'].includes(action)) {
		throw error(400, 'Valid action is required (accept, decline, block)');
	}

	try {
		// Find the friendship
		const existingFriendship = await db
			.select()
			.from(friendship)
			.where(eq(friendship.id, friendshipId))
			.limit(1);

		if (existingFriendship.length === 0) {
			throw error(404, 'Friendship not found');
		}

		const friendshipRecord = existingFriendship[0];

		// Check if user is authorized to modify this friendship
		// User can only accept/decline requests sent TO them, or cancel requests they sent
		const isReceiver = friendshipRecord.friendId === locals.user.id;
		const isSender = friendshipRecord.userId === locals.user.id;

		if (!isReceiver && !isSender) {
			throw error(403, 'Not authorized to modify this friendship');
		}

		// Only receivers can accept or decline pending requests
		if ((action === 'accept' || action === 'decline') && !isReceiver) {
			throw error(403, 'Only the recipient can accept or decline friend requests');
		}

		// Only accept pending requests
		if (action === 'accept' && friendshipRecord.status !== 'pending') {
			throw error(400, 'Can only accept pending friend requests');
		}

		let newStatus: string;
		if (action === 'accept') {
			newStatus = 'accepted';
		} else if (action === 'decline') {
			newStatus = 'declined';
		} else if (action === 'block') {
			newStatus = 'blocked';
		} else {
			throw error(400, 'Invalid action');
		}

		// Update the friendship status
		const updatedFriendship = await db
			.update(friendship)
			.set({ status: newStatus })
			.where(eq(friendship.id, friendshipId))
			.returning();

		// Send notification if friend request was accepted
		if (action === 'accept') {
			const senderId = friendshipRecord.userId;
			const shouldNotify = await notificationService.shouldNotify(senderId, 'friend_accepted');

			if (shouldNotify) {
				// Get accepter's username
				const accepterUser = await db
					.select({ username: user.username })
					.from(user)
					.where(eq(user.id, locals.user.id))
					.limit(1);

				const accepterUsername = accepterUser[0]?.username || 'Someone';

				await notificationService.createNotification({
					userId: senderId,
					type: 'friend_accepted',
					title: 'Friend request accepted',
					message: `${accepterUsername} accepted your friend request`,
					data: {
						friendshipId: friendshipRecord.id,
						accepterId: locals.user.id,
						accepterUsername
					}
				});

				// Send push notification
				await pushService.sendPushNotification(senderId, {
					title: 'Friend request accepted',
					message: `${accepterUsername} accepted your friend request`,
					url: '/friends',
					tag: 'friend_accepted',
					data: {
						friendshipId: friendshipRecord.id,
						accepterId: locals.user.id
					}
				});
			}
		}

		return json({ success: true, friendship: updatedFriendship[0] });
	} catch (err) {
		console.error('Error updating friendship:', err);
		if (err instanceof Error && 'status' in err) {
			throw err;
		}
		throw error(500, 'Failed to update friendship');
	}
};

export const DELETE: RequestHandler = async ({ params, locals }) => {
	if (!locals.user) {
		throw error(401, 'Unauthorized');
	}

	const { friendshipId } = params;

	if (!friendshipId) {
		throw error(400, 'Friendship ID is required');
	}

	try {
		// Find the friendship
		const existingFriendship = await db
			.select()
			.from(friendship)
			.where(eq(friendship.id, friendshipId))
			.limit(1);

		if (existingFriendship.length === 0) {
			throw error(404, 'Friendship not found');
		}

		const friendshipRecord = existingFriendship[0];

		// Check if user is part of this friendship
		if (
			friendshipRecord.userId !== locals.user.id &&
			friendshipRecord.friendId !== locals.user.id
		) {
			throw error(403, 'Not authorized to delete this friendship');
		}

		// Delete the friendship
		await db.delete(friendship).where(eq(friendship.id, friendshipId));

		return json({ success: true });
	} catch (err) {
		console.error('Error deleting friendship:', err);
		if (err instanceof Error && 'status' in err) {
			throw err;
		}
		throw error(500, 'Failed to delete friendship');
	}
};
