import { NextResponse } from 'next/server';
import { db, users, posts, sessions, likes, follows, notifications, chatMessages, chatConversations } from '@/db';
import { eq, or, and } from 'drizzle-orm';
import { requireSignedAction, type SignedAction } from '@/lib/auth/verify-signature';
import { verifyPassword } from '@/lib/auth';
import { cookies } from 'next/headers';

export async function POST(request: Request) {
    try {
        const signedAction: SignedAction = await request.json();

        // Verify signature and get user
        const user = await requireSignedAction(signedAction);

        if (signedAction.action !== 'delete_account') {
            return NextResponse.json(
                { error: 'Invalid action type' },
                { status: 400 }
            );
        }

        const { password } = signedAction.data;

        // Verify password
        if (!user.passwordHash) {
            return NextResponse.json(
                { error: 'Account has no password set' },
                { status: 400 }
            );
        }

        const isPasswordValid = await verifyPassword(password, user.passwordHash);
        
        if (!isPasswordValid) {
            return NextResponse.json(
                { error: 'Password is incorrect' },
                { status: 403 }
            );
        }

        const userId = user.id;
        const userDid = user.did;

        // Delete all user data in proper order to respect foreign keys
        
        // 1. Delete chat messages sent by this user
        await db.delete(chatMessages)
            .where(eq(chatMessages.senderDid, userDid));

        // 2. Find and delete conversations where user is a participant
        // First get conversation IDs where user is participant1 (local user)
        // For participant2, we need to check by handle since it's stored as text (can be remote)
        const conversations = await db.query.chatConversations.findMany({
            where: { OR: [{ participant1Id: userId }, { participant2Handle: user.handle }] },
        });

        const conversationIds = conversations.map(c => c.id);

        // Delete messages in those conversations
        if (conversationIds.length > 0) {
            for (const convId of conversationIds) {
                await db.delete(chatMessages)
                    .where(eq(chatMessages.conversationId, convId));
            }
        }

        // 3. Delete the conversations themselves
        if (conversationIds.length > 0) {
            for (const convId of conversationIds) {
                await db.delete(chatConversations)
                    .where(eq(chatConversations.id, convId));
            }
        }

        // 4. Delete notifications
        await db.delete(notifications)
            .where(or(
                eq(notifications.userId, userId),
                eq(notifications.actorId, userId)
            ));

        // 5. Delete likes
        await db.delete(likes)
            .where(eq(likes.userId, userId));

        // 6. Delete follows (both directions)
        await db.delete(follows)
            .where(or(
                eq(follows.followerId, userId),
                eq(follows.followingId, userId)
            ));

        // 7. Delete posts (this will cascade delete reposts and post likes via triggers if set up)
        await db.delete(posts)
            .where(eq(posts.userId, userId));

        // 8. Delete sessions
        await db.delete(sessions)
            .where(eq(sessions.userId, userId));

        // 9. Finally, delete the user
        await db.delete(users)
            .where(eq(users.id, userId));

        // Clear session cookie
        const cookieStore = await cookies();
        cookieStore.delete('synapsis_session');

        return NextResponse.json({
            success: true,
            message: 'Account deleted successfully',
        });

    } catch (error) {
        console.error('Account deletion error:', error);
        return NextResponse.json(
            { error: error instanceof Error ? error.message : 'Failed to delete account' },
            { status: 500 }
        );
    }
}
