'use client';

import { useState, useEffect, useRef, useCallback } from 'react';
import { collection, query, where, and, or, getDocs, doc, updateDoc, arrayUnion, serverTimestamp, addDoc, QueryDocumentSnapshot, DocumentData } from 'firebase/firestore';
import { db, auth } from '@/lib/firebase';
import { COLLECTIONS, AiSuggestion } from '@/types/firestore';
import { toast } from 'sonner';

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

interface SearchResultDoc {
    id: string;
    title: string;
    isNew?: boolean;        // "Create new" 항목 여부
    originalTerm?: string;  // 원래 검색어 (신규 생성 시 사용)
}

interface ManualTermInputProps {
    documentId: string;
}

function ManualTermInput({ documentId }: ManualTermInputProps) {
    const [searchValue, setSearchValue] = useState('');
    const [results, setResults] = useState<SearchResultDoc[]>([]);
    const [selectedDoc, setSelectedDoc] = useState<SearchResultDoc | null>(null);
    const [isSearching, setIsSearching] = useState(false);
    const [showDropdown, setShowDropdown] = useState(false);
    const [isConnecting, setIsConnecting] = useState(false);
    const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

    const handleSearch = useCallback(async (keyword: string) => {
        const currentUser = auth.currentUser;
        if (!keyword.trim() || !currentUser) {
            setResults([]);
            setShowDropdown(false);
            return;
        }

        try {
            setIsSearching(true);
            const docsRef = collection(db, COLLECTIONS.DOCUMENTS);
            const q = query(
                docsRef,
                and(
                    or(
                        where('visibility', '==', 'public'),
                        where('authorId', '==', currentUser.uid)
                    ),
                    where('searchKeywords', 'array-contains', keyword)
                )
            );
            const snapshot = await getDocs(q);
            const docs: SearchResultDoc[] = snapshot.docs.map((d: QueryDocumentSnapshot<DocumentData>) => ({
                id: d.id,
                title: (d.data() as { title: string }).title,
            }));

            // 정확한 제목 매칭 확인
            const normalizedKeyword = keyword.trim().toLowerCase();
            const exactMatchFound = docs.some(d => d.title.toLowerCase() === normalizedKeyword);

            // 정확한 매칭이 없으면 "신규 용어 생성" 옵션 추가
            if (!exactMatchFound && keyword.trim().length > 0) {
                docs.push({
                    id: `new-${keyword.trim()}`,
                    title: `"${keyword.trim()}" — 신규 용어로 생성`,
                    isNew: true,
                    originalTerm: keyword.trim(),
                });
            }

            setResults(docs);
            setShowDropdown(true);
        } catch (error) {
            console.error('[ManualTermInput] 검색 실패:', error);
            // 쿼리 실패해도 신규 용어 생성은 가능
            const keyword_trimmed = keyword.trim();
            if (keyword_trimmed.length > 0) {
                setResults([{
                    id: `new-${keyword_trimmed}`,
                    title: `"${keyword_trimmed}" — 신규 용어로 생성`,
                    isNew: true,
                    originalTerm: keyword_trimmed,
                }]);
                setShowDropdown(true);
            } else {
                setResults([]);
            }
        } finally {
            setIsSearching(false);
        }
    }, []);

    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const value = e.target.value;
        setSearchValue(value);
        setSelectedDoc(null);

        if (debounceRef.current) clearTimeout(debounceRef.current);
        debounceRef.current = setTimeout(() => {
            handleSearch(value);
        }, 300);
    };

    const handleCreateAndConnect = async (term: string) => {
        if (isConnecting) return;

        const currentUser = auth.currentUser;
        if (!currentUser) {
            toast.error('로그인이 필요합니다');
            return;
        }

        try {
            setIsConnecting(true);

            // Firestore에 빈 문서 생성
            const newDocData = {
                title: term,
                content: '',
                version: 1,
                tags: [],
                visibility: 'public',
                status: 'draft',
                authorId: currentUser.uid,
                authorName: currentUser.displayName || currentUser.email?.split('@')[0] || 'Unknown',
                createdAt: serverTimestamp(),
                updatedAt: serverTimestamp(),
                searchKeywords: [],
                docType: 'wiki',
                category: 'general',
                properties: {},
            };

            const newDocRef = await addDoc(collection(db, COLLECTIONS.DOCUMENTS), newDocData);

            // 현재 문서에 outgoingLinks/outgoingLinkIds 추가
            const sourceDocRef = doc(db, COLLECTIONS.DOCUMENTS, documentId);
            await updateDoc(sourceDocRef, {
                outgoingLinks: arrayUnion(term),
                outgoingLinkIds: arrayUnion(newDocRef.id),
                updatedAt: serverTimestamp(),
            });

            toast.success(`신규 용어 '${term}' 생성 및 연결 완료`);
            setSearchValue('');
            setSelectedDoc(null);
            setResults([]);
            setShowDropdown(false);
        } catch (error) {
            console.error('[ManualTermInput] 신규 용어 생성 실패:', error);
            toast.error('신규 용어 생성 중 오류가 발생했습니다');
        } finally {
            setIsConnecting(false);
        }
    };

    const handleSelectDoc = (resultDoc: SearchResultDoc) => {
        if (resultDoc.isNew && resultDoc.originalTerm) {
            handleCreateAndConnect(resultDoc.originalTerm);
            return;
        }
        setSelectedDoc(resultDoc);
        setSearchValue(resultDoc.title);
        setShowDropdown(false);
        setResults([]);
    };

    const handleConnect = async () => {
        if (!selectedDoc || isConnecting) return;

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

            toast.success('문서가 연결되었습니다');
            setSearchValue('');
            setSelectedDoc(null);
            setResults([]);
            setShowDropdown(false);
        } catch (error) {
            console.error('[ManualTermInput] 연결 실패:', error);
            toast.error('연결 중 오류가 발생했습니다');
        } finally {
            setIsConnecting(false);
        }
    };

    return (
        <div className="border-t border-amber-100 p-3">
            <div className="relative flex gap-2">
                <div className="relative flex-1">
                    <input
                        type="text"
                        value={searchValue}
                        onChange={handleInputChange}
                        placeholder="문서 검색..."
                        className="w-full text-sm px-3 py-1.5 rounded-lg border border-amber-200 focus:border-amber-400 focus:outline-none bg-white placeholder-amber-300"
                    />
                    {isSearching && (
                        <div className="absolute right-2 top-1/2 -translate-y-1/2">
                            <div className="w-3 h-3 border-2 border-amber-400 border-t-transparent rounded-full animate-spin" />
                        </div>
                    )}
                    {showDropdown && results.length > 0 && (
                        <div
                            className="absolute bottom-full left-0 right-0 mb-1 bg-white rounded-lg shadow-lg border border-amber-100 z-50 overflow-y-auto"
                            style={{ maxHeight: `${Math.min(results.length * 40, 400)}px` }}
                        >
                            {results.map(resultDoc => (
                                <button
                                    key={resultDoc.id}
                                    type="button"
                                    onClick={() => handleSelectDoc(resultDoc)}
                                    className={`w-full text-left px-3 py-2 text-sm transition-colors first:rounded-t-lg last:rounded-b-lg ${
                                        resultDoc.isNew
                                            ? 'text-amber-700 hover:bg-amber-100 border-t border-amber-100 font-medium'
                                            : 'text-gray-700 hover:bg-amber-50 hover:text-amber-800'
                                    }`}
                                >
                                    {resultDoc.isNew ? (
                                        <span className="flex items-center gap-1.5">
                                            <svg className="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 4v16m8-8H4" />
                                            </svg>
                                            {resultDoc.title}
                                        </span>
                                    ) : (
                                        resultDoc.title
                                    )}
                                </button>
                            ))}
                        </div>
                    )}
                </div>
                <button
                    type="button"
                    onClick={handleConnect}
                    disabled={!selectedDoc || isConnecting}
                    aria-label="연결"
                    className={`px-3 py-1.5 rounded-lg text-sm font-bold transition-all shrink-0
                        ${!selectedDoc || isConnecting
                            ? 'bg-amber-200 text-amber-400 cursor-not-allowed'
                            : 'bg-amber-500 hover:bg-amber-600 text-white active:scale-95'
                        }`}
                >
                    {isConnecting ? (
                        <div className="w-3 h-3 border-2 border-white border-t-transparent rounded-full animate-spin" />
                    ) : (
                        '연결'
                    )}
                </button>
            </div>
        </div>
    );
}

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';
}

