"""
네이버 플레이스 모니터링 크롤러 실행기
- DB의 활성 업체를 읽어 순차 크롤링
- 기본정보·리뷰·순위·키워드 수집 후 DB 저장
- Cron 또는 PHP exec()로 실행
  crontab: 0 */4 * * * /usr/bin/python3 /var/www/html/bicorn/place/run_crawl.py
"""
import sys
import time
import argparse
from datetime import datetime

sys.path.insert(0, '/var/www/html/bicorn/place')
from db       import get_active_places, save_stats, save_reviews, save_rank, save_keywords, update_place_info
from crawler  import get_place_summary, get_place_reviews, get_place_rank, analyze_review_keywords


def log(msg):
    ts = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print(f"[{ts}] {msg}", flush=True)


def crawl_place(place):
    place_id = place['place_id']
    client   = place['client_name'] or place_id
    keywords = [k.strip() for k in (place['keywords'] or '').split(',') if k.strip()]

    log(f"▶ [{client}] 수집 시작 (place_id: {place_id})")

    # ── 1. 기본정보 + 통계 ───────────────────────────
    hint = place.get('name', '') or place.get('client_name', '')
    summary = get_place_summary(place_id, hint_name=hint)
    if summary:
        save_stats(summary)
        update_place_info(place_id, summary)
        log(f"  ✓ 기본정보: {summary.get('name')} | ⭐{summary.get('rating')} | 방문자리뷰 {summary.get('visitor_review_count')}개 | 블로그 {summary.get('blog_review_count')}개")
    else:
        log(f"  ✗ 기본정보 수집 실패")
    time.sleep(1)

    # ── 2. 리뷰 수집 + 키워드 분석 ──────────────────
    try:
        reviews = get_place_reviews(place_id, page=1, size=50)
        if reviews:
            new_cnt = save_reviews(place_id, reviews)
            kws = analyze_review_keywords(reviews)
            save_keywords(place_id, kws)
            log(f"  ✓ 리뷰: {len(reviews)}개 수집 / 신규 {new_cnt}개 / 키워드 {len(kws)}개")
        else:
            log(f"  - 리뷰 없음")
    except Exception as e:
        log(f"  ✗ 리뷰 수집 오류: {e}")
    time.sleep(1)

    # ── 3. 키워드별 순위 ─────────────────────────────
    if not keywords:
        log(f"  - 모니터링 키워드 없음 (순위 수집 건너뜀)")
    for kw in keywords:
        try:
            rank_data = get_place_rank(kw, place_id)
            if rank_data:
                save_rank(rank_data)
                rank = rank_data.get('my_rank')
                total = rank_data.get('total_found', 0)
                log(f"  ✓ 순위 [{kw}]: {'{}위 / 전체 {}위'.format(rank, total) if rank else '순위권 밖 (상위 {}위 내 없음)'.format(total)}")
        except Exception as e:
            log(f"  ✗ 순위 수집 오류 [{kw}]: {e}")
        time.sleep(1.5)


def main():
    parser = argparse.ArgumentParser(description='네이버 플레이스 모니터링 크롤러')
    parser.add_argument('--place_id', help='특정 place_id만 수집 (생략 시 전체)')
    args = parser.parse_args()

    places = get_active_places()
    if args.place_id:
        places = [p for p in places if p['place_id'] == args.place_id]

    if not places:
        log("수집할 업체가 없습니다. (활성 업체 0개)")
        return

    log(f"=== 크롤링 시작: {len(places)}개 업체 ===")

    for i, place in enumerate(places, 1):
        log(f"── [{i}/{len(places)}] ──────────────────────")
        try:
            crawl_place(place)
        except Exception as e:
            log(f"  ✗ 예외 발생: {e}")
        if i < len(places):
            time.sleep(3)

    log(f"=== 크롤링 완료 ===\n")


if __name__ == '__main__':
    main()
