/**
 * Component: Admin Custom Search Terms API
 * Documentation: documentation/admin-dashboard.md
 */

import { NextRequest, NextResponse } from 'next/server';
import { requireAuth, requireAdmin, AuthenticatedRequest } from '@/lib/middleware/auth';
import { prisma } from '@/lib/db';
import { RMABLogger } from '@/lib/utils/logger';

const logger = RMABLogger.create('API.Admin.SearchTerms');

/**
 * PATCH /api/admin/requests/[id]/search-terms
 * Update custom search terms for a request (admin only)
 * Body: { searchTerms: string | null, triggerSearch?: boolean }
 */
export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  return requireAuth(request, async (req: AuthenticatedRequest) => {
    return requireAdmin(req, async () => {
      try {
        if (!req.user) {
          return NextResponse.json(
            { error: 'Unauthorized', message: 'User not authenticated' },
            { status: 401 }
          );
        }

        const { id } = await params;

        // Parse body
        let body;
        try {
          body = await req.json();
        } catch {
          return NextResponse.json(
            { error: 'BadRequest', message: 'Invalid JSON body' },
            { status: 400 }
          );
        }

        const { searchTerms, triggerSearch } = body;

        // Validate searchTerms is string or null
        if (searchTerms !== null && searchTerms !== undefined && typeof searchTerms !== 'string') {
          return NextResponse.json(
            { error: 'BadRequest', message: 'searchTerms must be a string or null' },
            { status: 400 }
          );
        }

        // Trim and normalize
        const normalizedTerms = typeof searchTerms === 'string' ? searchTerms.trim() || null : null;

        // Find the request
        const existingRequest = await prisma.request.findUnique({
          where: { id },
          include: {
            audiobook: {
              select: { id: true, title: true, author: true, audibleAsin: true },
            },
          },
        });

        if (!existingRequest || existingRequest.deletedAt) {
          return NextResponse.json(
            { error: 'NotFound', message: 'Request not found' },
            { status: 404 }
          );
        }

        // Update custom search terms
        await prisma.request.update({
          where: { id },
          data: {
            customSearchTerms: normalizedTerms,
            updatedAt: new Date(),
          },
        });

        logger.info(`Custom search terms ${normalizedTerms ? 'set' : 'cleared'} for request ${id}`, {
          requestId: id,
          customSearchTerms: normalizedTerms,
          adminId: req.user.id,
        });

        // Optionally trigger a new search
        let searchTriggered = false;
        if (triggerSearch && ['pending', 'failed', 'awaiting_search'].includes(existingRequest.status)) {
          // Reset status to pending and clear error
          await prisma.request.update({
            where: { id },
            data: {
              status: 'pending',
              errorMessage: null,
              updatedAt: new Date(),
            },
          });

          // Queue search job based on request type
          const { getJobQueueService } = await import('@/lib/services/job-queue.service');
          const jobQueue = getJobQueueService();
          const audiobookData = {
            id: existingRequest.audiobook.id,
            title: existingRequest.audiobook.title,
            author: existingRequest.audiobook.author,
            asin: existingRequest.audiobook.audibleAsin || undefined,
          };

          if (existingRequest.type === 'ebook') {
            await jobQueue.addSearchEbookJob(id, audiobookData);
          } else {
            await jobQueue.addSearchJob(id, audiobookData);
          }

          searchTriggered = true;
          logger.info(`Search triggered for request ${id} with custom terms`, { requestId: id });
        }

        return NextResponse.json({
          success: true,
          customSearchTerms: normalizedTerms,
          searchTriggered,
        });
      } catch (error) {
        logger.error('Failed to update search terms', {
          error: error instanceof Error ? error.message : String(error),
        });
        return NextResponse.json(
          { error: 'ServerError', message: 'Failed to update search terms' },
          { status: 500 }
        );
      }
    });
  });
}
