import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/prisma';
import { stripe, createPaymentIntent, findCustomerByEmail, createCustomer } from '@/lib/stripe';

interface CreatePaymentIntentRequest {
  categoryIds: string[];
  amount: number;
  currency: string;
  country: string;
}

export async function POST(req: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    
    if (!session?.user?.email) {
      return NextResponse.json(
        { error: 'Authentication required' },
        { status: 401 }
      );
    }

    const body: CreatePaymentIntentRequest = await req.json();
    const { categoryIds, amount, currency, country } = body;

    // Validate input
    if (!categoryIds || !Array.isArray(categoryIds) || categoryIds.length === 0) {
      return NextResponse.json(
        { error: 'Category IDs are required' },
        { status: 400 }
      );
    }

    if (!amount || amount <= 0) {
      return NextResponse.json(
        { error: 'Valid amount is required' },
        { status: 400 }
      );
    }

    if (!currency || !country) {
      return NextResponse.json(
        { error: 'Currency and country are required' },
        { status: 400 }
      );
    }

    try {
      // Validate categories exist
      const categories = await prisma.category.findMany({
        where: {
          id: { in: categoryIds }
        }
      });

      if (categories.length !== categoryIds.length) {
        return NextResponse.json(
          { error: 'One or more categories not found' },
          { status: 400 }
        );
      }

      // Check for existing active subscriptions
      const existingSubscriptions = await prisma.categorySubscription.findMany({
        where: {
          userId: session.user.id,
          categoryId: { in: categoryIds },
          status: 'ACTIVE',
          endDate: { gte: new Date() }
        }
      });

      if (existingSubscriptions.length > 0) {
        const activeCategories = existingSubscriptions.map(sub => sub.categoryId);
        const activeCategoryNames = categories
          .filter(cat => activeCategories.includes(cat.id))
          .map(cat => cat.name);

        return NextResponse.json(
          { 
            error: 'Active subscription exists',
            message: `You already have active subscriptions for: ${activeCategoryNames.join(', ')}`
          },
          { status: 409 }
        );
      }

      // Ensure we have user profile info to populate required customer name/address
      const user = await prisma.user.findUnique({
        where: { email: session.user.email },
        include: { profile: true }
      });

      const customerName = user?.profile 
        ? `${user.profile.firstName || ''} ${user.profile.lastName || ''}`.trim()
        : session.user.name || session.user.email;

      const inferredCountry = (country || user?.profile?.countryId || '').toString().slice(0, 2).toUpperCase();
      const customerAddress = user?.profile ? {
        line1: user.profile.address || undefined,
        city: user.profile.city || undefined,
        postal_code: (user.profile as any)?.zipCode || undefined,
        country: inferredCountry || undefined,
      } : undefined;

      // Validate presence of name and address for export compliance
      const missing: string[] = [];
      if (!customerName) missing.push('name');
      if (!customerAddress?.line1) missing.push('address line1');
      if (!customerAddress?.city) missing.push('city');
      if (!customerAddress?.country) missing.push('country');
      if (missing.length > 0) {
        return NextResponse.json(
          {
            error: 'Customer information required',
            message: 'As per Indian regulations, export transactions require a customer name and address.',
            code: 'REQUIRES_CUSTOMER_DETAILS',
            missingFields: missing
          },
          { status: 400 }
        );
      }

      // Find or create Stripe customer with required details
      let customer = await findCustomerByEmail(session.user.email);
      if (!customer) {
        customer = await createCustomer(
          session.user.email,
          customerName,
          {
            userId: session.user.id,
            source: 'smile24_platform'
          },
          customerAddress
        );
      } else if (customer) {
        const hasAddr = !!(customer.address as any)?.line1 && !!(customer.address as any)?.country;
        if (!(customer as any).name || !hasAddr) {
          const { stripe } = await import('@/lib/stripe');
          await stripe.customers.update(((customer as any).id) as string, {
            name: (customer as any).name || customerName,
            address: hasAddr ? undefined : customerAddress,
          } as any);
          customer = await stripe.customers.retrieve(((customer as any).id) as string) as any;
        }
      }

      if (!customer) {
        return NextResponse.json(
          {
            error: 'Customer creation failed',
            message: 'Unable to prepare customer details required for export transactions.'
          },
          { status: 500 }
        );
      }

      // Prepare shipping details for export regulations compliance
      const shipping = {
        name: (customer as any).name as string,
        address: {
          line1: ((customer as any).address as any)?.line1 as string,
          city: ((customer as any).address as any)?.city as string,
          postal_code: ((customer as any).address as any)?.postal_code as string,
          country: ((customer as any).address as any)?.country as string,
        }
      } as const;

      // Create payment intent with customer and shipping
      const paymentIntent = await createPaymentIntent(
        amount,
        currency,
        {
          userId: session.user.id,
          categoryIds: categoryIds.join(','),
          country,
          customerEmail: session.user.email,
          type: 'membership_subscription'
        },
        customer.id,
        shipping
      );

      // Note: Payment record will be created by webhook upon successful payment

      // Return client secret for frontend
      return NextResponse.json({
        success: true,
        clientSecret: paymentIntent.client_secret,
        paymentIntentId: paymentIntent.id,
        customerId: customer.id,
        // Return amount in actual value (not cents) as stripe.ts handles conversion
        amount: amount,
        currency
      });

    } catch (dbError: any) {
      console.error('Database error:', dbError);
      return NextResponse.json(
        { 
          error: 'Database operation failed',
          message: 'Unable to process payment request. Please try again.'
        },
        { status: 500 }
      );
    }

  } catch (error: any) {
    console.error('Error creating payment intent:', error);
    return NextResponse.json(
      { 
        error: 'Payment processing error',
        message: error.message || 'Failed to create payment intent'
      },
      { status: 500 }
    );
  }
}