interface TermItemProps {
    term: AiSuggestion;
    isProcessing: boolean;
    onApprove: () => void;
    onDismiss: () => void;
}

function TermItem({ term, isProcessing, onApprove, onDismiss }: TermItemProps) {
    const confidenceColor = getConfidenceColor(term.confidence);
    const confidenceTextColor = getConfidenceTextColor(term.confidence);

    return (
        <div className="flex items-center gap-3 p-3 rounded-xl border border-amber-100 bg-amber-50/40 hover:border-amber-300 hover:shadow-sm transition-all">
            <div className="flex-1 min-w-0">
                <div className="flex items-center gap-2 mb-1.5">
                    <span className="font-bold text-gray-900 text-sm truncate">
                        {term.targetTitle}
                    </span>
                    <span className="shrink-0 flex items-center gap-1 text-[10px] px-2 py-0.5 bg-amber-100 text-amber-700 rounded-full font-bold border border-amber-200">
                        <svg className="w-3 h-3 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>
                        용어 매칭
                    </span>
                </div>

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

                {term.explanation && (
                    <p className="mt-1 text-xs text-amber-700/80 line-clamp-1">
                        {term.explanation}
                    </p>
                )}
            </div>

            <div className="flex items-center gap-1 shrink-0">
                <button
                    onClick={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        if (!isProcessing) onApprove();
                    }}
                    disabled={isProcessing}
                    title="용어 연결 승인"
                    className={`w-7 h-7 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 h-3 border-2 border-amber-400 border-t-transparent rounded-full animate-spin" />
                    ) : (
                        <svg className="w-3.5 h-3.5" 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-7 h-7 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-3.5 h-3.5" 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>
    );
}

export default function FloatingTermDetection({ documentId }: FloatingTermDetectionProps) {
    const [terms, setTerms] = useState<AiSuggestion[]>([]);
    const [isExpanded, setIsExpanded] = useState(false);
    const [loading, setLoading] = useState(true);
    const [processingId, setProcessingId] = useState<string | null>(null);

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

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

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

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

                const items: AiSuggestion[] = snapshot.docs
                    .map((d: QueryDocumentSnapshot<DocumentData>) => ({ ...d.data(), id: d.id } as AiSuggestion))
                    .filter((s: AiSuggestion) => !s.dismissed && s.method === 'static')
                    .sort((a: AiSuggestion, b: AiSuggestion) => b.confidence - a.confidence);

                setTerms(items);
            } catch (error) {
                console.error('[FloatingTermDetection] 용어 목록 로드 실패:', error);
            } finally {
                setLoading(false);
            }
        };

        fetchTerms();
    }, [documentId]);

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

        setTerms(prev => prev.filter(s => s.id !== term.id));
        setProcessingId(term.id);

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

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

            toast.success('관련 문서가 연결되었습니다');
        } catch (error) {
            console.error('[FloatingTermDetection] 승인 처리 실패:', error);
            setTerms(prev => [...prev, term].sort((a, b) => b.confidence - a.confidence));
            toast.error('연결 중 오류가 발생했습니다');
        } finally {
            setProcessingId(null);
        }
    };

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

        setTerms(prev => prev.filter(s => s.id !== term.id));
        setProcessingId(term.id);

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

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

    if (loading) return null;

    return (
        <div className="fixed bottom-4 right-4 z-50">
            {isExpanded ? (
                <div className="w-80 max-h-96 bg-white rounded-2xl shadow-2xl border border-amber-200 overflow-hidden flex flex-col">
                    <div className="flex items-center justify-between px-4 py-3 bg-amber-50 border-b border-amber-100">
                        <h3 className="text-sm font-bold text-amber-800 flex items-center gap-2">
                            <svg className="w-4 h-4 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>
                            보험 용어 연결
                            {terms.length > 0 && (
                                <span className="text-xs bg-amber-200 text-amber-800 px-1.5 py-0.5 rounded-full">
                                    {terms.length}
                                </span>
                            )}
                        </h3>
                        <button
                            onClick={() => setIsExpanded(false)}
                            title="접기"
                            className="w-7 h-7 flex items-center justify-center rounded-full text-amber-600 hover:bg-amber-100 transition-colors"
                        >
                            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M19 9l-7 7-7-7" />
                            </svg>
                        </button>
                    </div>
                    {terms.length > 0 && (
                        <div className="flex-1 overflow-y-auto p-3 space-y-2">
                            {terms.map(term => (
                                <TermItem
                                    key={term.id}
                                    term={term}
                                    isProcessing={processingId === term.id}
                                    onApprove={() => handleApprove(term)}
                                    onDismiss={() => handleDismiss(term)}
                                />
                            ))}
                        </div>
                    )}
                    <ManualTermInput documentId={documentId} />
                </div>
            ) : (
                <button
                    onClick={() => setIsExpanded(true)}
                    className="bg-amber-500 hover:bg-amber-600 text-white px-4 py-2.5 rounded-full shadow-lg flex items-center gap-2 transition-colors active:scale-95"
                >
                    <svg className="w-4 h-4 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>
                    <span className="text-sm font-bold">
                        {terms.length > 0 ? `보험 용어 ${terms.length}건` : '용어 연결'}
                    </span>
                </button>
            )}
        </div>
    );
}
