'use client';

/**
 * RelatedDocsSidebar — AI 추천 관련 문서 사이드바
 *
 * documents/{documentId}/ai_suggestions 서브컬렉션을 읽어
 * method !== 'static' && dismissed=false 항목을 Firestore 존재 확인 후 최대 5개 표시.
 * 용어 매칭(method=static)은 FloatingTermDetection 컴포넌트에서 별도 처리.
 */

import { useState, useEffect } from 'react';
import Link from 'next/link';
import { collection, query, getDocs, getDoc, doc, updateDoc, arrayUnion, serverTimestamp, QueryDocumentSnapshot, DocumentData } from 'firebase/firestore';
import { db } from '@/lib/firebase';
import { COLLECTIONS, AiSuggestion, LinkMethod } from '@/types/firestore';
import { toast } from 'sonner';

// ── method 뱃지 매핑 ──────────────────────────────────────────────────────

const METHOD_LABEL: Record<LinkMethod, string> = {
    static: '용어 매칭',
    embedding: '유사 문서',
    semantic: 'AI 분석',
    manual: '수동',
};

// ── method 아이콘 컴포넌트 ─────────────────────────────────────────────────

function MethodIcon({ method }: { method: LinkMethod }) {
    if (method === 'static') {
        // 책/사전 아이콘
        return (
            <svg
                data-icon="static"
                className="w-3.5 h-3.5 shrink-0"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
                aria-hidden="true"
            >
                <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth="2"
                    d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
                />
            </svg>
        );
    }

    if (method === 'embedding') {
        // 네트워크/연결 아이콘
        return (
            <svg
                data-icon="embedding"
                className="w-3.5 h-3.5 shrink-0"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
                aria-hidden="true"
            >
                <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth="2"
                    d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
                />
            </svg>
        );
    }

    if (method === 'semantic') {
        // 별/AI 아이콘
        return (
            <svg
                data-icon="semantic"
                className="w-3.5 h-3.5 shrink-0"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
                aria-hidden="true"
            >
                <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth="2"
                    d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"
                />
            </svg>
        );
    }

    // manual: 사람 아이콘
    return (
        <svg
            data-icon="manual"
            className="w-3.5 h-3.5 shrink-0"
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
            aria-hidden="true"
        >
            <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth="2"
                d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
            />
        </svg>
    );
}

// ── method tooltip 설명 ───────────────────────────────────────────────────

const METHOD_TOOLTIP: Record<LinkMethod, string> = {
    static: '용어 매칭: 문서 내 키워드/용어 기반으로 연결된 문서',
    embedding: '유사 문서: 벡터 임베딩 유사도 기반으로 연결된 문서',
    semantic: 'AI 분석: AI가 의미론적으로 분석하여 추천한 문서',
    manual: '수동: 사용자가 직접 연결한 문서',
};

// ── confidence 색상 ───────────────────────────────────────────────────────

function getConfidenceColor(confidence: number): string {
    if (confidence >= 90) return 'bg-green-500';
    if (confidence >= 70) return 'bg-blue-500';
    return 'bg-gray-400';
}

function getConfidenceTextColor(confidence: number): string {
    if (confidence >= 90) return 'text-green-600';
    if (confidence >= 70) return 'text-blue-600';
    return 'text-gray-500';
}

// ── Props ─────────────────────────────────────────────────────────────────

interface RelatedDocsSidebarProps {
    documentId: string;
    documentTitle: string;
}

// ── 컴포넌트 ──────────────────────────────────────────────────────────────

