import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/prisma';

export async function GET(req: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    
    if (!session?.user?.email || !session?.user?.id) {
      return NextResponse.json(
        {
          success: false,
          error: 'Authentication Required',
          message: 'Please log in to access your projects. Your session may have expired.',
          action: 'redirect_login'
        },
        { status: 401 }
      );
    }

    const { searchParams } = new URL(req.url);
    const page = parseInt(searchParams.get('page') || '1');
    const limit = parseInt(searchParams.get('limit') || '12');
    const status = searchParams.get('status') || 'RECOMMENDED';
    const search = searchParams.get('search') || '';
    const category = searchParams.get('category') || '';
    const countryId = searchParams.get('countryId') || '';
    
    const skip = (page - 1) * limit;

    // Safety check for prisma client initialization
    if (!prisma) {
      console.error('Prisma client is not initialized');
      return NextResponse.json(
        {
          success: false,
          error: 'Database Connection Failed',
          message: 'Unable to connect to the database. Please try again later.',
          details: 'Prisma client is not initialized',
          support: 'If this error persists, please contact support with error code: PRISMA_INIT_001'
        },
        { status: 500 }
      );
    }

    // Get freelancer's active category subscriptions for RECOMMENDED projects
    let activeCategorySubscriptions;
    try {
      activeCategorySubscriptions = await prisma.categorySubscription.findMany({
        where: {
          userId: session.user.id,
          status: 'ACTIVE',
          endDate: {
            gte: new Date()
          }
        },
        select: {
          categoryId: true
        }
      });
    } catch (subscriptionError) {
      console.error('Error fetching category subscriptions:', subscriptionError);
      // If we can't get subscriptions, return empty array to continue with an empty result set
      activeCategorySubscriptions = [];
    }
    
    const subscribedCategoryIds = activeCategorySubscriptions.map((sub: { categoryId: string }) => sub.categoryId);
    const hasActiveSubscription = subscribedCategoryIds.length > 0;

    // Build where clause based on status and freelancer's relationship to projects
    let whereClause: any = {};

    switch (status.toUpperCase()) {
      case 'RECOMMENDED':
        // Show recommended projects only from subscribed categories
        if (subscribedCategoryIds.length === 0) {
          whereClause = {
            id: {
              in: [] // No subscribed categories, return no results
            }
          };
        } else {
          whereClause = {
            status: 'OPEN',
            categoryId: {
              in: subscribedCategoryIds // Only projects from subscribed categories
            },
            NOT: {
              bids: {
                some: {
                  freelancerId: session.user.id
                }
              }
            }
          };
        }
        break;
      
      case 'PROPOSED':
        // Projects where freelancer has submitted bids
        whereClause = {
          bids: {
            some: {
              freelancerId: session.user.id,
              status: 'PENDING'
            }
          }
        };
        break;
      
      case 'AWARDED':
        // Projects where freelancer's bid was accepted
        whereClause = {
          bids: {
            some: {
              freelancerId: session.user.id,
              status: 'ACCEPTED'
            }
          }
        };
        break;
      
      case 'CANCELLED':
        // Projects that were cancelled or freelancer's bid was rejected
        whereClause = {
          OR: [
            { status: 'CANCELLED' },
            {
              bids: {
                some: {
                  freelancerId: session.user.id,
                  status: 'REJECTED'
                }
              }
            }
          ]
        };
        break;
      
      case 'COMPLETED':
        // Projects that are completed where freelancer was awarded
        whereClause = {
          status: 'COMPLETED',
          bids: {
            some: {
              freelancerId: session.user.id,
              status: 'ACCEPTED'
            }
          }
        };
        break;
    }

    // Add search filter if provided
    if (search) {
      whereClause.OR = [
        { title: { contains: search } },
        { description: { contains: search } }
      ];
    }

    // Add category filter if provided
    if (category) {
      whereClause.category = {
        slug: category
      };
    }

    if (countryId) {
      whereClause.countryId = countryId;
    }

    // Get projects from database
    const [projects, totalCount] = await Promise.all([
      prisma.project.findMany({
        where: whereClause,
        skip,
        take: limit,
        orderBy: { createdAt: 'desc' },
        include: {
          client: {
            select: {
              id: true,
              email: true,
              image: true,
              profile: {
                select: {
                  firstName: true,
                  lastName: true
                }
              },
              _count: {
                select: {
                  receivedReviews: true
                }
              }
            }
          },
          category: {
            select: {
              id: true,
              name: true,
              slug: true,
              icon: true
            }
          },
          _count: {
            select: {
              bids: true
            }
          },
          bids: status.toUpperCase() !== 'RECOMMENDED' ? {
            where: {
              freelancerId: session.user.id
            },
            select: {
              id: true,
              status: true,
              amount: true,
              duration: true,
              createdAt: true
            }
          } : false
        }
      }),
      prisma.project.count({ where: whereClause })
    ]);

    // Get counts for all status types
    const [recommendedCount, proposedCount, awardedCount, cancelledCount, completedCount] = await Promise.all([
      // Recommended count - only from subscribed categories
      subscribedCategoryIds.length > 0 ? prisma.project.count({
        where: {
          status: 'OPEN',
          countryId: countryId,
          categoryId: {
            in: subscribedCategoryIds
          },
          NOT: {
            bids: {
              some: {
                freelancerId: session.user.id
              }
            }
          }
        }
      }) : Promise.resolve(0),
      // Proposed count
      prisma.project.count({
        where: {
          bids: {
            some: {
              freelancerId: session.user.id,
              status: 'PENDING'
            }
          }
        }
      }),
      // Awarded count
      prisma.project.count({
        where: {
          bids: {
            some: {
              freelancerId: session.user.id,
              status: 'ACCEPTED'
            }
          }
        }
      }),
      // Cancelled count
      prisma.project.count({
        where: {
          OR: [
            { status: 'CANCELLED' },
            {
              bids: {
                some: {
                  freelancerId: session.user.id,
                  status: 'REJECTED'
                }
              }
            }
          ]
        }
      }),
      // Completed count
      prisma.project.count({
        where: {
          status: 'COMPLETED',
          bids: {
            some: {
              freelancerId: session.user.id,
              status: 'ACCEPTED'
            }
          }
        }
      })
    ]);

    // Format projects data
    //const formattedProjects = projects.map((project: any) => {

      const formattedProjects = await Promise.all(
          projects.map(async (project: any) => {
     
      // Get client ratings
        const clientReviews = await prisma.review.aggregate({
          where: { recipientId: project.client?.id },
          _avg: { rating: true },
          _count: { rating: true }
        });

        const myReviewIs = await prisma.review.aggregate({
              where: {
                projectId: project.id,
                authorId: session.user.id,
              },
              _avg: {
                rating: true,
              },
            })

      return {
     
        id: project.id,
        title: project.title,
        description: project.description,
        category: project.category?.name || 'Uncategorized',
        categoryIcon: project.category?.icon ? `/assets/image/category/${project.category.icon}` : '/assets/image/category/default.svg',
        budget: project.budget,
        duration: project.duration,
        status: project.status,
        bidsCount: project._count?.bids || 0,
        myReviewIs: myReviewIs._avg.rating || 0,
        client: {
          id: project.client?.id,
          name: project.client?.profile ? 
            `${project.client.profile.firstName || ''} ${project.client.profile.lastName || ''}`.trim() || project.client.email :
            project.client?.email || 'Unknown Client',
          profileImage: project.client?.image || '/assets/image/user.png',
          rating:  clientReviews._avg.rating || 0,
          reviewCount: project.client?._count?.receivedReviews || 0
        },
        createdAt: project.createdAt.toISOString(),
        updatedAt: project.updatedAt.toISOString(),
        // Include bid info for non-recommended projects
        ...(project.bids && project.bids.length > 0 && {
          myBid: {
            id: project.bids[0].id,
            status: project.bids[0].status,
            amount: project.bids[0].amount,
            duration: project.bids[0].duration,
            proposal: project.bids[0].proposal,
            createdAt: project.bids[0].createdAt.toISOString()
          }
        })
      }
    }));

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

    // Special message for recommended projects based on category subscriptions
    let message = `Found ${totalCount} project${totalCount !== 1 ? 's' : ''} for ${status.toLowerCase()} status`;
    if (status.toUpperCase() === 'RECOMMENDED') {
      if (!hasActiveSubscription) {
        message = `No recommended projects found. Subscribe to categories to see relevant projects.`;
      } else {
        message = `Found ${totalCount} recommended project${totalCount !== 1 ? 's' : ''} from your subscribed categories.`;
      }
    }

    return NextResponse.json({
      success: true,
      message,
      data: {
        projects: formattedProjects,
        counts: {
          recommended: recommendedCount,
          proposed: proposedCount,
          awarded: awardedCount,
          cancelled: cancelledCount,
          completed: completedCount
        },
        pagination: {
          currentPage: page,
          totalPages,
          totalItems: totalCount,
          itemsPerPage: limit,
          hasNextPage,
          hasPrevPage
        },
        subscription: {
          isActive: hasActiveSubscription,
          required: status.toUpperCase() === 'RECOMMENDED',
          canBid: hasActiveSubscription || status.toUpperCase() !== 'RECOMMENDED',
          subscribedCategoryIds: status.toUpperCase() === 'RECOMMENDED' ? subscribedCategoryIds : undefined
        }
      }
    });

  } catch (error) {
    console.error('Error fetching freelancer projects:', error);
    
    let errorMessage = 'Unable to fetch your projects at this time. Please try again later.';
    let details = 'Unknown error occurred';
    
    if (error instanceof Error) {
      details = error.message;
      
      if (error.message.includes('connect') || error.message.includes('ECONNREFUSED')) {
        errorMessage = 'Database connection failed. Please contact support if this persists.';
      } else if (error.message.includes('relation') || error.message.includes('table')) {
        errorMessage = 'Database schema error. Please contact support.';
      } else if (error.message.includes('timeout')) {
        errorMessage = 'Request timed out. Please try again.';
      } else if (error.message.includes('permission') || error.message.includes('access')) {
        errorMessage = 'Access denied. Please check your permissions.';
      }
    }
    
    return NextResponse.json(
      { 
        success: false,
        error: 'Projects Load Failed',
        message: errorMessage,
        details: details,
        support: 'If this error persists, please contact support with error code: PROJECTS_LOAD_001'
      },
      { status: 500 }
    );
  }
}

