# -*- coding: utf-8 -*-
"""
STEP102-04
services/complex_address_display_helper.py

초안 생성(generate_blog_drafts.py)에서 소재지 표시용 주소를 결정하는 헬퍼.

우선순위:
1. blog_complex_address_cache.resolved_address
2. 기존 exposureAddress

운영 원칙:
- publish_worker.py 영향 없음
- 캐시 조회 실패 시 기존 주소 반환
- 임의 주소 생성 금지
"""

import json
import logging
from typing import Any, Dict, Optional, Tuple

from services.complex_address_cache_bridge import extract_region_and_complex

logger = logging.getLogger(__name__)


def parse_json_maybe(value: Any) -> Optional[Dict[str, Any]]:
    if isinstance(value, dict):
        return value

    if not value:
        return None

    if isinstance(value, str):
        try:
            return json.loads(value)
        except Exception:
            return None

    return None


def get_cached_resolved_address(conn, region_name: str, complex_name: str) -> Optional[Dict[str, Any]]:
    """
    blog_complex_address_cache에서 검증된 보강 주소 조회.
    """
    if not region_name or not complex_name:
        return None

    sql = """
        SELECT
            region_name,
            complex_name,
            complex_no,
            resolved_address,
            school_name,
            map_lng,
            map_lat,
            source,
            last_checked_at
        FROM blog_complex_address_cache
        WHERE region_name = %s
          AND complex_name = %s
          AND resolved_address IS NOT NULL
          AND resolved_address <> ''
        LIMIT 1
    """

    try:
        with conn.cursor() as cur:
            cur.execute(sql, (region_name, complex_name))
            row = cur.fetchone()

        return row if row else None

    except Exception as e:
        logger.warning(
            "[DRAFT_ADDRESS_CACHE_LOOKUP_FAIL] region=%s complex=%s err=%s",
            region_name,
            complex_name,
            e,
        )
        return None


def get_exposure_address_from_article_data(article_data: Any) -> Optional[str]:
    """
    raw_json에서 기존 exposureAddress만 안전하게 추출.
    """
    data = parse_json_maybe(article_data)
    if not data:
        return None

    detail = data.get("articleDetail") if isinstance(data.get("articleDetail"), dict) else data

    address = (
        detail.get("exposureAddress")
        or data.get("exposureAddress")
        or detail.get("address")
    )

    return str(address).strip() if address else None


def resolve_display_address_for_draft(
    conn,
    article_data: Any,
) -> Tuple[Optional[str], Dict[str, Any]]:
    """
    초안 생성에서 사용할 소재지 주소를 반환한다.

    return:
    (
        display_address,
        meta
    )

    meta 예:
    {
        "source": "complex_address_cache",
        "region_name": "...",
        "complex_name": "...",
        "resolved_address": "...",
        "fallback_address": "..."
    }
    """
    fallback_address = get_exposure_address_from_article_data(article_data)

    try:
        region_name, complex_name = extract_region_and_complex(article_data)

        if not region_name or not complex_name:
            return fallback_address, {
                "source": "fallback_exposureAddress",
                "reason": "missing_region_or_complex",
                "region_name": region_name,
                "complex_name": complex_name,
                "fallback_address": fallback_address,
            }

        cached = get_cached_resolved_address(conn, region_name, complex_name)

        if cached and cached.get("resolved_address"):
            return cached.get("resolved_address"), {
                "source": "complex_address_cache",
                "region_name": region_name,
                "complex_name": complex_name,
                "resolved_address": cached.get("resolved_address"),
                "fallback_address": fallback_address,
                "complex_no": cached.get("complex_no"),
                "school_name": cached.get("school_name"),
            }

        return fallback_address, {
            "source": "fallback_exposureAddress",
            "reason": "cache_not_found",
            "region_name": region_name,
            "complex_name": complex_name,
            "fallback_address": fallback_address,
        }

    except Exception as e:
        logger.warning("[DRAFT_ADDRESS_RESOLVE_SAFE_FAIL] err=%s", e)
        return fallback_address, {
            "source": "fallback_exposureAddress",
            "reason": "exception",
            "error": str(e),
            "fallback_address": fallback_address,
        }
