import { NextRequest, NextResponse } from 'next/server';
import { verifyN8nSignature } from '@/lib/n8n-auth';
import { setupLogRedaction } from '@/lib/log-redactor';

setupLogRedaction();

export async function POST(req: NextRequest) {
  try {
    const signature = req.headers.get('x-n8n-signature');
    if (!verifyN8nSignature(signature)) {
      return NextResponse.json({ error: 'No autorizado. Firma no válida.' }, { status: 401 });
    }

    const body = await req.json();
    const {
      period,
      simulateOnly,
      collaborators,
      activePlans,
      goals,
      salesResults,
      pastPeriods,
      approvedPastSettlements,
      pastSalesResults,
      pastGoals
    } = body;

    if (!period || !Array.isArray(collaborators) || !Array.isArray(activePlans)) {
      return NextResponse.json({ error: 'Parámetros no válidos.' }, { status: 400 });
    }

    const results: any[] = [];
    let totalCommission = 0;
    let totalAdjustment = 0;
    let count = 0;

    for (const collaborator of collaborators) {
      // Find matching plans
      const matchingPlans = activePlans.filter((plan: any) => {
        if (!plan.validityStart) {
          return false;
        }
        const startStr = plan.validityStart.substring(0, 7);
        const isStartOk = startStr <= period;
        let isEndOk = true;
        if (plan.validityEnd) {
          const endStr = plan.validityEnd.substring(0, 7);
          isEndOk = endStr >= period;
        }
        const matchesArea = plan.code.toLowerCase() === collaborator.area.toLowerCase() ||
                            plan.code.startsWith('PLAN-E2E') ||
                            plan.code.startsWith('PLAN-INT');
        return isStartOk && isEndOk && matchesArea;
      });

      for (const plan of matchingPlans) {
        // Find goal
        const goal = goals.find((g: any) => g.targetType === 'INDIVIDUAL' && g.targetId === collaborator.id);
        const goalAmount = goal ? parseFloat(goal.amount.toString()) : 0;

        // Sum current sales
        const sales = salesResults.filter((s: any) => s.userId === collaborator.id);
        const salesAmount = sales.reduce((sum: number, s: any) => sum + parseFloat(s.amount.toString()), 0);

        const achievementPercentage = goalAmount > 0 ? salesAmount / goalAmount : 0;

        let calculatedCommission = 0;
        let calculatedBonus = 0;
        for (const rule of plan.rules) {
          const min = parseFloat(rule.minAchievement.toString());
          const max = parseFloat(rule.maxAchievement.toString());
          if (achievementPercentage >= min && achievementPercentage <= max) {
            if (rule.type === 'TIER') {
              calculatedCommission += salesAmount * parseFloat(rule.rate.toString());
            } else if (rule.type === 'BONUS') {
              calculatedBonus += parseFloat(rule.payoutAmount.toString());
            }
          }
        }

        let totalPayout = calculatedCommission + calculatedBonus;
        if (plan.maxCap !== null && totalPayout > parseFloat(plan.maxCap.toString())) {
          totalPayout = parseFloat(plan.maxCap.toString());
        }

        // Retroactive adjustments / PMS clawbacks
        let planAdjustmentAmount = 0;
        const adjustments = [];

        for (const pastPeriod of pastPeriods) {
          const approvedSettlement = approvedPastSettlements.find((s: any) => 
            s.userId === collaborator.id && s.period === pastPeriod && s.planId === plan.id
          );

          if (approvedSettlement) {
            const pastSales = pastSalesResults.filter((s: any) => 
              s.userId === collaborator.id && s.period === pastPeriod
            );
            const liveSalesAmount = pastSales.reduce((sum: number, s: any) => sum + parseFloat(s.amount.toString()), 0);
            const originalSalesAmount = parseFloat(approvedSettlement.salesAmount.toString());

            if (Math.abs(liveSalesAmount - originalSalesAmount) > 0.001) {
              const pastGoal = pastGoals.find((g: any) => 
                g.targetType === 'INDIVIDUAL' && g.targetId === collaborator.id && g.period === pastPeriod
              );
              const pastGoalAmount = pastGoal ? parseFloat(pastGoal.amount.toString()) : 0;
              const liveAchievementPercentage = pastGoalAmount > 0 ? liveSalesAmount / pastGoalAmount : 0;

              let correctedCommission = 0;
              let correctedBonus = 0;
              for (const rule of plan.rules) {
                const min = parseFloat(rule.minAchievement.toString());
                const max = parseFloat(rule.maxAchievement.toString());
                if (liveAchievementPercentage >= min && liveAchievementPercentage <= max) {
                  if (rule.type === 'TIER') {
                    correctedCommission += liveSalesAmount * parseFloat(rule.rate.toString());
                  } else if (rule.type === 'BONUS') {
                    correctedBonus += parseFloat(rule.payoutAmount.toString());
                  }
                }
              }

              let correctedPayout = correctedCommission + correctedBonus;
              if (plan.maxCap !== null && correctedPayout > parseFloat(plan.maxCap.toString())) {
                correctedPayout = parseFloat(plan.maxCap.toString());
              }

              const previouslyPaidPayout = parseFloat(approvedSettlement.totalPayout.toString());
              const delta = correctedPayout - previouslyPaidPayout;

              if (Math.abs(delta) > 0.001) {
                planAdjustmentAmount += delta;
                adjustments.push({
                  period,
                  planId: plan.id,
                  userId: collaborator.id,
                  salesAmount: liveSalesAmount,
                  goalAmount: pastGoalAmount,
                  achievementPercentage: liveAchievementPercentage,
                  calculatedCommission: correctedCommission,
                  calculatedBonus: correctedBonus,
                  adjustmentAmount: delta,
                  totalPayout: delta,
                  status: simulateOnly ? 'SIMULATED' : 'PENDING',
                  originalSettlementId: approvedSettlement.id,
                  adjustmentNotes: `Retroactive adjustment for ${pastPeriod}`
                });
              }
            }
          }
        }

        const finalTotalPayout = totalPayout + planAdjustmentAmount;

        results.push({
          main: {
            period,
            planId: plan.id,
            userId: collaborator.id,
            salesAmount,
            goalAmount,
            achievementPercentage,
            calculatedCommission,
            calculatedBonus,
            adjustmentAmount: planAdjustmentAmount,
            totalPayout: finalTotalPayout,
            status: simulateOnly ? 'SIMULATED' : 'PENDING',
            adjustmentNotes: planAdjustmentAmount !== 0 ? `Includes adjustments from past periods: ${planAdjustmentAmount}` : null
          },
          adjustments
        });

        totalCommission += calculatedCommission + calculatedBonus;
        totalAdjustment += planAdjustmentAmount;
        count++;
      }
    }

    return NextResponse.json({
      success: true,
      results,
      metadata: {
        count,
        totalCommission,
        totalAdjustment
      }
    });
  } catch (err: any) {
    console.error('process-formula error:', err);
    return NextResponse.json({ error: err.message || 'Error al procesar la fórmula.' }, { status: 500 });
  }
}