export async function POST(req: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    
    if (!session?.user?.email) {
      return NextResponse.json(
        { 
          success: false,
          error: 'Authentication Required',
          message: 'Please log in to submit a bid. Your session may have expired.',
          action: 'redirect_login'
        },
        { status: 401 }
      );
    }

    const body = await req.json();
    const { projectId, amount, deliveryTime, proposal } = body;

    // Validate required fields
    if (!projectId || !amount || !deliveryTime || !proposal) {
      return NextResponse.json(
        { 
          success: false,
          error: 'Validation Failed',
          message: 'Please fill in all required fields: project, amount, delivery time, and proposal.',
          details: 'Missing required fields for bid submission'
        },
        { status: 400 }
      );
    }

    // Check if project exists and is open
    const project = await prisma.project.findUnique({
      where: { id: projectId },
      select: { 
        id: true, 
        status: true,
        clientId: true
      }
    });

    if (!project) {
      return NextResponse.json(
        { 
          success: false,
          error: 'Project Not Found',
          message: 'The project you are trying to bid on does not exist or has been removed.',
          details: 'Project not found in database'
        },
        { status: 404 }
      );
    }

    if (project.status !== 'OPEN') {
      return NextResponse.json(
        { 
          success: false,
          error: 'Project Closed',
          message: 'This project is no longer accepting bids. It may have been awarded or cancelled.',
          details: `Project status is ${project.status}`
        },
        { status: 400 }
      );
    }

    // Check if freelancer has already bid on this project
    const existingBid = await prisma.bid.findFirst({
      where: {
        projectId,
        freelancerId: session.user.id
      }
    });

    if (existingBid) {
      return NextResponse.json(
        { 
          success: false,
          error: 'Bid Already Submitted',
          message: 'You have already submitted a bid for this project. You can update your existing bid from the project details page.',
          details: 'Duplicate bid attempt detected',
          existingBidId: existingBid.id
        },
        { status: 400 }
      );
    }

    // Create the bid
    const bid = await prisma.bid.create({
      data: {
        amount: parseFloat(amount),
        duration: parseInt(deliveryTime),
        proposal,
        projectId,
        freelancerId: session.user.id,
        status: 'PENDING'
      },
      include: {
        project: {
          select: {
            title: true,
            client: {
              select: {
                id: true,
                email: true,
                profile: {
                  select: {
                    firstName: true,
                    lastName: true
                  }
                }
              }
            }
          }
        }
      }
    });

    // TODO: Send notification to project owner about new bid

    return NextResponse.json({
      success: true,
      message: `Bid submitted successfully! Your proposal of €${bid.amount} with ${bid.duration} days delivery has been sent to the client. You will be notified when they respond.`,
      data: {
        bid: {
          id: bid.id,
          amount: bid.amount,
          deliveryTime: bid.duration,
          proposal: bid.proposal,
          status: bid.status,
          createdAt: bid.createdAt.toISOString()
        },
        projectTitle: bid.project?.title || 'Unknown Project'
      }
    });

  } catch (error) {
    console.error('Error creating bid:', error);
    
    let errorMessage = 'Unable to submit your bid at this time. Please try again later.';
    let details = 'Unknown error occurred';
    
    if (error instanceof Error) {
      details = error.message;
      
      if (error.message.includes('connect') || error.message.includes('ECONNREFUSED')) {
        errorMessage = 'Database connection failed. Please contact support if this persists.';
      } else if (error.message.includes('constraint') || error.message.includes('duplicate')) {
        errorMessage = 'You may have already submitted a bid for this project.';
      } else if (error.message.includes('validation') || error.message.includes('invalid')) {
        errorMessage = 'Invalid bid data provided. Please check your inputs.';
      }
    }
    
    return NextResponse.json(
      { 
        success: false,
        error: 'Bid Submission Failed',
        message: errorMessage,
        details: details,
        support: 'If this error persists, please contact support with error code: BID_SUBMIT_001'
      },
      { status: 500 }
    );
  }
}
