import { NextRequest, NextResponse } from 'next/server';
import { db } from '@/lib/db';
import { verifyAdminPermission } from '@/lib/auth';
import { sanitizeString, isValidId, isValidLength, isValidMcqAnswer, validatePagination } from '@/lib/validation';
import { checkRateLimit, getRateLimitIdentifier, rateLimitError, RATE_LIMITS } from '@/lib/rate-limit';

export async function GET(request: NextRequest) {
  try {
    // Auth check
    const authResult = await verifyAdminPermission(request, 'canManageMCQ');
    if ('error' in authResult) return authResult.error;

    const { searchParams } = new URL(request.url);

    // Pagination
    const { page, limit } = validatePagination(
      searchParams.get('page'),
      searchParams.get('limit')
    );

    // Filters
    const classId = searchParams.get('classId');
    const subjectId = searchParams.get('subjectId');
    const topicId = searchParams.get('topicId');
    const category = searchParams.get('category');
    const difficulty = searchParams.get('difficulty');
    const search = searchParams.get('search');

    const where: Record<string, unknown> = {};

    if (classId) {
      if (!isValidId(classId)) {
        return NextResponse.json(
          { success: false, error: 'Invalid classId format' },
          { status: 400 }
        );
      }
      where.classId = classId;
    }

    if (subjectId) {
      if (!isValidId(subjectId)) {
        return NextResponse.json(
          { success: false, error: 'Invalid subjectId format' },
          { status: 400 }
        );
      }
      where.subjectId = subjectId;
    }

    if (topicId) {
      if (!isValidId(topicId)) {
        return NextResponse.json(
          { success: false, error: 'Invalid topicId format' },
          { status: 400 }
        );
      }
      where.topicId = topicId;
    }

    if (category) {
      where.category = category;
    }

    if (difficulty) {
      where.difficulty = difficulty;
    }

    if (search) {
      where.question = { contains: search };
    }

    const [questions, total] = await Promise.all([
      db.mcqQuestion.findMany({
        where,
        orderBy: { createdAt: 'desc' },
        skip: (page - 1) * limit,
        take: limit,
        include: {
          mcqClass: { select: { id: true, name: true, nameBn: true } },
          subject: { select: { id: true, name: true, nameBn: true } },
          mcqTopic: { select: { id: true, name: true, nameBn: true } },
        },
      }),
      db.mcqQuestion.count({ where }),
    ]);

    return NextResponse.json({
      success: true,
      questions,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit),
      },
    });
  } catch (error) {
    console.error('Admin MCQ fetch error:', error);
    return NextResponse.json(
      { success: false, error: 'Failed to fetch questions' },
      { status: 500 }
    );
  }
}

