import { NextRequest, NextResponse } from 'next/server';
import { adminDb } from '@/lib/firebase-admin';
import { FieldValue, Transaction } from 'firebase-admin/firestore';
import { verifyMember } from '@/lib/auth-middleware';

const VALID_FEEDBACK_TYPES = ['correct', 'incorrect', 'incomplete'] as const;
type FeedbackType = typeof VALID_FEEDBACK_TYPES[number];

/**
 * HTML 태그를 제거하여 XSS를 방지한다.
 */
function stripHtmlTags(input: string): string {
    return input.replace(/<[^>]*>/g, '');
}

/**
 * Task F: /api/ai/feedback — 사용자 피드백 저장
 * Spec: § 13 query_logs.feedbackStatus 업데이트
 *
 * PATCH /api/ai/feedback
 * Body: { logId: string, status: 'correct' | 'incorrect' | 'incomplete' }
 */
export async function PATCH(req: NextRequest) {
    try {
        // Firebase ID Token 검증
        const authResult = await verifyMember(req);
        if (authResult instanceof NextResponse) return authResult;

        const { logId, status } = await req.json();
        if (!logId || !VALID_FEEDBACK_TYPES.includes(status)) {
            return NextResponse.json({ error: 'logId와 올바른 status(correct/incorrect/incomplete)가 필요합니다.' }, { status: 400 });
        }

        await adminDb.collection('query_logs').doc(logId).update({
            feedbackStatus: status,
            feedbackAt: FieldValue.serverTimestamp(),
        });

        return NextResponse.json({ success: true });
    } catch (error: any) {
        return NextResponse.json({ error: error.message }, { status: 500 });
    }
}

const VALID_RATINGS = ['positive', 'negative'] as const;
type FeedbackRating = typeof VALID_RATINGS[number];

const VALID_ERROR_TYPES = ['exemption_missing', 'product_confusion', 'old_version', 'other'] as const;
type FeedbackErrorType = typeof VALID_ERROR_TYPES[number];

export async function POST(req: NextRequest) {
    try {
        const authResult = await verifyMember(req);
        if (authResult instanceof NextResponse) return authResult;
        const { uid: userId } = authResult;

        const body = await req.json();
        const { queryId, rating, errorType, freeText, query, answer } = body as {
            queryId?: string;
            rating?: FeedbackRating;
            errorType?: FeedbackErrorType;
            freeText?: string;
            query?: string;
            answer?: string;
        };

        if (!queryId) {
            return NextResponse.json({ error: 'queryId가 필요합니다.' }, { status: 400 });
        }
        if (!rating || !VALID_RATINGS.includes(rating)) {
            return NextResponse.json({ error: 'rating은 positive 또는 negative여야 합니다.' }, { status: 400 });
        }
        if (rating === 'negative' && (!errorType || !VALID_ERROR_TYPES.includes(errorType))) {
            return NextResponse.json(
                { error: 'rating이 negative일 때 errorType은 필수입니다. (exemption_missing | product_confusion | old_version | other)' },
                { status: 400 },
            );
        }
        if (!query) {
            return NextResponse.json({ error: 'query가 필요합니다.' }, { status: 400 });
        }
        if (!answer) {
            return NextResponse.json({ error: 'answer가 필요합니다.' }, { status: 400 });
        }
        if (freeText !== undefined && freeText.length > 500) {
            return NextResponse.json({ error: 'freeText는 최대 500자까지 입력 가능합니다.' }, { status: 400 });
        }

        const sanitizedFreeText = freeText ? stripHtmlTags(freeText) : undefined;

        const duplicateSnap = await adminDb
            .collection('ai_feedback')
            .where('queryId', '==', queryId)
            .where('userId', '==', userId)
            .limit(1)
            .get();
        if (!duplicateSnap.empty) {
            return NextResponse.json({ error: '이미 해당 질문에 대한 피드백을 제출하셨습니다.' }, { status: 409 });
        }

        const feedbackRef = adminDb.collection('ai_feedback').doc();
        const feedbackData: Record<string, any> = {
            queryId,
            rating,
            query,
            answer,
            userId,
            createdAt: FieldValue.serverTimestamp(),
        };
        if (errorType) feedbackData.errorType = errorType;
        if (sanitizedFreeText !== undefined) feedbackData.freeText = sanitizedFreeText;

        await feedbackRef.set(feedbackData);

        return NextResponse.json({ success: true, feedbackId: feedbackRef.id }, { status: 201 });
    } catch (error: any) {
        return NextResponse.json({ error: error.message }, { status: 500 });
    }
}
