← back to Dear Bubbe Nextjs

app/api/pricing/route.ts

148 lines

/**
 * Pricing API Endpoint
 * 
 * Provides pricing information and plan recommendations
 * GET /api/pricing - Get all plans
 * POST /api/pricing/recommend - Get plan recommendation based on features
 * POST /api/pricing/upgrade - Upgrade user plan
 */

import { NextRequest, NextResponse } from 'next/server';
import { 
  getAllPlansWithComparison,
  getRequiredPlanForFeatures,
  getPlanSummary,
  generateUpsellMessage,
  FeatureKey,
  PlanId
} from '@/lib/bubbe-pricing';
import {
  getUserSession,
  updateUserPlan,
  getUserIdFromRequest
} from '@/lib/user-session';

export async function GET(req: NextRequest) {
  try {
    // Get user's current plan if they're logged in
    const userId = req.cookies.get('userId')?.value || 
                   req.headers.get('x-user-id');
    
    const currentPlan = userId ? getUserSession(userId).plan : 'basic';
    
    // Get all plans with comparison
    const plans = getAllPlansWithComparison();
    
    return NextResponse.json({
      currentPlan,
      plans,
      recommendation: "Oy vey, looking to spend some money? Good, I need a new kitchen!"
    });
  } catch (error) {
    console.error('Pricing API error:', error);
    return NextResponse.json(
      { error: 'Failed to fetch pricing information' },
      { status: 500 }
    );
  }
}

export async function POST(req: NextRequest) {
  try {
    const body = await req.json();
    const { action } = body;
    
    // Get user ID
    const userId = req.cookies.get('userId')?.value || 
                   req.headers.get('x-user-id') ||
                   `user_${Date.now()}`;
    
    if (action === 'recommend') {
      // Recommend a plan based on requested features
      const { features } = body as { features: FeatureKey[] };
      
      if (!features || !Array.isArray(features)) {
        return NextResponse.json(
          { error: 'Features array required' },
          { status: 400 }
        );
      }
      
      const recommendedPlan = getRequiredPlanForFeatures(features);
      const planDetails = getPlanSummary(recommendedPlan);
      const currentPlan = getUserSession(userId).plan;
      
      const response = {
        recommendedPlan: planDetails,
        currentPlan,
        needsUpgrade: currentPlan !== recommendedPlan && 
                      ['basic', 'plus'].indexOf(currentPlan) < 
                      ['basic', 'plus', 'max'].indexOf(recommendedPlan),
        upsellMessage: generateUpsellMessage(currentPlan, recommendedPlan),
        requestedFeatures: features
      };
      
      return NextResponse.json(response);
    }
    
    if (action === 'upgrade') {
      // Upgrade user to a new plan
      const { plan } = body as { plan: PlanId };
      
      if (!plan || !['basic', 'plus', 'max'].includes(plan)) {
        return NextResponse.json(
          { error: 'Valid plan required (basic, plus, or max)' },
          { status: 400 }
        );
      }
      
      const session = updateUserPlan(userId, plan);
      const planDetails = getPlanSummary(plan);
      
      // Set cookie to persist user ID
      const response = NextResponse.json({
        success: true,
        message: `Mazel tov! You're now on ${planDetails.name}. Your mother would be proud... maybe.`,
        plan: planDetails,
        session: {
          userId: session.userId,
          plan: session.plan,
          subscribedAt: session.subscribedAt
        }
      });
      
      response.cookies.set('userId', userId, {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'lax',
        maxAge: 60 * 60 * 24 * 365 // 1 year
      });
      
      return response;
    }
    
    if (action === 'check') {
      // Check user's current plan and features
      const session = getUserSession(userId);
      const planDetails = getPlanSummary(session.plan);
      
      return NextResponse.json({
        userId,
        ...planDetails,
        subscribedAt: session.subscribedAt
      });
    }
    
    return NextResponse.json(
      { error: 'Invalid action. Use: recommend, upgrade, or check' },
      { status: 400 }
    );
    
  } catch (error) {
    console.error('Pricing API error:', error);
    return NextResponse.json(
      { error: 'Failed to process pricing request' },
      { status: 500 }
    );
  }
}