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';
import { Prisma } from '@prisma/client';

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

// Validation schema for updating a membership plan
const updateMembershipPlanSchema = z.object({
  name: z.string().min(1).max(100).optional(),
  description: z.string().max(500).optional().nullable(),
  price: z.number().nonnegative().optional(),
  durationMonths: z.number().int().min(1).optional(),
  freeHours: z.number().int().min(0).optional().nullable(),
  bookingDiscount: z.number().min(0).max(100).optional().nullable(),
  storeDiscount: z.number().min(0).max(100).optional().nullable(),
  extraBenefits: z.array(z.string()).optional(),
  isActive: z.boolean().optional(),
});

// GET /api/membership-plans/[id] - Get plan details with subscriber count
export async function GET(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

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

    const { id } = await context.params;

    const plan = await db.membershipPlan.findFirst({
      where: {
        id,
        organizationId: session.user.organizationId,
      },
      include: {
        memberships: {
          where: {
            status: 'ACTIVE',
          },
          include: {
            client: {
              select: {
                id: true,
                firstName: true,
                lastName: true,
                email: true,
              },
            },
          },
          orderBy: {
            endDate: 'asc',
          },
        },
        _count: {
          select: {
            memberships: true,
          },
        },
      },
    });

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

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

    const activeMemberships = plan.memberships.filter(m => m.status === 'ACTIVE');
    const expiringMemberships = activeMemberships.filter(
      m => m.endDate <= sevenDaysFromNow && m.endDate > now
    );

    // Transform response
    const planWithDetails = {
      ...plan,
      subscriberCount: activeMemberships.length,
      totalSubscriptions: plan._count.memberships,
      expiringCount: expiringMemberships.length,
      benefitsSummary: {
        freeHours: plan.courtHours || 0,
        bookingDiscount: plan.discountPercent ? Number(plan.discountPercent) : 0,
        extraBenefits: plan.benefits || [],
      },
      activeSubscribers: activeMemberships.map(m => ({
        membershipId: m.id,
        client: m.client,
        startDate: m.startDate,
        endDate: m.endDate,
        remainingHours: m.remainingHours,
        isExpiring: m.endDate <= sevenDaysFromNow,
      })),
    };

    return NextResponse.json(planWithDetails);
  } catch (error) {
    console.error('Error fetching membership plan:', error);
    return NextResponse.json(
      { error: 'Failed to fetch membership plan' },
      { status: 500 }
    );
  }
}

// PUT /api/membership-plans/[id] - Update plan
export async function PUT(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

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

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

    const { id } = await context.params;

    // Verify plan exists and belongs to user's organization
    const existingPlan = await db.membershipPlan.findFirst({
      where: {
        id,
        organizationId: session.user.organizationId,
      },
    });

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

    const body = await request.json();

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

    const {
      name,
      description,
      price,
      durationMonths,
      freeHours,
      bookingDiscount,
      storeDiscount,
      extraBenefits,
      isActive,
    } = validationResult.data;

    // Build update data
    const updateData: Prisma.MembershipPlanUpdateInput = {};

    if (name !== undefined) updateData.name = name;
    if (description !== undefined) updateData.description = description;
    if (price !== undefined) updateData.price = price;
    if (durationMonths !== undefined) updateData.durationMonths = durationMonths;
    if (freeHours !== undefined) updateData.courtHours = freeHours;
    if (bookingDiscount !== undefined) updateData.discountPercent = bookingDiscount;
    if (isActive !== undefined) updateData.isActive = isActive;

    // Update benefits array if provided
    if (extraBenefits !== undefined || storeDiscount !== undefined) {
      const currentBenefits = existingPlan.benefits || [];
      // Remove old store discount entries
      const filteredBenefits = currentBenefits.filter(
        b => !b.includes('store discount')
      );

      updateData.benefits = [
        ...(extraBenefits !== undefined ? extraBenefits : filteredBenefits),
        ...(storeDiscount ? [`${storeDiscount}% store discount`] : []),
      ];
    }

    const plan = await db.membershipPlan.update({
      where: { id },
      data: updateData,
      include: {
        _count: {
          select: {
            memberships: {
              where: {
                status: 'ACTIVE',
              },
            },
          },
        },
      },
    });

    // Transform response
    const planWithSummary = {
      ...plan,
      subscriberCount: plan._count.memberships,
      benefitsSummary: {
        freeHours: plan.courtHours || 0,
        bookingDiscount: plan.discountPercent ? Number(plan.discountPercent) : 0,
        extraBenefits: plan.benefits || [],
      },
    };

    return NextResponse.json(planWithSummary);
  } catch (error) {
    console.error('Error updating membership plan:', error);
    return NextResponse.json(
      { error: 'Failed to update membership plan' },
      { status: 500 }
    );
  }
}

// DELETE /api/membership-plans/[id] - Soft delete (set isActive = false)
export async function DELETE(
  request: NextRequest,
  context: RouteContext
) {
  try {
    const session = await getServerSession(authOptions);

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

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

    const { id } = await context.params;

    // Verify plan exists and belongs to user's organization
    const existingPlan = await db.membershipPlan.findFirst({
      where: {
        id,
        organizationId: session.user.organizationId,
      },
      include: {
        _count: {
          select: {
            memberships: {
              where: {
                status: 'ACTIVE',
              },
            },
          },
        },
      },
    });

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

    // Warn if there are active subscriptions
    const activeCount = existingPlan._count.memberships;

    // Soft delete - set isActive to false
    await db.membershipPlan.update({
      where: { id },
      data: {
        isActive: false,
      },
    });

    return NextResponse.json({
      message: 'Membership plan deactivated successfully',
      activeSubscriptionsAffected: activeCount,
      note: activeCount > 0
        ? 'This plan still has active subscriptions that will remain valid until expiration'
        : undefined,
    });
  } catch (error) {
    console.error('Error deactivating membership plan:', error);
    return NextResponse.json(
      { error: 'Failed to deactivate membership plan' },
      { status: 500 }
    );
  }
}
