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

export async function GET(req: NextRequest) {
  try {
    // Check if required dependencies are available
    if (!prisma) {
      return NextResponse.json(
        { error: 'Database connection not available' },
        { status: 503 }
      );
    }

    const session = await getServerSession(authOptions);
    
    if (!session?.user?.email) {
      return NextResponse.json(
        { error: 'Unauthorized' },
        { status: 401 }
      );
    }

    try {
      // First get the user's profile
      const user = await prisma.user.findUnique({
        where: { email: session.user.email },
        include: { profile: true }
      });

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

      // Get freelancer experiences with documents
      const experiences = await prisma.experience.findMany({
        where: { profileId: user.profile.id },
        include: {
          documents: {
            select: {
              id: true,
              filename: true,
              fileUrl: true,
              fileSize: true,
              fileType: true
            }
          }
        },
        orderBy: {
          createdAt: 'desc'
        }
      });

      const formattedExperiences = experiences.map(exp => ({
        id: exp.id,
        title: exp.title,
        location: exp.location,
        description: exp.description,
        documents: exp.documents || [],
        createdAt: exp.createdAt.toISOString(),
        updatedAt: exp.updatedAt.toISOString()
      }));

      return NextResponse.json({
        success: true,
        data: formattedExperiences
      });

    } catch (dbError) {
      console.error('Database query error:', dbError);

      return NextResponse.json(
        {
          error: 'Failed to fetch experiences from database',
          type: 'database_error'
        },
        { status: 503 }
      );
    }

  } catch (error) {
    console.error('Error fetching experiences:', error);
    
    // Return proper error for database issues
    
    return NextResponse.json(
      { 
        error: error instanceof Error ? error.message : 'Failed to fetch experiences',
        type: 'server_error'
      },
      { status: 500 }
    );
  }
}

export async function POST(req: NextRequest) {
  try {
    // Check if required dependencies are available
    if (!prisma) {
      return NextResponse.json(
        { error: 'Database connection not available' },
        { status: 503 }
      );
    }

    const session = await getServerSession(authOptions);
    
    if (!session?.user?.email) {
      return NextResponse.json(
        { error: 'Unauthorized' },
        { status: 401 }
      );
    }

    const formData = await req.formData();
    const title = formData.get('title') as string;
    const company = formData.get('company') as string;
    const location = formData.get('location') as string;
    const startDate = formData.get('startDate') as string;
    const endDate = formData.get('endDate') as string;
    const isCurrent = formData.get('isCurrent') === 'true';
    const description = formData.get('description') as string;
    
    // Validate required fields
    if (!title || !company || !startDate) {
      return NextResponse.json(
        { error: 'Title, company, and start date are required' },
        { status: 400 }
      );
    }

    // First get the user's profile
    const user = await prisma.user.findUnique({
      where: { email: session.user.email },
      include: { profile: true }
    });

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

    // Get uploaded files
    const files = formData.getAll('documents') as File[];
    
    try {
      // Create experience
      const experience = await prisma.experience.create({
        data: {
          profileId: user.profile.id,
          title: title.trim(),
          company: company.trim(),
          location: location?.trim() || null,
          startDate: new Date(startDate),
          endDate: endDate ? new Date(endDate) : null,
          isCurrent,
          description: description?.trim() || null
        }
      });

      // Handle file uploads
      const documentRecords = [];
      if (files && files.length > 0) {
        // Create uploads directory if it doesn't exist
        const uploadsDir = join(process.cwd(), 'public', 'uploads', 'experiences');
        if (!existsSync(uploadsDir)) {
          await mkdir(uploadsDir, { recursive: true });
        }

        for (const file of files) {
          if (file && file.size > 0) {
            // Validate file type
            const allowedTypes = [
              'image/jpeg', 'image/jpg', 'image/png', 'image/gif',
              'application/pdf',
              'text/plain',
              'application/msword',
              'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
            ];
            
            if (!allowedTypes.includes(file.type)) {
              console.warn(`Skipping unsupported file type: ${file.type}`);
              continue;
            }

            // Validate file size (max 10MB)
            const maxSize = 10 * 1024 * 1024; // 10MB in bytes
            if (file.size > maxSize) {
              console.warn(`Skipping large file: ${file.name} (${file.size} bytes)`);
              continue;
            }

            try {
              // Generate unique filename
              const timestamp = Date.now();
              const randomString = Math.random().toString(36).substring(2, 15);
              const fileExtension = file.name.split('.').pop() || 'bin';
              const fileName = `exp_${experience.id}_${timestamp}_${randomString}.${fileExtension}`;
              const filePath = join(uploadsDir, fileName);

              // Convert file to buffer and save
              const bytes = await file.arrayBuffer();
              const buffer = Buffer.from(bytes);
              await writeFile(filePath, buffer);

              // Create the URL path for the uploaded file
              const fileUrl = `/uploads/experiences/${fileName}`;

              // Format file size
              const formatFileSize = (bytes: number) => {
                if (bytes === 0) return '0 Bytes';
                const k = 1024;
                const sizes = ['Bytes', 'KB', 'MB', 'GB'];
                const i = Math.floor(Math.log(bytes) / Math.log(k));
                return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
              };

              // Create document record
              const document = await prisma.experienceDocument.create({
                data: {
                  experienceId: experience.id,
                  filename: file.name,
                  fileUrl: fileUrl,
                  fileSize: formatFileSize(file.size),
                  fileType: file.type
                }
              });

              documentRecords.push({
                id: document.id,
                filename: document.filename,
                fileUrl: document.fileUrl,
                fileSize: document.fileSize,
                fileType: document.fileType
              });

            } catch (fileError) {
              console.error('File upload error:', fileError);
              // Continue with other files
            }
          }
        }
      }

      // Log the experience creation activity (optional)
      // TODO: Add UserActivity model to schema
      /*
      try {
        await prisma.userActivity.create({
          data: {
            userId: session.user.email,
            action: 'EXPERIENCE_CREATED',
            details: `Created experience: ${title}`,
            ipAddress: req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip') || 'unknown',
            userAgent: req.headers.get('user-agent') || 'unknown',
            createdAt: new Date()
          }
        });
      } catch (activityError) {
        // Don't fail the experience creation if activity logging fails
        console.error('Failed to log experience creation activity:', activityError);
      }
      */

      return NextResponse.json({
        success: true,
        data: {
          id: experience.id,
          title: experience.title,
          location: experience.location,
          description: experience.description,
          documents: documentRecords,
          createdAt: experience.createdAt.toISOString(),
          updatedAt: experience.updatedAt.toISOString()
        },
        message: 'Experience created successfully'
      });

    } catch (dbError) {
      console.error('Database error during experience creation:', dbError);
      throw dbError;
    }

  } catch (error) {
    console.error('Error creating experience:', error);
    
    // Return proper error for database issues
    
    return NextResponse.json(
      { 
        error: error instanceof Error ? error.message : 'Failed to create experience',
        type: 'server_error'
      },
      { status: 500 }
    );
  }
}