"""
용어집 데이터 로딩 스크립트
"""
import sys
import json
import logging
from pathlib import Path
from typing import List

# 프로젝트 루트 디렉토리를 Python 경로에 추가
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from src.models.term import Term, DocumentSource
from src.db.postgres_vector import PostgresVectorDB
from src.utils.config import load_config, get_database_url
from src.utils.embedding import EmbeddingGenerator

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


def load_terms_from_json(file_path: Path) -> List[Term]:
    """
    JSON 파일에서 용어 데이터 로드

    Args:
        file_path: JSON 파일 경로

    Returns:
        용어 리스트
    """
    logger.info(f"JSON 파일 로딩: {file_path}")

    with open(file_path, 'r', encoding='utf-8') as f:
        data = json.load(f)

    terms = []

    # 도메인별 데이터 처리
    for domain_data in data.get("terms", []):
        domain = domain_data.get("domain")
        source_type = domain_data.get("source_type")

        for term_data in domain_data.get("data", []):
            # DocumentSource 파싱
            doc_source = None
            if "document_source" in term_data:
                doc_source = DocumentSource(**term_data["document_source"])

            # Term 객체 생성
            term = Term(
                term_id=term_data["term_id"],
                term_name=term_data["term_name"],
                normalized_name=term_data["normalized_name"],
                category=term_data["category"],
                definition=term_data["definition"],
                context=term_data.get("context", ""),
                synonyms=term_data.get("synonyms", []),
                related_terms=term_data.get("related_terms", []),
                document_source=doc_source,
                confidence_score=term_data.get("confidence_score", 0.0),
                usage_count=term_data.get("usage_count", 0),
                last_updated=term_data.get("last_updated"),
                embedding=None  # 나중에 생성
            )

            terms.append(term)

    logger.info(f"  → {len(terms)}개 용어 로드 완료")
    return terms


def generate_embeddings(
    terms: List[Term],
    embedding_gen: EmbeddingGenerator
) -> List[Term]:
    """
    용어 임베딩 생성

    Args:
        terms: 용어 리스트
        embedding_gen: 임베딩 생성기

    Returns:
        임베딩이 추가된 용어 리스트
    """
    logger.info(f"임베딩 생성 시작: {len(terms)}개 용어")

    # 임베딩 텍스트 준비 (용어명 + 정의 + 맥락)
    texts = []
    for term in terms:
        text = f"{term.term_name}\n{term.definition}"
        if term.context:
            text += f"\n{term.context}"
        texts.append(text)

    # 배치 임베딩 생성
    embeddings = embedding_gen.generate_embeddings_batch(texts, batch_size=50)

    # 임베딩 추가
    for term, embedding in zip(terms, embeddings):
        term.embedding = embedding

    logger.info(f"  → 임베딩 생성 완료")
    return terms


def main():
    """메인 함수"""
    logger.info("=" * 60)
    logger.info("용어집 데이터 로딩 시작")
    logger.info("=" * 60)

    # 1. 설정 로드
    config = load_config(str(project_root / "config.yaml"))
    logger.info("✓ 설정 로드 완료")

    # 2. PostgreSQL 연결
    db_url = get_database_url(config)
    db = PostgresVectorDB(db_url)
    logger.info("✓ PostgreSQL 연결 완료")

    # 3. 데이터베이스 초기화
    db.init_database()
    logger.info("✓ 데이터베이스 초기화 완료")

    # 4. 임베딩 생성기 초기화
    azure_openai = config["azure_openai"]
    embedding_gen = EmbeddingGenerator(
        api_key=azure_openai["api_key"],
        endpoint=azure_openai["endpoint"],
        model=azure_openai["embedding_model"],
        dimension=azure_openai["embedding_dimension"],
        api_version=azure_openai["api_version"]
    )
    logger.info("✓ 임베딩 생성기 초기화 완료")

    # 5. 용어 데이터 로딩
    all_terms = []
    data_dir = project_root.parent / config["data"]["terms_dir"]

    for filename in config["data"]["terms_files"]:
        file_path = data_dir / filename
        if file_path.exists():
            terms = load_terms_from_json(file_path)
            all_terms.extend(terms)
        else:
            logger.warning(f"⚠ 파일 없음: {file_path}")

    logger.info(f"✓ 총 {len(all_terms)}개 용어 로드 완료")

    # 6. 임베딩 생성
    all_terms = generate_embeddings(all_terms, embedding_gen)

    # 7. 데이터베이스에 삽입
    logger.info(f"데이터베이스 삽입 시작: {len(all_terms)}개 용어")
    success_count = 0
    fail_count = 0

    for i, term in enumerate(all_terms, 1):
        if db.insert_term(term):
            success_count += 1
        else:
            fail_count += 1

        if i % 100 == 0:
            logger.info(f"  진행: {i}/{len(all_terms)} (성공: {success_count}, 실패: {fail_count})")

    logger.info(f"✓ 삽입 완료: 성공 {success_count}, 실패 {fail_count}")

    # 8. 통계 조회
    stats = db.get_stats()
    logger.info("=" * 60)
    logger.info("용어집 통계")
    logger.info("=" * 60)
    logger.info(f"전체 용어: {stats['total_terms']}개")
    logger.info(f"평균 신뢰도: {stats['avg_confidence']:.2f}")
    logger.info("\n카테고리별 통계:")
    for category, count in sorted(stats['by_category'].items(), key=lambda x: x[1], reverse=True):
        logger.info(f"  - {category}: {count}개")

    logger.info("=" * 60)
    logger.info("용어집 데이터 로딩 완료")
    logger.info("=" * 60)


if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        logger.error(f"오류 발생: {str(e)}", exc_info=True)
        sys.exit(1)
