#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""운영센터 홈페이지 생성·기사 갱신: 최신 20건 상세수집 후 기사화."""

from __future__ import annotations

import subprocess
import sys
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parents[1]
if str(BASE_DIR) not in sys.path:
    sys.path.insert(0, str(BASE_DIR))

from db import get_conn

GENERATOR = Path(__file__).with_name("generate_multi_articles.py")
DETAIL_SYNC = Path(__file__).with_name("multi_webzine_detail_sync.py")
SHORTS_ENQUEUE = Path(__file__).with_name("enqueue_auto_shorts.py")
LOCK_NAME = "multi_homepage_build_worker"
INITIAL_LIMIT = 20


def claim(conn):
    conn.begin()
    try:
        with conn.cursor() as cur:
            cur.execute("""
                SELECT bj.*
                  FROM multi_site_build_jobs bj
                  INNER JOIN multi_sites s ON s.id=bj.site_id AND s.status='active'
                 WHERE bj.build_type='initial_articles' AND bj.status='pending'
                 ORDER BY bj.id LIMIT 1 FOR UPDATE
            """)
            row = cur.fetchone()
            if not row:
                conn.rollback()
                return None
            cur.execute("UPDATE multi_site_build_jobs SET status='running',total_count=%s,started_at=NOW(),updated_at=NOW() WHERE id=%s", (INITIAL_LIMIT, row["id"]))
        conn.commit()
        return row
    except Exception:
        conn.rollback()
        raise


def mark_failed(conn, job_id):
    conn.rollback()
    with conn.cursor() as cur:
        cur.execute("""UPDATE multi_site_build_jobs
                          SET status='failed',finished_at=NOW(),updated_at=NOW()
                        WHERE id=%s AND status IN ('pending','running')""", (job_id,))
    conn.commit()


def current_job_status(conn, job_id):
    conn.rollback()
    with conn.cursor() as cur:
        cur.execute("SELECT status FROM multi_site_build_jobs WHERE id=%s", (job_id,))
        row = cur.fetchone() or {}
    return str(row.get("status") or "")


def set_phase(conn, job_id, phase):
    """상세수집 동안 0건으로 보여도 멈춘 작업으로 오해하지 않도록 단계를 기록한다."""
    conn.rollback()
    with conn.cursor() as cur:
        cur.execute(
            "UPDATE multi_site_build_jobs SET current_article_no=%s,updated_at=NOW() WHERE id=%s",
            (str(phase), int(job_id)),
        )
    conn.commit()


def main():
    for program in (GENERATOR, DETAIL_SYNC):
        if not program.is_file():
            print(f"[MULTI HOMEPAGE BUILD ERROR] program_missing={program}", flush=True)
            raise SystemExit(1)

    conn = get_conn()
    locked = False
    job = None
    try:
        with conn.cursor() as cur:
            cur.execute("SELECT GET_LOCK(%s,0) acquired", (LOCK_NAME,))
            locked = int((cur.fetchone() or {}).get("acquired") or 0) == 1
        if not locked:
            print("[MULTI HOMEPAGE BUILD SKIP] another_worker_running", flush=True)
            return
        job = claim(conn)
        if not job:
            print("[MULTI HOMEPAGE BUILD DONE] no_pending_job", flush=True)
            return

        detail_command = [
            sys.executable, "-B", str(DETAIL_SYNC),
            "--realtor-id", str(job["realtor_id"]),
            "--limit-per-realtor", str(INITIAL_LIMIT),
            "--max-total", str(INITIAL_LIMIT),
            "--ignore-window", "--ignore-server-publish-busy",
            "--skip-webzine-generate",
        ]
        set_phase(conn, int(job["id"]), "DETAIL_SYNC")
        print(f"[MULTI HOMEPAGE DETAIL START] job_id={job['id']} realtor_id={job['realtor_id']} limit={INITIAL_LIMIT}", flush=True)
        detail_result = subprocess.run(detail_command, cwd=str(BASE_DIR), check=False)
        if detail_result.returncode:
            set_phase(conn, int(job["id"]), f"DETAIL_ERROR_{detail_result.returncode}")
            mark_failed(conn, int(job["id"]))
            raise SystemExit(detail_result.returncode)

        command = [
            sys.executable, "-B", str(GENERATOR),
            "--realtor-id", str(job["realtor_id"]),
            "--initialize-site", "--initial-max", str(INITIAL_LIMIT),
            "--build-job-id", str(job["id"]), "--skip-policy-feeds",
        ]
        set_phase(conn, int(job["id"]), "ARTICLE_GENERATE")
        result = subprocess.run(command, cwd=str(BASE_DIR), check=False)
        if result.returncode:
            if current_job_status(conn, int(job["id"])) != "partial":
                mark_failed(conn, int(job["id"]))
            raise SystemExit(result.returncode)

        with conn.cursor() as cur:
            cur.execute("UPDATE multi_sites SET updated_at=NOW() WHERE id=%s", (job["site_id"],))
        conn.commit()
        if SHORTS_ENQUEUE.is_file():
            subprocess.run([sys.executable, "-B", str(SHORTS_ENQUEUE), "--realtor-id", str(job["realtor_id"])], cwd=str(BASE_DIR), check=False)
        print(f"[MULTI HOMEPAGE BUILD DONE] job_id={job['id']}", flush=True)
    except SystemExit:
        raise
    except Exception as exc:
        if job:
            mark_failed(conn, int(job["id"]))
        print(f"[MULTI HOMEPAGE BUILD ERROR] {type(exc).__name__}: {exc}", flush=True)
        raise SystemExit(1)
    finally:
        if locked:
            try:
                with conn.cursor() as cur:
                    cur.execute("SELECT RELEASE_LOCK(%s)", (LOCK_NAME,))
            except Exception:
                pass
        conn.close()


if __name__ == "__main__":
    main()
