import { NextRequest, NextResponse } from 'next/server';
import { dbConnect } from '@/lib/dbConnect';
import { Order } from '@/models/Order';
import { Course } from '@/models/Course';
import { Student } from '@/models/Student';
import { Lesson } from '@/models/Lesson';
import { Admin } from '@/models/Admin';
import { requireAuth } from '@/lib/auth';
import { validateFields } from '@/lib/validation';

// GET /api/orders - List orders
export async function GET(req: NextRequest) {
  const auth = requireAuth(req);
  if (auth instanceof NextResponse) return auth;

  try {
    await dbConnect();
    const { searchParams } = new URL(req.url);
    const isAdmin = auth.user.role === 'admin' || auth.user.role === 'super_admin';

    const query: Record<string, any> = {};

    if (!isAdmin) {
      query.student = auth.user.id;
    } else {
      const studentId = searchParams.get('student');
      const gateway = searchParams.get('gateway');
      const status = searchParams.get('status');
      const bankConfirmation = searchParams.get('bankConfirmation');
      const search = searchParams.get('search')?.trim();

      if (studentId) query.student = studentId;
      if (gateway && gateway !== 'all') query.gateway = gateway;

      if (status && status !== 'all') {
        if (status === 'completed') {
          query.status = { $in: ['completed', 'succeeded'] };
        } else if (status === 'pending') {
          query.status = { $in: ['pending', 'initiated'] };
        } else {
          query.status = status;
        }
      }

      if (bankConfirmation) query['bankTransferDetails.adminConfirmationStatus'] = bankConfirmation;

      if (search) {
        const { Student } = await import('@/models/Student');
        const regex = new RegExp(search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i');

        const matchingStudents = await Student.find({
          $or: [{ name: regex }, { email: regex }],
        }).select('_id');
        const studentIds = matchingStudents.map((s) => s._id);

        const matchingCourses = await Course.find({
          title: regex,
        }).select('_id');
        const courseIds = matchingCourses.map((c) => c._id);

        const searchConditions: any[] = [
          { student: { $in: studentIds } },
          { courseId: { $in: courseIds } },
          { gatewayTransactionId: regex },
        ];

        // Check if valid ObjectId
        if (search.match(/^[0-9a-fA-F]{24}$/)) {
          searchConditions.push({ _id: search });
        }

        query.$or = searchConditions;
      }
    }

    const page = parseInt(searchParams.get('page') || '1', 10);
    const limit = parseInt(searchParams.get('limit') || '20', 10);
    const skip = (page - 1) * limit;

    const total = await Order.countDocuments(query);
    const orders = await Order.find(query)
      .populate('student', 'name email phoneNumber')
      .populate('courseId', 'title level courseType regularPrice offerPrice')
      .populate('lessons', 'title price chapterNumber durationMinutes')
      .populate('bankTransferDetails.confirmedBy', 'name email')
      .sort({ createdAt: -1 })
      .skip(skip)
      .limit(limit);

    return NextResponse.json({
      success: true,
      total,
      page,
      pages: Math.ceil(total / limit),
      count: orders.length,
      orders,
    });
  } catch (error: any) {
    return NextResponse.json(
      { success: false, error: error.message || 'Server error fetching orders' },
      { status: 500 }
    );
  }
}

// POST /api/orders - Initiate or create an order
export async function POST(req: NextRequest) {
  const auth = requireAuth(req);
  if (auth instanceof NextResponse) return auth;

  try {
    await dbConnect();
    const body = await req.json();

    const {
      courseId,
      course,
      courses: courseIds,
      lessons: lessonIds = [],
      studentId,
      gateway,
      gatewayTransactionId,
      gatewayResponse,
      amount,
      paymentRequired = true,
      notes,
    } = body;

    const isAdmin = auth.user.role === 'admin' || auth.user.role === 'super_admin';

    // Determine selected course ID (compulsory for every purchase/selection)
    const selectedCourseId = courseId || course || (Array.isArray(courseIds) && courseIds.length > 0 ? courseIds[0] : null);
    if (!selectedCourseId) {
      return NextResponse.json({ success: false, error: 'courseId is compulsory for every purchase/selection' }, { status: 400 });
    }

    // Verify course exists
    const targetCourse = await Course.findById(selectedCourseId);
    if (!targetCourse) {
      return NextResponse.json({ success: false, error: 'Selected course was not found' }, { status: 404 });
    }

    // Determine target student: Admin can specify studentId, otherwise default to logged in user
    let targetStudentId = auth.user.id;
    if (isAdmin && studentId) {
      targetStudentId = studentId;
    }

    // Validate gateway
    const selectedGateway = gateway || (paymentRequired ? 'stripe' : 'admin_bypass');
    if (!['stripe', 'paypal', 'bank_transfer', 'admin_bypass'].includes(selectedGateway)) {
      return NextResponse.json({ success: false, error: 'Invalid payment gateway' }, { status: 400 });
    }

    // Calculate default price
    let calculatedAmount = 0;
    const selectedLessonsArray = Array.isArray(lessonIds) ? lessonIds : [];

    if (selectedLessonsArray.length > 0) {
      // If user selected individual lessons, store their IDs in lessons array and sum their prices
      const { Lesson } = await import('@/models/Lesson');
      const foundLessons = await Lesson.find({ _id: { $in: selectedLessonsArray } });
      foundLessons.forEach((l) => {
        calculatedAmount += l.price || 0;
      });
    } else {
      // Complete course purchase (lessons array remains empty)
      calculatedAmount = targetCourse.offerPrice !== undefined && targetCourse.offerPrice !== null ? targetCourse.offerPrice : targetCourse.regularPrice;
    }

    const finalAmount = amount !== undefined && amount !== null && amount !== '' ? Number(amount) : calculatedAmount;

    // Determine order status based on paymentRequired toggle
    let orderStatus: 'initiated' | 'pending' | 'succeeded' = 'initiated';
    if (!paymentRequired) {
      orderStatus = 'succeeded'; // Payment Bypassed -> Order placed & fulfilled immediately
    } else if (selectedGateway === 'bank_transfer') {
      orderStatus = 'pending';
    }

    // Fetch settings for bank transfer details fallback if applicable
    const { Settings } = await import('@/models/Settings');
    const settingsDoc = await Settings.getSettings();
    const bankSettings = settingsDoc?.bankTransfer || {};

    const bankDetailsPayload = body.bankTransferDetails || {};

    const orderData: Record<string, any> = {
      student: targetStudentId,
      courseId: targetCourse._id,
      lessons: selectedLessonsArray,
      gateway: selectedGateway,
      gatewayTransactionId: gatewayTransactionId || (paymentRequired ? '' : `ADMIN-BYPASS-${Date.now()}`),
      gatewayResponse: gatewayResponse || (notes ? { adminNotes: notes } : {}),
      amount: finalAmount,
      currency: 'EUR',
      paymentRequired: Boolean(paymentRequired),
      status: orderStatus,
      bankTransferDetails: {
        accountHolder: bankDetailsPayload.accountHolder || bankSettings.accountHolder || 'Apka German School',
        iban: bankDetailsPayload.iban || bankSettings.iban || 'DE06300209005350983142',
        bicSwift: bankDetailsPayload.bicSwift || bankSettings.bicSwift || 'CMCIDEDDXXX',
        bankName: bankDetailsPayload.bankName || bankSettings.bankName || 'TARGOBANK',
        reference: bankDetailsPayload.reference || targetCourse.title || 'Course Payment',
        proofOfPaymentUrl: bankDetailsPayload.proofOfPaymentUrl || bankDetailsPayload.paymentScreenshot || bankDetailsPayload.paymentScreenShot || '',
        paymentScreenshot: bankDetailsPayload.paymentScreenshot || bankDetailsPayload.paymentScreenShot || bankDetailsPayload.proofOfPaymentUrl || '',
        paymentScreenShot: bankDetailsPayload.paymentScreenShot || bankDetailsPayload.paymentScreenshot || bankDetailsPayload.proofOfPaymentUrl || '',
        senderAccountName: bankDetailsPayload.senderAccountName || '',
        senderBank: bankDetailsPayload.senderBank || '',
        adminConfirmationStatus: !paymentRequired ? 'approved' : 'pending',
        adminNotes: notes || '',
      },
      initiatedAt: new Date(),
    };

    if (orderStatus === 'succeeded') {
      orderData.confirmedAt = new Date();
    }

    const order = await Order.create(orderData);

    return NextResponse.json(
      {
        success: true,
        message: !paymentRequired
          ? 'Order created successfully with payment bypass'
          : 'Order initiated successfully',
        order,
      },
      { status: 201 }
    );
  } catch (error: any) {
    return NextResponse.json(
      { success: false, error: error.message || 'Server error creating order' },
      { status: 500 }
    );
  }
}
