import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/prisma';
import { writeFile, mkdir, unlink } from 'fs/promises';
import path from 'path';
import { z } from 'zod';

// Validation schema
const profileUpdateSchema = z.object({
  firstName: z.string().min(1, 'First name is required').max(50, 'First name too long'),
  lastName: z.string().min(1, 'Last name is required').max(50, 'Last name too long'),
  email: z.string().email('Invalid email address'),
  phone: z.string().optional(),
  country: z.string().optional(),
  city: z.string().optional(),
  zipCode: z.string().optional(),
  address: z.string().optional(),
  bio: z.string().optional(),
  title: z.string().optional(),
});

// File validation
const validateImageFile = (file: File) => {
  const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'];
  const maxSize = 5 * 1024 * 1024; // 5MB

  if (!allowedTypes.includes(file.type)) {
    throw new Error('Invalid file type. Only JPEG, PNG, and WebP images are allowed.');
  }

  if (file.size > maxSize) {
    throw new Error('File size too large. Maximum size is 5MB.');
  }

  return true;
};

// Delete old profile image
const deleteOldImage = async (imagePath: string) => {
  try {
    if (imagePath && imagePath.startsWith('/uploads/')) {
      const fullPath = path.join(process.cwd(), 'public', imagePath);
      await unlink(fullPath);
    }
  } catch (error) {
    console.log('Could not delete old image:', error);
  }
};

export async function POST(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);

    if (!session?.user) {
      return NextResponse.json(
        { message: 'Unauthorized' },
        { status: 401 }
      );
    }

    const formData = await request.formData();
    
    // Extract form data
    const formFields = {
      firstName: formData.get('firstName') as string,
      lastName: formData.get('lastName') as string,
      email: formData.get('email') as string,
      phone: formData.get('phone') as string,
      country: formData.get('country') as string,
      city: formData.get('city') as string,
      zipCode: formData.get('zipCode') as string,
      address: formData.get('address') as string,
      bio: formData.get('bio') as string,
      title: formData.get('title') as string,
    };

    // Validate form data
    const validatedData = profileUpdateSchema.parse(formFields);

    const profileImage = formData.get('profileImage') as File | null;
    let profileImagePath: string | null = null;

    // Handle profile image upload
    if (profileImage && profileImage.size > 0) {
      try {
        // Validate image file
        validateImageFile(profileImage);

        const bytes = await profileImage.arrayBuffer();
        const buffer = Buffer.from(bytes);

        // Create unique filename
        const timestamp = Date.now();
        const fileExtension = path.extname(profileImage.name).toLowerCase();
        const fileName = `profile_${session.user.email}_${timestamp}${fileExtension}`;
        
        // Create uploads directory if it doesn't exist
        const uploadDir = path.join(process.cwd(), 'public/uploads/profiles');
        try {
          await mkdir(uploadDir, { recursive: true });
        } catch (error) {
          console.log('Directory might already exist:', error);
        }

        // Save file
        const filePath = path.join(uploadDir, fileName);
        await writeFile(filePath, buffer);
        
        profileImagePath = `/uploads/profiles/${fileName}`;
      } catch (imageError) {
        return NextResponse.json(
          { message: `Image upload error: ${imageError}` },
          { status: 400 }
        );
      }
    }

    const userEmail = session.user?.email;
    
    if (!userEmail) {
      return NextResponse.json(
        { error: 'User email not found in session' },
        { status: 400 }
      );
    }

    // First get the user to get their ID
    const user = await prisma.user.findUnique({
      where: { email: userEmail },
      select: { id: true }
    });

    if (!user) {
      return NextResponse.json(
        { message: 'User not found' },
        { status: 404 }
      );
    }

    // Get current profile to check for existing image
    const currentProfile = await prisma.profile.findUnique({
      where: { userId: user.id },
      select: { profileImage: true }
    });

    // Prepare profile data
    const profileData: any = {
      firstName: validatedData.firstName,
      lastName: validatedData.lastName,
      phone: validatedData.phone || null,
      city: validatedData.city || null,
      address: validatedData.address || null,
      bio: validatedData.bio || null,
      title: validatedData.title || null,
    };

    // Add zipCode to profile data
    if (validatedData.zipCode) {
      profileData.zipCode = validatedData.zipCode;
    }

    // Add profile image if uploaded
    if (profileImagePath) {
      // Delete old image if exists
      if (currentProfile?.profileImage) {
        await deleteOldImage(currentProfile.profileImage);
      }
      profileData.profileImage = profileImagePath;
    }

    let updatedProfile;
    
    // Check if profile exists
    const existingProfile = await prisma.profile.findUnique({
      where: { userId: user.id },
    });

    if (!existingProfile) {
      // Create profile if it doesn't exist
      updatedProfile = await prisma.profile.create({
        data: {
          userId: user.id,
          ...profileData,
          countryId: validatedData.country || 'switzerland', // Default to switzerland
        },
        include: {
          country: true,
        },
      });
    } else {
      // Update existing profile
      updatedProfile = await prisma.profile.update({
        where: { userId: user.id },
        data: {
          ...profileData,
          countryId: validatedData.country || existingProfile.countryId,
        },
        include: {
          country: true,
        },
      });
    }

    // Update user email if changed and validate uniqueness
    // if (validatedData.email !== session.user.email) {
    //   // Check if email is already taken by another user
    //   const existingUser = await prisma.user.findUnique({
    //     where: { email: validatedData.email },
    //   });

    //   if (existingUser && existingUser.email !== userEmail) {
    //     return NextResponse.json(
    //       { message: 'Email address is already taken by another user' },
    //       { status: 400 }
    //     );
    //   }

    //   await prisma.user.update({
    //     where: { email: userEmail },
    //     data: { email: validatedData.email },
    //   });
    // }

    // Return updated profile data
    const fullName = `${updatedProfile.firstName || ''} ${updatedProfile.lastName || ''}`.trim();

    return NextResponse.json({
      message: 'Profile updated successfully',
      profile: {
        ...updatedProfile,
        fullName,
      }
    });

  } catch (error) {
    console.error('Profile update error:', error);
    
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { 
          message: 'Validation error',
          errors: error.issues.map(e => `${e.path.join('.')}: ${e.message}`)
        },
        { status: 400 }
      );
    }

    return NextResponse.json(
      { message: 'Internal server error' },
      { status: 500 }
    );
  }
}

// GET method to fetch current profile
export async function GET(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    
    if (!session?.user) {
      return NextResponse.json(
        { message: 'Unauthorized' },
        { status: 401 }
      );
    }

    const userEmail = session.user?.email;
    
    if (!userEmail) {
      return NextResponse.json(
        { error: 'User email not found in session' },
        { status: 400 }
      );
    }
    
    const user = await prisma.user.findUnique({
      where: { email: userEmail },
      include: {
        profile: {
          include: {
            country: true,
          },
        },
      },
    });

    if (!user) {
      return NextResponse.json(
        { message: 'User not found' },
        { status: 404 }
      );
    }

    return NextResponse.json({
      user: {
        id: user.id,
        email: user.email,
        role: user.role,
        provider: user.provider,
        profile: user.profile,
      }
    });

  } catch (error) {
    console.error('Error fetching profile:', error);
    return NextResponse.json(
      { message: 'Internal server error' },
      { status: 500 }
    );
  }
}