export default function RelatedDocsSidebar({ documentId }: RelatedDocsSidebarProps) {
    // docSuggestions: method !== 'static', Firestore 존재 확인된 항목
    const [docSuggestions, setDocSuggestions] = useState<AiSuggestion[]>([]);
    const [loading, setLoading] = useState(true);
    const [processingId, setProcessingId] = useState<string | null>(null);
    const [config, setConfig] = useState<{ maxSuggestions: number }>({ maxSuggestions: 5 });
    const [configLoaded, setConfigLoaded] = useState(false);

    // ── config 로드 ─────────────────────────────────────────────────────

    useEffect(() => {
        const loadConfig = async () => {
            try {
                const configDoc = await getDoc(doc(db, 'config', 'aiLinking'));
                if (configDoc.exists()) {
                    const data = configDoc.data();
                    setConfig({
                        maxSuggestions: data.maxSuggestions ?? 5,
                    });
                }
            } catch (e) {
                console.warn('[RelatedDocsSidebar] config 로드 실패, 기본값 사용');
            } finally {
                setConfigLoaded(true);
            }
        };
        loadConfig();
    }, []);

    // ── 추천 목록 로드 ──────────────────────────────────────────────────

    useEffect(() => {
        if (!documentId || !configLoaded) {
            if (!documentId) setLoading(false);
            return;
        }

        const fetchSuggestions = async () => {
            try {
                setLoading(true);

                const suggestionsRef = collection(
                    db,
                    COLLECTIONS.DOCUMENTS,
                    documentId,
                    COLLECTIONS.AI_SUGGESTIONS
                );

                const q = query(suggestionsRef);
                const snapshot = await getDocs(q);

                const allItems: AiSuggestion[] = snapshot.docs
                    .map((d: QueryDocumentSnapshot<DocumentData>) => ({ ...d.data(), id: d.id } as AiSuggestion))
                    // dismissed=false 항목만
                    .filter((s: AiSuggestion) => !s.dismissed)
                    // confidence 내림차순 정렬
                    .sort((a: AiSuggestion, b: AiSuggestion) => b.confidence - a.confidence);

                // 관련 문서 항목 (method !== 'static') — Firestore 존재 확인 후 최대 5개
                const nonStaticItems = allItems.filter(s => s.method !== 'static');
                const existenceChecks = await Promise.all(
                    nonStaticItems.map(async s => {
                        try {
                            const docSnap = await getDoc(doc(db, COLLECTIONS.DOCUMENTS, s.targetDocId));
                            return docSnap.exists() ? s : null;
                        } catch {
                            return null;
                        }
                    })
                );
                const docs = existenceChecks
                    .filter((s): s is AiSuggestion => s !== null)
                    .slice(0, config.maxSuggestions);

                setDocSuggestions(docs);
            } catch (error) {
                console.error('[RelatedDocsSidebar] 추천 목록 로드 실패:', error);
            } finally {
                setLoading(false);
            }
        };

        fetchSuggestions();
    }, [documentId, configLoaded, config.maxSuggestions]);

    // ── 승인 핸들러 ─────────────────────────────────────────────────────

    const handleApprove = async (suggestion: AiSuggestion) => {
        if (processingId) return;

        // optimistic update: 즉시 UI에서 제거
        setDocSuggestions(prev => prev.filter(s => s.id !== suggestion.id));
        setProcessingId(suggestion.id);

        try {
            // 1. [[ 백링크와 동일한 메커니즘으로 문서 필드에 저장
            const sourceDocRef = doc(db, COLLECTIONS.DOCUMENTS, documentId);
            await updateDoc(sourceDocRef, {
                outgoingLinks: arrayUnion(suggestion.targetTitle),
                outgoingLinkIds: arrayUnion(suggestion.targetDocId),
                updatedAt: serverTimestamp(),
            });

            // 2. ai_suggestions 해당 문서에서 dismissed: true 마킹
            const suggestionDocRef = doc(
                db,
                COLLECTIONS.DOCUMENTS,
                documentId,
                COLLECTIONS.AI_SUGGESTIONS,
                suggestion.id
            );
            await updateDoc(suggestionDocRef, { dismissed: true });

            toast.success('관련 문서가 연결되었습니다');
        } catch (error) {
            console.error('[RelatedDocsSidebar] 승인 처리 실패:', error);
            // 롤백: UI에 다시 추가
            setDocSuggestions(prev =>
                [...prev, suggestion].sort((a, b) => b.confidence - a.confidence)
            );
            toast.error('연결 중 오류가 발생했습니다');
        } finally {
            setProcessingId(null);
        }
    };

    // ── 거부 핸들러 ─────────────────────────────────────────────────────

    const handleDismiss = async (suggestion: AiSuggestion) => {
        if (processingId) return;

        // optimistic update: 즉시 UI에서 제거
        setDocSuggestions(prev => prev.filter(s => s.id !== suggestion.id));
        setProcessingId(suggestion.id);

        try {
            const suggestionDocRef = doc(
                db,
                COLLECTIONS.DOCUMENTS,
                documentId,
                COLLECTIONS.AI_SUGGESTIONS,
                suggestion.id
            );
            await updateDoc(suggestionDocRef, { dismissed: true });

            toast.success('추천이 거부되었습니다');
        } catch (error) {
            console.error('[RelatedDocsSidebar] 거부 처리 실패:', error);
            // 롤백
            setDocSuggestions(prev =>
                [...prev, suggestion].sort((a, b) => b.confidence - a.confidence)
            );
            toast.error('거부 처리 중 오류가 발생했습니다');
        } finally {
            setProcessingId(null);
        }
    };

    // ── 렌더링 ──────────────────────────────────────────────────────────

    if (loading) {
        return (
            <div className="mt-8 flex items-center gap-2 text-sm text-gray-400">
                <div className="animate-spin rounded-full h-4 w-4 border-t-2 border-b-2 border-indigo-400"></div>
                <span>AI 추천 로드 중...</span>
            </div>
        );
    }

    if (docSuggestions.length === 0) {
        return null;
    }

    return (
        <div className="mt-10 border-t border-gray-100 pt-8">
            <h2 className="text-xl font-bold text-gray-900 mb-5 flex items-center gap-2">
                <span className="w-1.5 h-6 bg-violet-500 rounded-full"></span>
                AI 추천 관련 문서
                <span className="text-xs font-normal text-gray-400 ml-1 px-2 py-0.5 bg-violet-50 rounded-full border border-violet-100">
                    {docSuggestions.length}
                </span>
            </h2>
            <div className="space-y-3">
                {docSuggestions.map(suggestion => (
                    <SuggestionCard
                        key={suggestion.id}
                        suggestion={suggestion}
                        isProcessing={processingId === suggestion.id}
                        onApprove={() => handleApprove(suggestion)}
                        onDismiss={() => handleDismiss(suggestion)}
                    />
                ))}
            </div>
        </div>
    );
}

