# -*- coding: utf-8 -*-

import os
import sys
import argparse
import subprocess
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


def fetch_pending_jobs(conn, limit=5, realtor_id=None):
    sql = """
        SELECT
            q.id,
            q.realtor_id,
            q.article_no,
            q.work_type,
            q.work_status,
            q.priority
        FROM blog_article_work_queue q
        WHERE q.work_status = 'pending'
          AND q.work_type = 'new_article'
    """

    params = []

    if realtor_id:
        sql += " AND q.realtor_id = %s "
        params.append(realtor_id)

    sql += """
        ORDER BY q.priority ASC, q.id ASC
        LIMIT %s
    """
    params.append(limit)

    with conn.cursor() as cur:
        cur.execute(sql, params)
        return cur.fetchall()


def update_job_status(conn, job_id, status, error_message=""):
    if error_message and len(error_message) > 5000:
        error_message = error_message[-5000:]

    with conn.cursor() as cur:
        cur.execute("""
            UPDATE blog_article_work_queue
            SET
                work_status = %s,
                error_message = %s,
                updated_at = NOW()
            WHERE id = %s
        """, (
            status,
            error_message or "",
            job_id,
        ))

    conn.commit()


def run_process_one_article(realtor_id, article_no, force=False):
    cmd = [
        sys.executable,
        os.path.join("jobs", "process_one_article_pipeline.py"),
        "--realtor-id",
        str(realtor_id),
        "--article-no",
        str(article_no),
    ]

    if force:
        cmd.append("--force")

    print("[COMMAND]", " ".join(cmd))

    result = subprocess.run(
        cmd,
        cwd=BASE_DIR,
        text=True,
        capture_output=True,
        encoding="utf-8",
        errors="replace",
    )

    if result.stdout:
        print(result.stdout)

    if result.stderr:
        print("[STDERR]")
        print(result.stderr)

    if result.returncode != 0:
        raise Exception(
            "process_one_article_pipeline failed\n"
            f"article_no={article_no}\n"
            f"returncode={result.returncode}\n"
            f"stdout={result.stdout}\n"
            f"stderr={result.stderr}"
        )

    return result.stdout


def process_job(conn, job, force=False):
    job_id = int(job["id"])
    realtor_id = int(job["realtor_id"])
    article_no = str(job["article_no"])

    print("-" * 80)
    print(f"[QUEUE START] job_id={job_id}, realtor_id={realtor_id}, article_no={article_no}")

    update_job_status(conn, job_id, "processing")

    try:
        output = run_process_one_article(
            realtor_id=realtor_id,
            article_no=article_no,
            force=force,
        )

        update_job_status(conn, job_id, "done", "")

        print(f"[QUEUE DONE] job_id={job_id}, article_no={article_no}")

    except Exception as e:
        error_text = str(e)

        update_job_status(
            conn,
            job_id,
            "failed",
            error_text,
        )

        print(f"[QUEUE FAILED] job_id={job_id}, article_no={article_no}")
        print("[ERROR]", error_text)


def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("--limit", type=int, default=9999)
    parser.add_argument("--realtor-id", type=int, default=None)
    parser.add_argument("--force", action="store_true")

    args = parser.parse_args()

    conn = get_conn()

    try:
        print("=" * 80)
        print("[START] process_article_queue")
        print("TIME:", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        print("=" * 80)

        jobs = fetch_pending_jobs(
            conn=conn,
            limit=args.limit,
            realtor_id=args.realtor_id,
        )

        print(f"[PENDING JOBS] {len(jobs)}")

        for job in jobs:
            process_job(
                conn=conn,
                job=job,
                force=args.force,
            )

        print("=" * 80)
        print("[DONE] process_article_queue")
        print("=" * 80)

    finally:
        conn.close()


if __name__ == "__main__":
    main()