# -*- coding: utf-8 -*-
"""
DS 전투 데이터 수집 메인 스크립트

실행 방법:
    python collect_combat_data.py
"""

import json
import logging
import os
from datetime import datetime
from typing import Dict, List

from data_extractors import (
    TARGET_STALKERS,
    extract_character_stat,
    extract_attack_montages,
    extract_skill_data,
    extract_montage_info
)
from markdown_formatter import generate_stalker_markdown
from validators import validate_collection_result, log_collection_summary


# 로깅 설정
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)


# 경로 설정
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SOURCE_DATA_DIR = os.path.join(os.path.dirname(BASE_DIR), '원본데이터')
OUTPUT_DIR = os.path.join(BASE_DIR, '수집결과')
MARKDOWN_DIR = os.path.join(OUTPUT_DIR, 'markdown')

DATATABLE_JSON = os.path.join(SOURCE_DATA_DIR, 'DataTable.json')
ANIMMONTAGE_JSON = os.path.join(SOURCE_DATA_DIR, 'AnimMontage.json')

OUTPUT_JSON = os.path.join(OUTPUT_DIR, 'all_stalkers_combat_data.json')
LOG_FILE = os.path.join(OUTPUT_DIR, 'collection_log.txt')


def load_json_file(file_path: str) -> dict:
    """JSON 파일 로드"""
    logger.info(f"JSON 파일 로드 중: {file_path}")
    with open(file_path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    logger.info(f"  - 로드 완료")
    return data


def collect_stalker_data(
    stalker_name: str,
    datatable_assets: List[Dict],
    animmontage_assets: List[Dict]
) -> Dict:
    """
    단일 스토커의 전투 데이터 수집

    Args:
        stalker_name: 스토커 이름 (소문자)
        datatable_assets: DataTable.json의 Assets 배열
        animmontage_assets: AnimMontage.json의 Assets 배열

    Returns:
        스토커 전투 데이터
    """
    logger.info(f"  [{stalker_name}] 데이터 수집 시작")

    # 1. 기본 스탯 추출
    stats = extract_character_stat(datatable_assets, stalker_name)
    if not stats:
        logger.error(f"  [{stalker_name}] 스탯 정보 추출 실패")
        return {}

    # 2. 기본 정보 분리
    basic_info = {
        'name': stats.pop('name', ''),
        'jobName': stats.pop('jobName', '')
    }

    # 3. 스킬 정보 분리
    skills = {
        'default': stats.pop('defaultSkills', []),
        'sub': stats.pop('subSkill', ''),
        'ultimate': stats.pop('ultimateSkill', ''),
        'ultimatePoint': stats.pop('ultimatePoint', 0)
    }

    # 4. 스킬 상세 정보 및 몽타주 수집
    skill_details = {}
    all_skill_ids = skills['default'] + [skills['sub'], skills['ultimate']]

    for skill_id in all_skill_ids:
        if not skill_id:
            continue

        skill_data = extract_skill_data(datatable_assets, skill_id)
        if not skill_data:
            logger.warning(f"  [{stalker_name}] 스킬 {skill_id} 데이터 추출 실패")
            continue

        # 스킬 몽타주 정보 수집
        montage_paths = skill_data.get('useMontages', [])
        montages = []
        for montage_path in montage_paths:
            montage_info = extract_montage_info(animmontage_assets, montage_path)
            if montage_info:
                montages.append(montage_info)

        skill_data['montages'] = montages
        skill_details[skill_id] = skill_data

    # 5. 기본 공격 몽타주 수집
    attack_montages_map = extract_attack_montages(datatable_assets, stalker_name)
    basic_attacks = {}

    for weapon_type, montage_paths in attack_montages_map.items():
        montages = []
        for montage_path in montage_paths:
            montage_info = extract_montage_info(animmontage_assets, montage_path)
            if montage_info:
                montages.append(montage_info)

        if montages:
            basic_attacks[weapon_type] = montages

    # 6. 최종 데이터 구성
    stalker_data = {
        'basic_info': basic_info,
        'stats': stats,
        'skills': skills,
        'skill_details': skill_details,
        'basic_attacks': basic_attacks
    }

    logger.info(f"  [{stalker_name}] 데이터 수집 완료")
    logger.info(f"    - 스킬 {len(skill_details)}개")
    logger.info(f"    - 무기 타입 {len(basic_attacks)}개")

    return stalker_data


def main():
    """메인 실행 함수"""
    logger.info("=" * 80)
    logger.info("DS 전투 데이터 수집 시작")
    logger.info("=" * 80)

    # 1. 원본 데이터 로드
    logger.info("1. 원본 데이터 로드 중...")
    datatable_data = load_json_file(DATATABLE_JSON)
    animmontage_data = load_json_file(ANIMMONTAGE_JSON)

    datatable_assets = datatable_data.get('Assets', [])
    animmontage_assets = animmontage_data.get('Assets', [])

    logger.info(f"  - DataTable 에셋 수: {len(datatable_assets)}")
    logger.info(f"  - AnimMontage 에셋 수: {len(animmontage_assets)}")
    logger.info("")

    # 2. 스토커별 데이터 수집
    logger.info(f"2. 스토커 데이터 수집 중 (총 {len(TARGET_STALKERS)}명)...")
    stalkers_data = {}

    for stalker_name in TARGET_STALKERS:
        stalker_data = collect_stalker_data(
            stalker_name,
            datatable_assets,
            animmontage_assets
        )
        if stalker_data:
            stalkers_data[stalker_name] = stalker_data

    logger.info("")

    # 3. 통합 JSON 생성
    logger.info("3. 통합 JSON 생성 중...")
    collection_data = {
        'collection_metadata': {
            'collected_at': datetime.now().isoformat(),
            'source_files': [
                'DataTable.json',
                'AnimMontage.json'
            ],
            'total_stalkers': len(stalkers_data)
        },
        'stalkers': stalkers_data
    }

    with open(OUTPUT_JSON, 'w', encoding='utf-8') as f:
        json.dump(collection_data, f, ensure_ascii=False, indent=2)

    logger.info(f"  - 통합 JSON 생성 완료: {OUTPUT_JSON}")
    logger.info("")

    # 4. 스토커별 마크다운 생성
    logger.info(f"4. 스토커별 마크다운 생성 중 ({len(stalkers_data)}명)...")
    for stalker_name, stalker_data in stalkers_data.items():
        markdown_content = generate_stalker_markdown(stalker_name, stalker_data)
        markdown_path = os.path.join(MARKDOWN_DIR, f'{stalker_name}.md')

        with open(markdown_path, 'w', encoding='utf-8') as f:
            f.write(markdown_content)

        logger.info(f"  - {stalker_name}.md 생성 완료")

    logger.info("")

    # 5. 데이터 검증
    logger.info("5. 데이터 검증 중...")
    is_valid = validate_collection_result(collection_data)

    if is_valid:
        logger.info("  ✓ 모든 데이터 검증 통과")
    else:
        logger.warning("  ⚠ 일부 데이터 검증 실패 (상세 내용은 로그 참조)")

    logger.info("")

    # 6. 수집 요약 로그 생성
    logger.info("6. 수집 요약 로그 생성 중...")
    log_collection_summary(collection_data, LOG_FILE)
    logger.info("")

    # 7. 완료
    logger.info("=" * 80)
    logger.info("DS 전투 데이터 수집 완료!")
    logger.info("=" * 80)
    logger.info(f"결과 파일:")
    logger.info(f"  - 통합 JSON: {OUTPUT_JSON}")
    logger.info(f"  - 마크다운: {MARKDOWN_DIR}")
    logger.info(f"  - 수집 로그: {LOG_FILE}")
    logger.info("")


if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        logger.exception("수집 중 예외 발생:")
        raise
