# ══════════════════════════════════════════════════════════
#  engines/article.py — Artikel Generator (Single + Bulk)
#  Input : BRAND / TITLE / META DESC  (3 baris)
#  Output: 1 artikel per domain
# ══════════════════════════════════════════════════════════

import asyncio
import logging
import os
import re
import time
from telegram import InlineKeyboardButton, InlineKeyboardMarkup

from config import PROMPT_ARTICLE, BULK_SLEEP_SEC
from engines.utils import load_prompt_file, call_ai, build_article_user_message

logger = logging.getLogger(__name__)


def _kb(*rows):
    return InlineKeyboardMarkup(
        [[InlineKeyboardButton(t, callback_data=d) for t, d in row] for row in rows]
    )


def _extract_clean(raw: str):
    """
    Pisah isi artikel dan baris audit dari raw response.
    Return: (article_body: str, audit_line: str)
    """
    # Coba ambil antara dua ---
    parts = re.split(r'(?m)^-{3,}\s*$', raw)
    if len(parts) >= 3:
        body  = parts[1].strip()
        body  = re.sub(r'(?i)^\[?ARTIKEL\]?\s*', '', body).strip()
        # Cari baris audit (satu baris terakhir setelah ---)
        after = parts[2].strip() if len(parts) > 2 else ''
        audit = after.split('\n')[0].strip() if after else ''
        return body, audit

    # Fallback: buang baris header, ambil paragraf terpanjang
    lines  = raw.split('\n')
    clean  = [l for l in lines if not re.match(r'(?i).*=====|\[langkah|\[artikel|^audit:', l.strip())]
    body   = '\n'.join(clean).strip()

    # Cari baris audit
    audit  = ''
    for l in lines:
        if re.match(r'(?i)^audit:', l.strip()):
            audit = l.strip()
            break

    return body, audit


async def _send_article(message, raw: str, brand: str, ai: str, keyboard=None):
    body, audit = _extract_clean(raw)
    ai_tag      = '⚡ Claude' if ai == 'claude' else '🔮 Gemini'

    header = f"*Artikel*  ·  {ai_tag}  ·  `{brand}`\n\n"
    footer = f"\n\n_{audit}_" if audit else ''
    full   = f"{header}{body}{footer}"

    if len(full) > 4000:
        filename = f"artikel_{brand}_{int(time.time())}.txt"
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(body)
        with open(filename, 'rb') as f:
            await message.reply_document(
                document=f, filename=filename,
                caption=f"*Artikel*  ·  {ai_tag}  ·  `{brand}`",
                parse_mode="Markdown"
            )
        os.remove(filename)
    else:
        await message.reply_text(full, reply_markup=keyboard, parse_mode="Markdown")


# ══════════════════════════════════════════════════════════
#  SINGLE
# ══════════════════════════════════════════════════════════
async def generate_article_single(message, context):
    try:
        system_prompt = load_prompt_file(PROMPT_ARTICLE)
        ai            = context.user_data.get('ai_provider', 'claude')

        user_msg = build_article_user_message(
            brand     = context.user_data['brand'],
            title     = context.user_data['title'],
            meta_desc = context.user_data['meta_desc'],
        )

        response = await call_ai(user_msg, system_prompt, message, "article", ai)
        if not response:
            return

        keyboard = _kb([("↺  Regen", "mode_ARTICLE_SINGLE"), ("Menu", "menu_main")])
        await _send_article(message, response, context.user_data['brand'], ai, keyboard)
        context.user_data.clear()

    except FileNotFoundError as e:
        await message.reply_text(f"File tidak ditemukan\n`{e}`", parse_mode="Markdown")
    except Exception as e:
        logger.error(f"Article single: {e}")
        await message.reply_text(f"Article engine error\n`{e}`", parse_mode="Markdown")


# ══════════════════════════════════════════════════════════
#  BULK
# ══════════════════════════════════════════════════════════
async def generate_article_bulk(message, context):
    try:
        bulk_data     = context.user_data.get('bulk_data', [])
        system_prompt = load_prompt_file(PROMPT_ARTICLE)
        ai            = context.user_data.get('ai_provider', 'claude')
        ai_tag        = '⚡ Claude' if ai == 'claude' else '🔮 Gemini'

        for idx, item in enumerate(bulk_data):
            user_msg = build_article_user_message(
                brand=item['brand'], title=item['title'], meta_desc=item['meta_desc']
            )
            response = await call_ai(user_msg, system_prompt, message, "article", ai)
            if not response:
                return

            await _send_article(message, response, item['brand'], ai)
            if idx < len(bulk_data) - 1:
                await asyncio.sleep(BULK_SLEEP_SEC)

        await message.reply_text(
            f"*Bulk artikel selesai*\n{len(bulk_data)} domain  ·  {ai_tag}",
            reply_markup=_kb([("Bulk Baru", "mode_ARTICLE_BULK"), ("Menu", "menu_main")]),
            parse_mode="Markdown"
        )
        context.user_data.clear()

    except FileNotFoundError as e:
        await message.reply_text(f"File tidak ditemukan\n`{e}`", parse_mode="Markdown")
    except Exception as e:
        logger.error(f"Article bulk: {e}")
        await message.reply_text(f"Bulk artikel error\n`{e}`", parse_mode="Markdown")


# ══════════════════════════════════════════════════════════
#  FROM CONTEXT (Full Content pipeline)
# ══════════════════════════════════════════════════════════
async def generate_article_from_context(message, context):
    try:
        system_prompt = load_prompt_file(PROMPT_ARTICLE)
        ai            = context.user_data.get('ai_provider', 'claude')

        user_msg = build_article_user_message(
            brand     = context.user_data['brand'],
            title     = context.user_data['selected_title'],
            meta_desc = context.user_data['selected_meta'],
        )

        response = await call_ai(user_msg, system_prompt, message, "article", ai)
        if not response:
            return

        keyboard = _kb([("Ulangi Full Content", "mode_FULL"), ("Menu", "menu_main")])
        await _send_article(message, response, context.user_data['brand'], ai, keyboard)
        context.user_data.clear()

    except FileNotFoundError as e:
        await message.reply_text(f"File tidak ditemukan\n`{e}`", parse_mode="Markdown")
    except Exception as e:
        logger.error(f"Article from context: {e}")
        await message.reply_text(f"Article engine error\n`{e}`", parse_mode="Markdown")