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

interface RouteContext {
  params: Promise<{ id: string }>;
}

// Validation schema for renewal
const renewMembershipSchema = z.object({
  planId: z.string().cuid().optional(), // Optional: change plan during renewal
  extendMonths: z.number().int().min(1).optional(), // Override default extension
});

// POST /api/memberships/[id]/renew - Renew membership
export async function POST(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

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

    // Check if user has appropriate role
    const allowedRoles = ['SUPER_ADMIN', 'ORG_ADMIN', 'SITE_ADMIN', 'RECEPTIONIST'];
    if (!allowedRoles.includes(session.user.role)) {
      return NextResponse.json(
        { error: 'Forbidden: Insufficient permissions' },
        { status: 403 }
      );
    }

    const { id } = await context.params;

    // Verify membership exists and belongs to organization
    const existingMembership = await db.membership.findFirst({
      where: {
        id,
        plan: {
          organizationId: session.user.organizationId,
        },
      },
      include: {
        plan: true,
        client: {
          select: {
            id: true,
            firstName: true,
            lastName: true,
          },
        },
      },
    });

    if (!existingMembership) {
      return NextResponse.json(
        { error: 'Membership not found' },
        { status: 404 }
      );
    }

    // Cannot renew a cancelled membership
    if (existingMembership.status === 'CANCELLED') {
      return NextResponse.json(
        { error: 'Cannot renew a cancelled membership. Create a new membership instead.' },
        { status: 400 }
      );
    }

    // Parse optional body
    let body = {};
    try {
      body = await request.json();
    } catch {
      // Empty body is acceptable
    }

    // Validate input
    const validationResult = renewMembershipSchema.safeParse(body);
    if (!validationResult.success) {
      return NextResponse.json(
        {
          error: 'Invalid renewal data',
          details: validationResult.error.flatten().fieldErrors,
        },
        { status: 400 }
      );
    }

    const { planId, extendMonths } = validationResult.data;

    // Determine which plan to use
    let targetPlan = existingMembership.plan;

    if (planId && planId !== existingMembership.planId) {
      // Verify new plan exists and is active
      const newPlan = await db.membershipPlan.findFirst({
        where: {
          id: planId,
          organizationId: session.user.organizationId,
          isActive: true,
        },
      });

      if (!newPlan) {
        return NextResponse.json(
          { error: 'New membership plan not found or inactive' },
          { status: 404 }
        );
      }

      targetPlan = newPlan;
    }

    // Calculate new end date
    // Extend from current endDate (not from now) to avoid losing time
    const currentEndDate = existingMembership.endDate;
    const now = new Date();

    // If membership is already expired, extend from now instead
    const baseDate = currentEndDate > now ? currentEndDate : now;

    const extensionMonths = extendMonths || targetPlan.durationMonths;
    const newEndDate = new Date(baseDate);
    newEndDate.setMonth(newEndDate.getMonth() + extensionMonths);

    // Update membership
    const membership = await db.membership.update({
      where: { id },
      data: {
        planId: targetPlan.id,
        status: 'ACTIVE',
        endDate: newEndDate,
        remainingHours: targetPlan.courtHours || null, // Reset hours
        // Keep startDate as is - it's the original start
      },
      include: {
        plan: {
          select: {
            id: true,
            name: true,
            price: true,
            durationMonths: true,
            courtHours: true,
            discountPercent: true,
            benefits: true,
          },
        },
        client: {
          select: {
            id: true,
            firstName: true,
            lastName: true,
            email: true,
            phone: true,
          },
        },
      },
    });

    // Calculate computed fields
    const sevenDaysFromNow = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);

    const membershipWithDetails = {
      ...membership,
      renewed: true,
      previousEndDate: existingMembership.endDate,
      previousPlan: existingMembership.planId !== targetPlan.id
        ? existingMembership.plan.name
        : undefined,
      isExpiring: membership.endDate <= sevenDaysFromNow,
      daysUntilExpiry: Math.ceil((membership.endDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)),
      benefitsSummary: {
        freeHours: membership.plan.courtHours || 0,
        hoursRemaining: membership.remainingHours || 0,
        bookingDiscount: membership.plan.discountPercent ? Number(membership.plan.discountPercent) : 0,
        extraBenefits: membership.plan.benefits || [],
      },
    };

    return NextResponse.json(membershipWithDetails);
  } catch (error) {
    console.error('Error renewing membership:', error);
    return NextResponse.json(
      { error: 'Failed to renew membership' },
      { status: 500 }
    );
  }
}
