# -*- coding: utf-8 -*-

import os
import sys
import json
import argparse
from datetime import datetime

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

from db import get_conn

from services.fin_land_service import fetch_fin_land_article_html
from services.fin_land_parser import parse_fin_land_article_html
from services.realtor_matcher import calc_realtor_match_score


MATCH_THRESHOLD = 70


def fetch_pending_candidates(conn, limit=100, realtor_id=None):
    sql = """
        SELECT *
        FROM blog_realtor_article_candidates
        WHERE match_status = 'pending'
    """
    params = []

    if realtor_id:
        sql += " AND realtor_id = %s"
        params.append(realtor_id)

    sql += " ORDER BY id ASC LIMIT %s"
    params.append(limit)

    with conn.cursor() as cur:
        cur.execute(sql, params)
        return cur.fetchall()


def fetch_realtor(conn, realtor_id):
    with conn.cursor() as cur:
        cur.execute("""
            SELECT *
            FROM blog_realtors
            WHERE id = %s
            LIMIT 1
        """, (realtor_id,))
        return cur.fetchone()


def update_candidate(conn, candidate_id, detail_data, score_result):
    with conn.cursor() as cur:
        cur.execute("""
            UPDATE blog_realtor_article_candidates
            SET
                match_score = %s,
                match_status = %s,
                match_reasons = %s,
                detail_collected = 1,
                raw_json = %s,
                updated_at = NOW()
            WHERE id = %s
        """, (
            score_result["score"],
            score_result["status"],
            "\n".join(score_result["reasons"]),
            json.dumps(detail_data, ensure_ascii=False),
            candidate_id
        ))


def mark_candidate_failed(conn, candidate_id, error_message):
    with conn.cursor() as cur:
        cur.execute("""
            UPDATE blog_realtor_article_candidates
            SET
                match_status = 'failed',
                match_reasons = %s,
                detail_collected = 0,
                updated_at = NOW()
            WHERE id = %s
        """, (
            str(error_message)[:1000],
            candidate_id
        ))


def save_final_article(conn, realtor_id, article_no, detail_data, score_result):
    article_url = f"https://fin.land.naver.com/articles/{article_no}"

    with conn.cursor() as cur:
        cur.execute("""
            INSERT INTO blog_realtor_articles
            (
                realtor_id,
                search_run_id,
                article_no,
                article_name,
                trade_type,
                real_estate_type,
                price_text,
                building_name,
                floor_info,
                area_info,
                article_url,
                matched_office_name,
                matched_representative_name,
                matched_phone,
                match_score,
                collect_status,
                raw_json,
                created_at,
                updated_at
            )
            VALUES
            (
                %s, NULL, %s, %s, %s, %s,
                %s, %s, %s, %s, %s,
                %s, %s, %s, %s,
                'pending', %s, NOW(), NOW()
            )
            ON DUPLICATE KEY UPDATE
                article_name = VALUES(article_name),
                trade_type = VALUES(trade_type),
                real_estate_type = VALUES(real_estate_type),
                price_text = VALUES(price_text),
                building_name = VALUES(building_name),
                floor_info = VALUES(floor_info),
                area_info = VALUES(area_info),
                article_url = VALUES(article_url),
                matched_office_name = VALUES(matched_office_name),
                matched_representative_name = VALUES(matched_representative_name),
                matched_phone = VALUES(matched_phone),
                match_score = VALUES(match_score),
                collect_status = 'pending',
                raw_json = VALUES(raw_json),
                updated_at = NOW()
        """, (
            realtor_id,
            article_no,
            detail_data.get("article_name", ""),
            detail_data.get("trade_type_name") or detail_data.get("trade_type", ""),
            detail_data.get("real_estate_type_name") or detail_data.get("real_estate_type", ""),
            detail_data.get("price_text", ""),
            detail_data.get("complex_name") or detail_data.get("article_name", ""),
            detail_data.get("floor_info", ""),
            detail_data.get("area_info", ""),
            article_url,
            detail_data.get("realtor_office_name", ""),
            detail_data.get("realtor_name", ""),
            detail_data.get("realtor_phone", ""),
            score_result["score"],
            json.dumps(detail_data, ensure_ascii=False),
        ))


def process_candidate(conn, candidate):
    candidate_id = candidate["id"]
    realtor_id = candidate["realtor_id"]
    article_no = candidate["article_no"]

    print("-" * 80)
    print(f"[VERIFY] candidate_id={candidate_id}")
    print(f"[ARTICLE] {article_no}")

    realtor = fetch_realtor(conn, realtor_id)

    if not realtor:
        print("[SKIP] realtor not found")
        return

    try:
        html = fetch_fin_land_article_html(article_no)
        detail_data = parse_fin_land_article_html(html)

        score_result = calc_realtor_match_score(
            realtor,
            detail_data
        )

        collector = candidate.get("collector") or ""

        # 단체아이디 기반 수집은 해당 중개업소 페이지에서 나온 매물이므로 승인
        if collector == "office_realtor_id":
            if score_result["score"] < MATCH_THRESHOLD:
                score_result["score"] = MATCH_THRESHOLD

            score_result["status"] = "matched"
            score_result["reasons"].append(
                "단체아이디 기반 수집 매물 자동 승인"
            )

        update_candidate(
            conn,
            candidate_id,
            detail_data,
            score_result
        )

        conn.commit()

        print(
            f"[MATCH] "
            f"score={score_result['score']} "
            f"status={score_result['status']}"
        )

        if score_result["score"] >= MATCH_THRESHOLD:
            save_final_article(
                conn,
                realtor_id,
                article_no,
                detail_data,
                score_result
            )

            conn.commit()

            print(f"[FINAL SAVED] {article_no}")

    except Exception as e:
        conn.rollback()

        mark_candidate_failed(
            conn,
            candidate_id,
            str(e)
        )

        conn.commit()

        print(f"[ERROR] {article_no} / {str(e)}")


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--realtor-id", type=int, default=None)
    parser.add_argument("--limit", type=int, default=100)

    args = parser.parse_args()

    conn = get_conn()

    try:
        print("=" * 80)
        print("[START] verify_article_candidates")
        print("TIME:", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        print("=" * 80)

        candidates = fetch_pending_candidates(
            conn,
            limit=args.limit,
            realtor_id=args.realtor_id
        )

        print(f"[PENDING] {len(candidates)}")

        for candidate in candidates:
            process_candidate(conn, candidate)

        print("=" * 80)
        print("[DONE] verify_article_candidates")
        print("=" * 80)

    finally:
        conn.close()


if __name__ == "__main__":
    main()