// ── SuggestionCard 서브컴포넌트 (AI 추천 관련 문서용) ────────────────────

interface SuggestionCardProps {
    suggestion: AiSuggestion;
    isProcessing: boolean;
    onApprove: () => void;
    onDismiss: () => void;
}

function SuggestionCard({ suggestion, isProcessing, onApprove, onDismiss }: SuggestionCardProps) {
    const confidenceColor = getConfidenceColor(suggestion.confidence);
    const confidenceTextColor = getConfidenceTextColor(suggestion.confidence);
    const methodLabel = METHOD_LABEL[suggestion.method] ?? suggestion.method;
    const methodTooltip = METHOD_TOOLTIP[suggestion.method] ?? suggestion.method;

    return (
        <div className="flex items-center gap-3 p-4 rounded-xl border border-gray-100 bg-white hover:border-violet-200 hover:shadow-sm transition-all group">
            {/* 문서 링크 영역 */}
            <Link
                href={`/docs/${suggestion.targetDocId}`}
                className="flex-1 min-w-0 no-underline"
            >
                {/* 제목 + method 뱃지 */}
                <div className="flex items-center gap-2 mb-2">
                    <span className="font-semibold text-gray-900 text-sm truncate group-hover:text-violet-700 transition-colors">
                        {suggestion.targetTitle}
                    </span>
                    <span
                        className="shrink-0 flex items-center gap-1 text-[10px] px-2 py-0.5 bg-violet-50 text-violet-600 rounded-full font-bold border border-violet-100"
                        title={methodTooltip}
                    >
                        <MethodIcon method={suggestion.method} />
                        {methodLabel}
                    </span>
                </div>

                {/* confidence 바 */}
                <div className="flex items-center gap-2">
                    <div className="flex-1 h-1.5 bg-gray-100 rounded-full overflow-hidden">
                        <div
                            className={`h-full rounded-full transition-all ${confidenceColor}`}
                            style={{ width: `${Math.min(suggestion.confidence, 100)}%` }}
                        />
                    </div>
                    <span
                        className={`text-[10px] font-bold tabular-nums shrink-0 ${confidenceTextColor}`}
                        title={methodTooltip}
                    >
                        {suggestion.confidence}%
                    </span>
                </div>

                {/* explanation (있을 경우) */}
                {suggestion.explanation && (
                    <p className="mt-1.5 text-xs text-gray-500 line-clamp-1">
                        {suggestion.explanation}
                    </p>
                )}
            </Link>

            {/* 액션 버튼 영역 */}
            <div className="flex items-center gap-1 shrink-0">
                {/* 승인 버튼 */}
                <button
                    onClick={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        if (!isProcessing) onApprove();
                    }}
                    disabled={isProcessing}
                    title="관련 문서로 연결"
                    className={`w-8 h-8 flex items-center justify-center rounded-full border transition-all
                        ${isProcessing
                            ? 'opacity-40 cursor-not-allowed bg-gray-50 border-gray-200'
                            : 'bg-white border-gray-200 text-gray-400 hover:bg-green-50 hover:border-green-300 hover:text-green-600 active:scale-95'
                        }`}
                >
                    {isProcessing ? (
                        <div className="w-3.5 h-3.5 border-2 border-indigo-400 border-t-transparent rounded-full animate-spin" />
                    ) : (
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M5 13l4 4L19 7" />
                        </svg>
                    )}
                </button>

                {/* 거부 버튼 */}
                <button
                    onClick={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        if (!isProcessing) onDismiss();
                    }}
                    disabled={isProcessing}
                    title="추천 거부"
                    className={`w-8 h-8 flex items-center justify-center rounded-full border transition-all
                        ${isProcessing
                            ? 'opacity-40 cursor-not-allowed bg-gray-50 border-gray-200'
                            : 'bg-white border-gray-200 text-gray-400 hover:bg-red-50 hover:border-red-300 hover:text-red-500 active:scale-95'
                        }`}
                >
                    <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M6 18L18 6M6 6l12 12" />
                    </svg>
                </button>
            </div>
        </div>
    );
}

