import { NextRequest, NextResponse } from 'next/server';
import { prismaAuth } from '@/lib/db';
import { isAdmin } from '@/lib/permissions';
import bcrypt from 'bcryptjs';

// PATCH /api/users/[id] - Update user (admin only)
export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    // Check if user is admin
    const admin = await isAdmin();
    if (!admin) {
      return NextResponse.json(
        { error: 'Unauthorized. Admin access required.' },
        { status: 403 }
      );
    }

    const { id } = await params;
    const userId = parseInt(id, 10);
    if (isNaN(userId)) {
      return NextResponse.json(
        { error: 'Invalid user ID' },
        { status: 400 }
      );
    }

    const body = await request.json();
    const { hasWriteAccess, name, password, email, isAdmin: isAdminValue, isActive } = body;

    // Prevent users from removing their own admin status
    const session = await import('@/app/api/auth/[...nextauth]/route').then(
      (m) => m.auth()
    );
    if (session?.user?.id && parseInt(session.user.id, 10) === userId) {
      if (isAdminValue === false) {
        return NextResponse.json(
          { error: 'You cannot remove your own admin status' },
          { status: 400 }
        );
      }
    }

    // Build update data
    const updateData: {
      hasWriteAccess?: boolean;
      name?: string;
      passwordHash?: string;
      email?: string;
      isAdmin?: boolean;
      isActive?: boolean;
    } = {};

    if (typeof hasWriteAccess === 'boolean') {
      updateData.hasWriteAccess = hasWriteAccess;
    }

    if (typeof isAdminValue === 'boolean') {
      updateData.isAdmin = isAdminValue;
    }

    if (typeof isActive === 'boolean') {
      updateData.isActive = isActive;
    }

    if (name !== undefined) {
      if (!name || name.trim().length === 0) {
        return NextResponse.json(
          { error: 'Name is required and cannot be empty' },
          { status: 400 }
        );
      }
      updateData.name = name.trim();
    }

    if (email !== undefined) {
      // Basic email validation
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(email)) {
        return NextResponse.json(
          { error: 'Invalid email format' },
          { status: 400 }
        );
      }
      updateData.email = email;
    }

    if (password) {
      if (password.length < 6) {
        return NextResponse.json(
          { error: 'Password must be at least 6 characters' },
          { status: 400 }
        );
      }
      updateData.passwordHash = await bcrypt.hash(password, 10);
    }

    if (Object.keys(updateData).length === 0) {
      return NextResponse.json(
        { error: 'No valid fields to update' },
        { status: 400 }
      );
    }

    // Update user
    const user = await prismaAuth.user.update({
      where: { id: userId },
      data: updateData,
      select: {
        id: true,
        email: true,
        name: true,
        isAdmin: true,
        hasWriteAccess: true,
        isActive: true,
        createdAt: true,
        updatedAt: true,
      },
    });

    return NextResponse.json(
      { message: 'User updated successfully', user },
      { status: 200 }
    );
  } catch (error: any) {
    console.error('Error updating user:', error);
    if (error.code === 'P2025') {
      return NextResponse.json(
        { error: 'User not found' },
        { status: 404 }
      );
    }
    if (error.code === 'P2002') {
      // Unique constraint violation (likely email already exists)
      return NextResponse.json(
        { error: 'Email already exists. Please use a different email address.' },
        { status: 409 }
      );
    }
    return NextResponse.json(
      { error: 'Failed to update user', details: error.message },
      { status: 500 }
    );
  }
}

