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 { randomUUID } from 'crypto';

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    
    // Pagination parameters
    const page = parseInt(searchParams.get('page') || '1');
    const limit = parseInt(searchParams.get('limit') || '12');
    const skip = (page - 1) * limit;

    // Filter parameters
    const search = searchParams.get('search') || '';
    const categoryId = searchParams.get('categoryId') || '';
    const minBudget = searchParams.get('minBudget') ? parseFloat(searchParams.get('minBudget')!) : undefined;
    const maxBudget = searchParams.get('maxBudget') ? parseFloat(searchParams.get('maxBudget')!) : undefined;
    const countryId = searchParams.get('countryId') || '';
    const sortBy = searchParams.get('sortBy') || 'newest'; // newest, oldest, price_low_high, price_high_low

    // Build where clause for filtering
    const where: any = {
      status: 'OPEN', // Only show open projects
      publishedAt: {
        not: null
      }
    };

    // Search filter
    if (search) {
      where.OR = [
        {
          title: {
            contains: search
          }
        },
        {
          description: {
            contains: search
          }
        }
      ];
    }

    // Category filter
    if (categoryId) {
      // Handle multiple categories separated by comma
      const categoryIds = categoryId.split(',').filter(id => id.trim());
      
      if (categoryIds.length === 1) {
        // Single category
        where.categoryId = categoryIds[0];
      } else if (categoryIds.length > 1) {
        // Multiple categories
        where.categoryId = {
          in: categoryIds
        };
      }
    }

    // Budget range filter
    if (minBudget !== undefined || maxBudget !== undefined) {
      where.budget = {};
      if (minBudget !== undefined) {
        where.budget.gte = minBudget;
      }
      if (maxBudget !== undefined) {
        where.budget.lte = maxBudget;
      }
    }

    // Country filter
    if (countryId) {
      where.countryId = countryId;
    }

    // Build orderBy clause for sorting
    let orderBy: any = {};
    switch (sortBy) {
      case 'oldest':
        orderBy = { publishedAt: 'asc' };
        break;
      case 'price_low_high':
        orderBy = { budget: 'asc' };
        break;
      case 'price_high_low':
        orderBy = { budget: 'desc' };
        break;
      case 'newest':
      default:
        orderBy = { publishedAt: 'desc' };
        break;
    }

    // Get total count for pagination
    const total = await prisma.project.count({ where });

    // Get projects with relations
    const projects = await prisma.project.findMany({
      where,
      orderBy,
      skip,
      take: limit,
      include: {
        client: {
          include: {
            profile: true,
            receivedReviews: {
              select: {
                rating: true
              }
            }
          }
        },
        category: {
          select: {
            id: true,
            name: true,
            slug: true,
            icon: true
          }
        },
        country: {
          select: {
            id: true,
            name: true,
            currency: true,
            currencySymbol: true
          }
        },
        bids: {
          where: {
            status: 'PENDING'
          },
          select: {
            id: true
          }
        },
        _count: {
          select: {
            bids: true
          }
        }
      }
    });

    // Transform data for frontend
    const transformedProjects = projects.map(project => {
      // Calculate client rating
      const reviews = project.client.receivedReviews;
      const averageRating = reviews.length > 0 
        ? reviews.reduce((sum, review) => sum + review.rating, 0) / reviews.length 
        : 0;

      return {
        id: project.id,
        title: project.title,
        description: project.description,
        budget: project.budget,
        duration: project.duration,
        skills: project.skills ? (() => {
          try {
            return JSON.parse(project.skills);
          } catch (e) {
            console.warn('Invalid skills JSON:', project.skills, e);
            return [];
          }
        })() : [],
        status: project.status,
        publishedAt: project.publishedAt,
        category: project.category,
        country: project.country,
        client: {
          id: project.client.id,
          name: project.client.profile 
            ? `${project.client.profile.firstName || ''} ${project.client.profile.lastName || ''}`.trim() || 'Anonymous'
            : 'Anonymous',
          profileImage: project.client.profile?.profileImage || '/assets/image/user.png',
          rating: parseFloat(averageRating.toFixed(1)),
          reviewCount: reviews.length
        },
        bidCount: project._count.bids,
        createdAt: project.createdAt,
        updatedAt: project.updatedAt
      };
    });

    const totalPages = Math.ceil(total / limit);
    const hasNextPage = page < totalPages;
    const hasPrevPage = page > 1;

    return NextResponse.json({
      success: true,
      data: {
        projects: transformedProjects,
        pagination: {
          currentPage: page,
          totalPages,
          totalItems: total,
          itemsPerPage: limit,
          hasNextPage,
          hasPrevPage
        },
        filters: {
          search,
          categoryId,
          minBudget,
          maxBudget,
          countryId,
          sortBy
        }
      }
    });

  } catch (error) {
    console.error('Error fetching projects:', error);
    return NextResponse.json(
      { 
        success: false, 
        error: 'Failed to fetch projects',
        message: error instanceof Error ? error.message : 'Unknown error'
      },
      { status: 500 }
    );
  }
}

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

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

    const user = session.user as any;

    if (user.role !== 'CLIENT') {
      return NextResponse.json(
        { error: 'Access denied. Client role required.' },
        { status: 403 }
      );
    }

    const formData = await request.formData();
    
    // Extract form fields
    const title = formData.get('title') as string;
    const categoryId = formData.get('categoryId') as string;
    const budget = parseFloat(formData.get('budget') as string);
    const duration = parseInt(formData.get('duration') as string);
    const countryId = formData.get('countryId') as string;
    const city = formData.get('city') as string;
    const zipCode = formData.get('zipCode') as string;
    const description = formData.get('description') as string;
    const skills = formData.get('skills') as string; // JSON string of skills

    // Handle file uploads (declare early to avoid initialization issues)
    const attachments = formData.getAll('attachments') as File[];

    console.log('📝 Creating project with data:');
    console.log('title ===', title);
    console.log('categoryId ===', categoryId);
    console.log('budget ===', budget);
    console.log('duration ===', duration);
    console.log('countryId ===', countryId);
    console.log('city ===', city);
    console.log('zipCode ===', zipCode);
    console.log('description length ===', description?.length || 0);
    console.log('skills ===', skills);
    console.log('attachments count ===', attachments.length);

    // Validate required fields
    if (!title || !categoryId || !budget || !duration || !countryId || !description) {
      return NextResponse.json(
        { error: 'All required fields must be provided' },
        { status: 400 }
      );
    }

    // Handle file processing
    const uploadedFiles: any[] = [];

    if (attachments && attachments.length > 0) {
      // Ensure upload directory exists
      const uploadDir = join(process.cwd(), 'public', 'uploads', 'projects');
      try {
        await mkdir(uploadDir, { recursive: true });
      } catch (error) {
        // Directory might already exist
      }

      for (const file of attachments) {
        if (file.size > 0) {
          const bytes = await file.arrayBuffer();
          const buffer = Buffer.from(bytes);

          // Generate unique filename
          const fileExtension = file.name.split('.').pop();
          const fileName = `${randomUUID()}.${fileExtension}`;
          const filePath = join(uploadDir, fileName);

          await writeFile(filePath, buffer);
          
          // Store complete file information instead of just the path
          uploadedFiles.push({
            id: `file-${randomUUID()}`,
            name: file.name,
            originalName: file.name,
            size: `${(file.size / (1024 * 1024)).toFixed(1)} MB`,
            type: file.type,
            url: `/uploads/projects/${fileName}`,
            uploadedBy: user.email || 'Unknown',
            createdAt: new Date().toISOString()
          });
        }
      }
    }

    // Validate that the user exists in the database
    const existingUser = await prisma.user.findUnique({
      where: { email: user.email }
    });

    if (!existingUser) {
      return NextResponse.json(
        { error: 'User not found in database' },
        { status: 400 }
      );
    }

    // Find category to validate it exists
    const category = await prisma.category.findUnique({
      where: { id: categoryId }
    });

    if (!category) {
      return NextResponse.json(
        { error: 'Invalid category selected' },
        { status: 400 }
      );
    }

    // Validate country exists
    const country = await prisma.country.findUnique({
      where: { id: countryId }
    });

    if (!country) {
      return NextResponse.json(
        { error: 'Invalid country selected' },
        { status: 400 }
      );
    }

    // Validate and clean skills JSON
    let validSkills = null;
    if (skills && skills.trim()) {
      try {
        // Try to parse and re-stringify to ensure valid JSON
        const parsedSkills = JSON.parse(skills);
        validSkills = JSON.stringify(parsedSkills);
      } catch (e) {
        console.warn('Invalid skills JSON provided:', skills, e);
        // If it's not valid JSON, treat it as a plain string and create an array
        validSkills = JSON.stringify([skills]);
      }
    }

    // Create the project
    const project = await prisma.project.create({
      data: {
        title,
        description,
        budget,
        duration,
        city: city || null,
        zipCode: zipCode || null,
        skills: validSkills,
        attachments: uploadedFiles.length > 0 ? JSON.stringify(uploadedFiles) : null,
        status: 'OPEN',
        clientId: existingUser.id,
        categoryId,
        countryId,
        publishedAt: new Date(),
      },
      include: {
        client: {
          select: {
            id: true,
            email: true,
            profile: {
              select: {
                firstName: true,
                lastName: true,
                profileImage: true
              }
            }
          }
        },
        category: {
          select: {
            id: true,
            name: true,
          }
        },
        country: {
          select: {
            id: true,
            name: true,
            currency: true,
            currencySymbol: true
          }
        },
        _count: {
          select: {
            bids: true,
          }
        }
      }
    });

    // Transform the response data
    const responseData = {
      id: project.id,
      title: project.title,
      description: project.description,
      budget: project.budget,
      duration: project.duration,
      status: project.status,
      category: {
        id: project.category.id,
        name: project.category.name
      },
      country: {
        id: project.country.id,
        name: project.country.name,
        currency: project.country.currency,
        currencySymbol: project.country.currencySymbol
      },
      client: {
        id: project.client.id,
        email: project.client.email,
        name: project.client.profile 
          ? `${project.client.profile.firstName || ''} ${project.client.profile.lastName || ''}`.trim() || 'Anonymous'
          : 'Anonymous',
        profileImage: project.client.profile?.profileImage || '/assets/image/user.png'
      },
      attachments: project.attachments ? (() => {
        try {
          return JSON.parse(project.attachments);
        } catch (e) {
          console.warn('Invalid attachments JSON:', project.attachments, e);
          return [];
        }
      })() : [],
      createdAt: project.createdAt.toISOString(),
      updatedAt: project.updatedAt.toISOString(),
      bidsCount: project._count.bids,
      publishedAt: project.publishedAt?.toISOString(),
    };

    return NextResponse.json({
      success: true,
      message: 'Project created successfully',
      project: responseData,
    });

  } catch (error) {
    console.error('Error creating project:', error);
    return NextResponse.json(
      { 
        success: false,
        error: 'Internal server error',
        message: error instanceof Error ? error.message : 'Unknown error'
      },
      { status: 500 }
    );
  }
}
