# -*- coding: utf-8 -*-
"""
STEP103-14 DraftAdapter - V2 TargetSelector Based

역할:
- V2에서는 45건 Draft Buffer 정책을 사용하지 않는다.
- TargetSelector가 결정한 1건만 처리한다.
- 기존 Queue가 있으면 DraftStage는 아무 것도 하지 않는다.
- 기존 Draft는 있으나 Queue가 없으면 create_publish_queue()만 수행한다.
- 신규 Article이면 process_article()로 초안 생성 + Queue 생성까지 기존 엔진에 맡긴다.

중요:
- fetch_target_articles(... draft_buffer=45 ...) 호출 금지.
- 최신 10건만 보는 방식 금지.
- TargetSelector 기준으로 전체 매물 중 오늘 처리할 1건만 선택한다.
"""

from services.v2.base_adapter import BaseAdapter
from services.v2.target_selector import TargetSelector


class DraftAdapter(BaseAdapter):
    name = "draft_adapter"

    def run(self, context) -> dict:
        return self.generate(context)

    def generate(self, context) -> dict:
        try:
            from db import get_conn
            from jobs import generate_blog_drafts as draft_engine

            conn = get_conn()

            generated = []
            failed = []
            skipped = []
            queue_created = []

            try:
                selector = TargetSelector(conn)
                target = selector.select(context.realtor_id)

                target_data = {
                    "found": target.found,
                    "action": target.action,
                    "reason": target.reason,
                    "article_no": target.article_no,
                    "draft_id": target.draft_id,
                    "publish_queue_id": target.publish_queue_id,
                    "basis_date": str(target.basis_date) if target.basis_date else None,
                    "compare": target.compare,
                }

                context.put("target_selection", target_data)

                if not target.found:
                    skipped.append({
                        "reason": target.reason,
                        "action": target.action,
                    })
                    return self.ok(
                        message="draft skipped: no target",
                        data={
                            "realtor_id": context.realtor_id,
                            "target": target_data,
                            "generated_count": 0,
                            "failed_count": 0,
                            "skipped_count": 1,
                        },
                        drafts=[],
                        failed=[],
                        skipped=skipped,
                    )

                if target.action == "publish_existing_queue":
                    skipped.append({
                        "reason": "publish_queue_already_exists",
                        "article_no": target.article_no,
                        "draft_id": target.draft_id,
                        "publish_queue_id": target.publish_queue_id,
                    })
                    return self.ok(
                        message="draft skipped: existing publish queue selected",
                        data={
                            "realtor_id": context.realtor_id,
                            "target": target_data,
                            "generated_count": 0,
                            "failed_count": 0,
                            "skipped_count": 1,
                        },
                        drafts=[],
                        failed=[],
                        skipped=skipped,
                    )

                if target.action == "publish_existing_draft":
                    try:
                        publish_queue_id = draft_engine.create_publish_queue(
                            conn,
                            context.realtor_id,
                            target.article_no,
                            target.draft_id,
                        )

                        queue_created.append({
                            "article_no": target.article_no,
                            "draft_id": target.draft_id,
                            "publish_queue_id": publish_queue_id,
                            "status": "queue_created",
                        })

                        return self.ok(
                            message="draft skipped: existing draft queued for publish",
                            data={
                                "realtor_id": context.realtor_id,
                                "target": target_data,
                                "generated_count": 0,
                                "queue_created_count": len(queue_created),
                                "failed_count": 0,
                            },
                            drafts=[],
                            queue_created=queue_created,
                            failed=[],
                            skipped=[],
                        )

                    except Exception as e:
                        failed.append({
                            "article_no": target.article_no,
                            "draft_id": target.draft_id,
                            "error": str(e),
                            "status": "queue_create_failed",
                        })
                        return self.fail(
                            message=f"existing draft queue create failed: {e}",
                            data={
                                "realtor_id": context.realtor_id,
                                "target": target_data,
                                "failed": failed,
                            },
                            drafts=[],
                            failed=failed,
                            skipped=[],
                        )

                if target.action == "create_draft_then_publish":
                    article_no = str(target.article_no or "")

                    try:
                        rows = draft_engine.fetch_target_articles(
                            conn=conn,
                            realtor_id=context.realtor_id,
                            article_no=article_no,
                            limit=1,
                            force=True,
                            draft_buffer=1,
                            replenish_count=1,
                            limit_realtors=1,
                        ) or []

                        if not rows:
                            raise Exception(f"target article detail row not found: {article_no}")

                        row = rows[0]

                        draft_engine.process_article(conn, row)

                        draft_row = self.fetch_draft_by_article_no(conn, article_no)
                        queue_row = self.fetch_queue_by_article_no(conn, article_no)

                        generated.append({
                            "article_no": article_no,
                            "draft_id": draft_row.get("id") if draft_row else None,
                            "draft_title": draft_row.get("draft_title") if draft_row else None,
                            "publish_queue_id": queue_row.get("id") if queue_row else None,
                            "status": "generated",
                        })

                        return self.ok(
                            message="draft bridge completed: generated=1, failed=0",
                            data={
                                "realtor_id": context.realtor_id,
                                "target": target_data,
                                "generated_count": 1,
                                "failed_count": 0,
                            },
                            drafts=generated,
                            failed=[],
                            skipped=[],
                        )

                    except Exception as e:
                        failed.append({
                            "article_no": article_no,
                            "error": str(e),
                            "status": "failed",
                        })
                        return self.fail(
                            message=f"draft generation failed: {e}",
                            data={
                                "realtor_id": context.realtor_id,
                                "target": target_data,
                                "failed": failed,
                            },
                            drafts=[],
                            failed=failed,
                            skipped=[],
                        )

                skipped.append({
                    "reason": f"unsupported target action: {target.action}",
                    "target": target_data,
                })

                return self.ok(
                    message=f"draft skipped: unsupported target action {target.action}",
                    data={
                        "realtor_id": context.realtor_id,
                        "target": target_data,
                        "skipped_count": 1,
                    },
                    drafts=[],
                    failed=[],
                    skipped=skipped,
                )

            finally:
                conn.close()

        except Exception as e:
            return self.fail(
                message=f"draft adapter failed: {e}",
                data={
                    "realtor_id": context.realtor_id,
                    "error": str(e),
                },
                drafts=[],
                failed=[],
                skipped=[],
            )

    def fetch_draft_by_article_no(self, conn, article_no: str):
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT
                    id,
                    realtor_id,
                    article_no,
                    draft_title,
                    status,
                    draft_status,
                    updated_at
                FROM blog_article_drafts
                WHERE article_no=%s
                ORDER BY id DESC
                LIMIT 1
                """,
                (str(article_no),),
            )
            row = cur.fetchone()

        return dict(row) if row else None

    def fetch_queue_by_article_no(self, conn, article_no: str):
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT
                    id,
                    realtor_id,
                    draft_id,
                    article_no,
                    queue_status,
                    updated_at
                FROM blog_publish_queue
                WHERE article_no=%s
                ORDER BY id DESC
                LIMIT 1
                """,
                (str(article_no),),
            )
            row = cur.fetchone()

        return dict(row) if row else None