// DELETE /api/users/[id] - Delete user (admin only)
export async function DELETE(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    // Check if user is admin
    const admin = await isAdmin();
    if (!admin) {
      return NextResponse.json(
        { error: 'Unauthorized. Admin access required.' },
        { status: 403 }
      );
    }

    const { id } = await params;
    const userId = parseInt(id, 10);
    if (isNaN(userId)) {
      return NextResponse.json(
        { error: 'Invalid user ID' },
        { status: 400 }
      );
    }

    // Prevent deleting yourself
    const session = await import('@/app/api/auth/[...nextauth]/route').then(
      (m) => m.auth()
    );
    if (session?.user?.id && parseInt(session.user.id, 10) === userId) {
      return NextResponse.json(
        { error: 'You cannot delete your own account' },
        { status: 400 }
      );
    }

    // Check if user has any related records in other tables
    let pendingIdentifications = 0;
    let pendingPhotos = 0;
    let inappropriatePhotoReports = 0;
    let pendingLinkages = 0;
    let photoFavorites = 0;

    try {
      [pendingIdentifications, pendingPhotos, inappropriatePhotoReports, pendingLinkages, photoFavorites] = await Promise.all([
        prismaAuth.pendingIdentification.count({ where: { userId } }),
        prismaAuth.pendingPhoto.count({ where: { userId } }),
        prismaAuth.inappropriatePhotoReport.count({ where: { userId } }),
        prismaAuth.pendingLinkage.count({ where: { userId } }),
        prismaAuth.photoFavorite.count({ where: { userId } }),
      ]);
    } catch (countError: any) {
      console.error('Error counting related records:', countError);
      // If counting fails, err on the side of caution and deactivate instead of delete
      await prismaAuth.user.update({
        where: { id: userId },
        data: { isActive: false },
      });
      return NextResponse.json(
        { 
          message: 'User deactivated successfully (error checking related records)',
          deactivated: true 
        },
        { status: 200 }
      );
    }

    console.log(`[DELETE User ${userId}] Related records:`, {
      pendingIdentifications,
      pendingPhotos,
      inappropriatePhotoReports,
      pendingLinkages,
      photoFavorites,
    });

    // Ensure all counts are numbers and check explicitly
    const counts = {
      pendingIdentifications: Number(pendingIdentifications) || 0,
      pendingPhotos: Number(pendingPhotos) || 0,
      inappropriatePhotoReports: Number(inappropriatePhotoReports) || 0,
      pendingLinkages: Number(pendingLinkages) || 0,
      photoFavorites: Number(photoFavorites) || 0,
    };

    const hasRelatedRecords = 
      counts.pendingIdentifications > 0 ||
      counts.pendingPhotos > 0 ||
      counts.inappropriatePhotoReports > 0 ||
      counts.pendingLinkages > 0 ||
      counts.photoFavorites > 0;

    console.log(`[DELETE User ${userId}] hasRelatedRecords:`, hasRelatedRecords, 'Counts:', counts);

    if (hasRelatedRecords) {
      console.log(`[DELETE User ${userId}] Deactivating user due to related records`);
      // Set user as inactive instead of deleting
      try {
        await prismaAuth.user.update({
          where: { id: userId },
          data: { isActive: false },
        });
        console.log(`[DELETE User ${userId}] User deactivated successfully`);
      } catch (updateError: any) {
        console.error(`[DELETE User ${userId}] Error deactivating user:`, updateError);
        throw updateError;
      }

      return NextResponse.json(
        { 
          message: 'User deactivated successfully (user has related records in other tables)',
          deactivated: true,
          relatedRecords: {
            pendingIdentifications: counts.pendingIdentifications,
            pendingPhotos: counts.pendingPhotos,
            inappropriatePhotoReports: counts.inappropriatePhotoReports,
            pendingLinkages: counts.pendingLinkages,
            photoFavorites: counts.photoFavorites,
          }
        },
        { status: 200 }
      );
    }

    console.log(`[DELETE User ${userId}] No related records found, proceeding with deletion`);

    // Double-check one more time before deleting (defensive programming)
    const finalCheck = await Promise.all([
      prismaAuth.pendingIdentification.count({ where: { userId } }),
      prismaAuth.pendingPhoto.count({ where: { userId } }),
      prismaAuth.inappropriatePhotoReport.count({ where: { userId } }),
      prismaAuth.pendingLinkage.count({ where: { userId } }),
      prismaAuth.photoFavorite.count({ where: { userId } }),
    ]);

    const finalHasRelatedRecords = finalCheck.some((count: number) => count > 0);
    
    if (finalHasRelatedRecords) {
      console.log(`[DELETE User ${userId}] Final check found related records, deactivating instead`);
      await prismaAuth.user.update({
        where: { id: userId },
        data: { isActive: false },
      });
      return NextResponse.json(
        { 
          message: 'User deactivated successfully (related records detected in final check)',
          deactivated: true 
        },
        { status: 200 }
      );
    }

    // No related records, safe to delete
    console.log(`[DELETE User ${userId}] Confirmed no related records, deleting user`);
    await prismaAuth.user.delete({
      where: { id: userId },
    });

    console.log(`[DELETE User ${userId}] User deleted successfully`);
    return NextResponse.json(
      { message: 'User deleted successfully' },
      { status: 200 }
    );
  } catch (error: any) {
    console.error('Error deleting user:', error);
    if (error.code === 'P2025') {
      return NextResponse.json(
        { error: 'User not found' },
        { status: 404 }
      );
    }
    return NextResponse.json(
      { error: 'Failed to delete user', details: error.message },
      { status: 500 }
    );
  }
}

