import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/api-guards';
import { createAuditLog } from '@/lib/audit-logger';

// GET: Fetch a single plan by ID
export const GET = withAuth(async (req, { prisma, params }) => {
  const unwrappedParams = await params;
  const id = parseInt(unwrappedParams.id);

  if (isNaN(id)) {
    return NextResponse.json({ error: 'ID no válido.' }, { status: 400 });
  }

  const plan = await prisma.compensationPlan.findUnique({
    where: { id },
    include: { rules: true }
  });

  if (!plan) {
    return NextResponse.json({ error: 'Plan no encontrado.' }, { status: 404 });
  }

  return NextResponse.json({ plan });
});

// PUT: Update or Version a plan (restricted to admin and director)
export const PUT = withAuth(async (req, { session, prisma, params }) => {
  const unwrappedParams = await params;
  const id = parseInt(unwrappedParams.id);
  const body = await req.json();

  if (isNaN(id)) {
    return NextResponse.json({ error: 'ID no válido.' }, { status: 400 });
  }

  const plan = await prisma.compensationPlan.findUnique({
    where: { id }
  });

  if (!plan) {
    return NextResponse.json({ error: 'Plan no encontrado.' }, { status: 404 });
  }

  // Versioning replication if the plan is currently ACTIVE
  if (plan.status === 'ACTIVE') {
    const newPlan = await prisma.$transaction(async (tx: any) => {
      // 1. Mark current plan version as INACTIVE
      const oldPlanUpdated = await tx.compensationPlan.update({
        where: { id },
        data: {
          status: 'INACTIVE',
          validityEnd: new Date()
        }
      });

      // Log the old plan status update
      await createAuditLog(tx, {
        userId: session.userId,
        action: 'UPDATE',
        targetTable: 'compensation_plans',
        targetId: id,
        previousValue: plan,
        newValue: oldPlanUpdated,
        ipAddress: req.headers.get('x-forwarded-for') || '127.0.0.1'
      });

      // 2. Clone to a new version record
      const clonedPlan = await tx.compensationPlan.create({
        data: {
          name: body.name || plan.name,
          code: body.code || plan.code,
          validityStart: new Date(), // starts now
          validityEnd: body.validityEnd ? new Date(body.validityEnd) : null,
          type: body.type || plan.type,
          formula: body.formula !== undefined ? body.formula : plan.formula,
          metaAmount: body.metaAmount !== undefined ? parseFloat(body.metaAmount) : plan.metaAmount,
          percentageRate: body.percentageRate !== undefined ? parseFloat(body.percentageRate) : plan.percentageRate,
          maxCap: body.maxCap !== undefined ? parseFloat(body.maxCap) : plan.maxCap,
          status: 'ACTIVE',
          version: plan.version + 1,
          createdBy: session.userId
        }
      });

      // Log the new cloned plan version creation
      await createAuditLog(tx, {
        userId: session.userId,
        action: 'CREATE',
        targetTable: 'compensation_plans',
        targetId: clonedPlan.id,
        newValue: clonedPlan,
        ipAddress: req.headers.get('x-forwarded-for') || '127.0.0.1'
      });

      // 3. Clone rules associated with the original plan
      const originalRules = await tx.calculationRule.findMany({
        where: { planId: id }
      });

      if (originalRules.length > 0) {
        await tx.calculationRule.createMany({
          data: originalRules.map((r: any) => ({
            planId: clonedPlan.id,
            type: r.type,
            minAchievement: r.minAchievement,
            maxAchievement: r.maxAchievement,
            rate: r.rate,
            payoutAmount: r.payoutAmount
          }))
        });
      }

      return clonedPlan;
    });

    return NextResponse.json({ plan: newPlan, versioned: true });
  } else {
    // In-place update for DRAFT / INACTIVE plans
    const updatedPlan = await prisma.$transaction(async (tx: any) => {
      const p = await tx.compensationPlan.update({
        where: { id },
        data: {
          name: body.name,
          code: body.code,
          validityStart: body.validityStart ? new Date(body.validityStart) : undefined,
          validityEnd: body.validityEnd !== undefined ? (body.validityEnd ? new Date(body.validityEnd) : null) : undefined,
          type: body.type,
          formula: body.formula,
          metaAmount: body.metaAmount !== undefined ? (body.metaAmount ? parseFloat(body.metaAmount) : null) : undefined,
          percentageRate: body.percentageRate !== undefined ? (body.percentageRate ? parseFloat(body.percentageRate) : null) : undefined,
          maxCap: body.maxCap !== undefined ? (body.maxCap ? parseFloat(body.maxCap) : null) : undefined,
          status: body.status
        }
      });

      await createAuditLog(tx, {
        userId: session.userId,
        action: 'UPDATE',
        targetTable: 'compensation_plans',
        targetId: id,
        previousValue: plan,
        newValue: p,
        ipAddress: req.headers.get('x-forwarded-for') || '127.0.0.1'
      });

      return p;
    });

    return NextResponse.json({ plan: updatedPlan, versioned: false });
  }
}, ['admin', 'director']);