export async function POST(request: NextRequest) {
  try {
    // Auth check
    const authResult = await verifyAdminPermission(request, 'canManageMCQ');
    if ('error' in authResult) return authResult.error;

    // Rate limit
    const identifier = `admin-mcq-post:${getRateLimitIdentifier(request)}`;
    const rateLimit = checkRateLimit(identifier, RATE_LIMITS.adminWrite);
    if (!rateLimit.allowed) return rateLimitError(rateLimit.resetTime);

    const body = await request.json();
    const {
      question, optionA, optionB, optionC, optionD, correctAnswer,
      category, difficulty, explanation,
      class: mcqClass, topic,
      classId, subjectId, topicId,
      questionImage, optionAImage, optionBImage, optionCImage, optionDImage,
      explanationImage, year, source,
    } = body;

    if (!question || !optionA || !optionB || !optionC || !optionD || !correctAnswer) {
      return NextResponse.json(
        { success: false, error: 'All question fields are required' },
        { status: 400 }
      );
    }

    // Validate answer
    if (!isValidMcqAnswer(correctAnswer)) {
      return NextResponse.json(
        { success: false, error: 'Correct answer must be A, B, C, or D' },
        { status: 400 }
      );
    }

    // Validate question length
    if (!isValidLength(question, 1, 1000)) {
      return NextResponse.json(
        { success: false, error: 'Question must be between 1 and 1000 characters' },
        { status: 400 }
      );
    }

    // Validate foreign keys if provided
    if (classId) {
      const cls = await db.mcqClass.findUnique({ where: { id: classId } });
      if (!cls) {
        return NextResponse.json(
          { success: false, error: 'Referenced class does not exist' },
          { status: 400 }
        );
      }
    }

    if (subjectId) {
      const sub = await db.mcqSubject.findUnique({ where: { id: subjectId } });
      if (!sub) {
        return NextResponse.json(
          { success: false, error: 'Referenced subject does not exist' },
          { status: 400 }
        );
      }
    }

    if (topicId) {
      const tpc = await db.mcqTopic.findUnique({ where: { id: topicId } });
      if (!tpc) {
        return NextResponse.json(
          { success: false, error: 'Referenced topic does not exist' },
          { status: 400 }
        );
      }
    }

    const validCategories = ['gk', 'ssc', 'hsc', 'class6-8', 'class9-10', 'admission', 'bcs', 'bangla', 'english', 'math', 'science'];
    const validDifficulties = ['easy', 'medium', 'hard'];
    const validClasses = ['SSC', 'HSC', 'Admission', 'GK', 'BCS', 'Class 6-8', 'Class 9-10'];

    const newQuestion = await db.mcqQuestion.create({
      data: {
        question: sanitizeString(question),
        questionImage: questionImage ? sanitizeString(questionImage) : null,
        optionA: sanitizeString(optionA),
        optionAImage: optionAImage ? sanitizeString(optionAImage) : null,
        optionB: sanitizeString(optionB),
        optionBImage: optionBImage ? sanitizeString(optionBImage) : null,
        optionC: sanitizeString(optionC),
        optionCImage: optionCImage ? sanitizeString(optionCImage) : null,
        optionD: sanitizeString(optionD),
        optionDImage: optionDImage ? sanitizeString(optionDImage) : null,
        correctAnswer,
        category: validCategories.includes(category) ? category : 'gk',
        class: mcqClass && validClasses.includes(mcqClass) ? mcqClass : 'GK',
        classId: classId || null,
        subjectId: subjectId || null,
        topicId: topicId || null,
        topic: topic ? sanitizeString(topic) : 'General',
        difficulty: validDifficulties.includes(difficulty) ? difficulty : 'medium',
        explanation: explanation ? sanitizeString(explanation) : null,
        explanationImage: explanationImage ? sanitizeString(explanationImage) : null,
        year: year ? sanitizeString(String(year)) : null,
        source: source ? sanitizeString(source) : null,
      },
      include: {
        mcqClass: { select: { id: true, name: true, nameBn: true } },
        subject: { select: { id: true, name: true, nameBn: true } },
        mcqTopic: { select: { id: true, name: true, nameBn: true } },
      },
    });

    return NextResponse.json({ success: true, question: newQuestion }, { status: 201 });
  } catch (error) {
    console.error('Admin MCQ create error:', error);
    return NextResponse.json(
      { success: false, error: 'Failed to create question' },
      { status: 500 }
    );
  }
}

export async function DELETE(request: NextRequest) {
  try {
    // Auth check
    const authResult = await verifyAdminPermission(request, 'canManageMCQ');
    if ('error' in authResult) return authResult.error;

    const { id } = await request.json();

    if (!id) {
      return NextResponse.json(
        { success: false, error: 'Question ID is required' },
        { status: 400 }
      );
    }

    if (!isValidId(id)) {
      return NextResponse.json(
        { success: false, error: 'Invalid question ID format' },
        { status: 400 }
      );
    }

    await db.mcqQuestion.delete({ where: { id } });

    return NextResponse.json({ success: true });
  } catch (error) {
    console.error('Admin MCQ delete error:', error);
    return NextResponse.json(
      { success: false, error: 'Failed to delete question' },
      { status: 500 }
    );
  }
}
