import { NextRequest, NextResponse } from 'next/server';
import { verifyMember } from '@/lib/auth-middleware';
import { getFirebaseAdmin } from '@/lib/firebase-admin';
import { getFirestore, FieldValue } from 'firebase-admin/firestore';

const VALID_REPORT_REASONS = [
  'incorrect_info',
  'outdated_info',
  'misleading_content',
  'missing_source',
] as const;

// POST /api/wiki/entries/{id}/report
export async function POST(
  req: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  // 1. 인증 + member 역할 확인
  const authResult = await verifyMember(req);
  if (authResult instanceof NextResponse) return authResult;

  const { id: docId } = await params;

  // 2. 요청 바디 파싱
  let body: { reasonType: string; memo?: string };
  try {
    body = await req.json();
  } catch {
    return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
  }

  const { reasonType, memo } = body;

  // 3. 유효성 검증: reasonType
  if (!reasonType || !(VALID_REPORT_REASONS as readonly string[]).includes(reasonType)) {
    return NextResponse.json(
      {
        error: `Invalid reasonType. Must be one of: ${VALID_REPORT_REASONS.join(', ')}`,
      },
      { status: 400 }
    );
  }

  // 4. 유효성 검증: memo (선택적, 최대 200자)
  if (memo !== undefined && memo.length > 200) {
    return NextResponse.json(
      { error: 'memo must be 200 characters or fewer' },
      { status: 400 }
    );
  }

  // 5. Firestore 초기화
  getFirebaseAdmin();
  const db = getFirestore();

  // 6. Rate limit 체크: 문서 레벨 (동일 유저×문서 1회/24h)
  const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);

  const docReportSnap = await db
    .collection('documents')
    .doc(docId)
    .collection('reports')
    .where('reporterId', '==', authResult.uid)
    .where('createdAt', '>', twentyFourHoursAgo)
    .get();

  if (!docReportSnap.empty) {
    const latestReport = docReportSnap.docs.reduce((latest, doc) => {
      const docCreatedAt = doc.data().createdAt?.toDate?.() ?? new Date(0);
      const latestCreatedAt = latest.data().createdAt?.toDate?.() ?? new Date(0);
      return docCreatedAt > latestCreatedAt ? doc : latest;
    });
    const latestCreatedAt: Date =
      latestReport.data().createdAt?.toDate?.() ?? new Date(0);
    const retryAfterMs =
      latestCreatedAt.getTime() + 24 * 60 * 60 * 1000 - Date.now();

    return NextResponse.json(
      {
        error: 'You have already reported this document within the last 24 hours',
        retryAfterMs: Math.max(0, retryAfterMs),
      },
      { status: 429 }
    );
  }

  // 7. Rate limit 체크: 글로벌 레벨 (전체 10건/일)
  const globalReportSnap = await db
    .collectionGroup('reports')
    .where('reporterId', '==', authResult.uid)
    .where('createdAt', '>', twentyFourHoursAgo)
    .limit(11)
    .get();

  if (globalReportSnap.size >= 10) {
    return NextResponse.json(
      {
        error: 'You have reached the maximum number of reports (10) within the last 24 hours',
        retryAfterMs: 24 * 60 * 60 * 1000,
      },
      { status: 429 }
    );
  }

  // 8. 문서 존재 확인
  const docRef = db.collection('documents').doc(docId);
  const docSnap = await docRef.get();
  if (!docSnap.exists) {
    return NextResponse.json({ error: 'Document not found' }, { status: 404 });
  }

  // 9. reporter 이름 조회
  const userDoc = await db.collection('users').doc(authResult.uid).get();
  const reporterName = userDoc.data()?.name ?? userDoc.data()?.displayName ?? 'Unknown';

  // 10. reports 서브컬렉션에 신고 저장
  const reportRef = docRef.collection('reports').doc();
  const reportData: Record<string, unknown> = {
    id: reportRef.id,
    docId,
    reporterId: authResult.uid,
    reporterName,
    reasonType,
    createdAt: FieldValue.serverTimestamp(),
  };

  if (memo !== undefined) {
    reportData.memo = memo;
  }

  await reportRef.set(reportData);

  return NextResponse.json({
    success: true,
    reportId: reportRef.id,
    docId,
  });
}
