"""
Lyric Background Tasks

가사 생성 관련 백그라운드 태스크를 정의합니다.
"""

import logging
import traceback

from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError

from app.database.session import BackgroundSessionLocal
from app.lyric.models import Lyric
from app.utils.chatgpt_prompt import ChatgptService

# 로거 설정
logger = logging.getLogger(__name__)


async def _update_lyric_status(
    task_id: str,
    status: str,
    result: str | None = None,
) -> bool:
    """Lyric 테이블의 상태를 업데이트합니다.

    Args:
        task_id: 프로젝트 task_id
        status: 변경할 상태 ("processing", "completed", "failed")
        result: 가사 결과 또는 에러 메시지

    Returns:
        bool: 업데이트 성공 여부
    """
    try:
        async with BackgroundSessionLocal() as session:
            query_result = await session.execute(
                select(Lyric)
                .where(Lyric.task_id == task_id)
                .order_by(Lyric.created_at.desc())
                .limit(1)
            )
            lyric = query_result.scalar_one_or_none()

            if lyric:
                lyric.status = status
                if result is not None:
                    lyric.lyric_result = result
                await session.commit()
                logger.info(f"[Lyric] Status updated - task_id: {task_id}, status: {status}")
                print(f"[Lyric] Status updated - task_id: {task_id}, status: {status}")
                return True
            else:
                logger.warning(f"[Lyric] NOT FOUND in DB - task_id: {task_id}")
                print(f"[Lyric] NOT FOUND in DB - task_id: {task_id}")
                return False

    except SQLAlchemyError as e:
        logger.error(f"[Lyric] DB Error while updating status - task_id: {task_id}, error: {e}")
        print(f"[Lyric] DB Error while updating status - task_id: {task_id}, error: {e}")
        return False
    except Exception as e:
        logger.error(f"[Lyric] Unexpected error while updating status - task_id: {task_id}, error: {e}")
        print(f"[Lyric] Unexpected error while updating status - task_id: {task_id}, error: {e}")
        return False


async def generate_lyric_background(
    task_id: str,
    prompt: str,
    language: str,
) -> None:
    """백그라운드에서 ChatGPT를 통해 가사를 생성하고 Lyric 테이블을 업데이트합니다.

    Args:
        task_id: 프로젝트 task_id
        prompt: ChatGPT에 전달할 프롬프트
        language: 가사 언어
    """
    import time

    task_start = time.perf_counter()
    logger.info(f"[generate_lyric_background] START - task_id: {task_id}")
    print(f"[generate_lyric_background] ========== START ==========")
    print(f"[generate_lyric_background] task_id: {task_id}")
    print(f"[generate_lyric_background] language: {language}")
    print(f"[generate_lyric_background] prompt length: {len(prompt)}자")

    try:
        # ========== Step 1: ChatGPT 서비스 초기화 ==========
        step1_start = time.perf_counter()
        print(f"[generate_lyric_background] Step 1: ChatGPT 서비스 초기화...")

        service = ChatgptService(
            customer_name="",  # 프롬프트가 이미 생성되었으므로 빈 값
            region="",
            detail_region_info="",
            language=language,
        )

        step1_elapsed = (time.perf_counter() - step1_start) * 1000
        print(f"[generate_lyric_background] Step 1 완료 ({step1_elapsed:.1f}ms)")

        # ========== Step 2: ChatGPT API 호출 (가사 생성) ==========
        step2_start = time.perf_counter()
        logger.info(f"[generate_lyric_background] Step 2: ChatGPT API 호출 시작 - task_id: {task_id}")
        print(f"[generate_lyric_background] Step 2: ChatGPT API 호출 시작...")

        result = await service.generate(prompt=prompt)

        step2_elapsed = (time.perf_counter() - step2_start) * 1000
        logger.info(f"[generate_lyric_background] Step 2 완료 - 응답 {len(result)}자 ({step2_elapsed:.1f}ms)")
        print(f"[generate_lyric_background] Step 2 완료 - 응답 {len(result)}자 ({step2_elapsed:.1f}ms)")

        # ========== Step 3: DB 상태 업데이트 ==========
        step3_start = time.perf_counter()
        print(f"[generate_lyric_background] Step 3: DB 상태 업데이트...")

        await _update_lyric_status(task_id, "completed", result)

        step3_elapsed = (time.perf_counter() - step3_start) * 1000
        print(f"[generate_lyric_background] Step 3 완료 ({step3_elapsed:.1f}ms)")

        # ========== 완료 ==========
        total_elapsed = (time.perf_counter() - task_start) * 1000
        logger.info(f"[generate_lyric_background] SUCCESS - task_id: {task_id}, 총 소요시간: {total_elapsed:.1f}ms")
        print(f"[generate_lyric_background] ========== SUCCESS ==========")
        print(f"[generate_lyric_background] 총 소요시간: {total_elapsed:.1f}ms")
        print(f"[generate_lyric_background]   - Step 1 (서비스 초기화): {step1_elapsed:.1f}ms")
        print(f"[generate_lyric_background]   - Step 2 (GPT API 호출): {step2_elapsed:.1f}ms")
        print(f"[generate_lyric_background]   - Step 3 (DB 업데이트): {step3_elapsed:.1f}ms")

    except SQLAlchemyError as e:
        elapsed = (time.perf_counter() - task_start) * 1000
        logger.error(f"[generate_lyric_background] DB ERROR - task_id: {task_id}, error: {e} ({elapsed:.1f}ms)")
        print(f"[generate_lyric_background] DB ERROR - {e} ({elapsed:.1f}ms)")
        traceback.print_exc()
        await _update_lyric_status(task_id, "failed", f"Database Error: {str(e)}")

    except Exception as e:
        elapsed = (time.perf_counter() - task_start) * 1000
        logger.error(f"[generate_lyric_background] EXCEPTION - task_id: {task_id}, error: {e} ({elapsed:.1f}ms)")
        print(f"[generate_lyric_background] EXCEPTION - {e} ({elapsed:.1f}ms)")
        traceback.print_exc()
        await _update_lyric_status(task_id, "failed", f"Error: {str(e)}")
