"""Auto-send scheduler — digianti-style cron jobs with PTB job_queue."""
from __future__ import annotations

import logging
import time
from typing import Optional

from telegram import Update
from telegram.constants import ParseMode
from telegram.ext import ContextTypes

from bot import db
from bot.helpers import is_chat_admin
from bot.infra.db.scheduler_repository import scheduler_repository

logger = logging.getLogger(__name__)


# ───────── Scheduled Messages (one-shot or repeating) ─────────
async def schedule_add_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """
    /schedule add <seconds> <text> — Schedule a one-shot message
    /schedule repeat <minutes> <text> — Schedule a repeating message
    /schedule list — List scheduled jobs
    /schedule del <id> — Delete a scheduled job
    """
    if not update.message or not update.message.text:
        return

    chat_id = update.effective_chat.id
    user_id = update.effective_user.id

    if not await is_chat_admin(context.bot, chat_id, user_id):
        await update.message.reply_text("فقط ادمین‌ها می‌توانند زمان‌بندی تنظیم کنند.")
        return

    parts = update.message.text.split(None, 3)
    if len(parts) < 2:
        await update.message.reply_text(
            "UsageId:\n"
            "/schedule add <ثانیه> <متن> — ارسال یکبار\n"
            "/schedule repeat <دقیقه> <متن> — ارسال تکراری\n"
            "/schedule list — لیست زمان‌بندی‌ها\n"
            "/schedule del <id> — حذف زمان‌بندی"
        )
        return

    sub = parts[1].lower()

    if sub == "list":
        rows = await scheduler_repository.list_chat_jobs(chat_id)

        if not rows:
            await update.message.reply_text("هیچ زمان‌بندی‌ای ثبت نشده.")
            return
        text = "📋 زمان‌بندی‌ها:\n\n"
        for r in rows:
            icon = "🔁" if r["job_type"] == "repeat" else "⏰"
            mins = r["interval_secs"] // 60
            text += f"{icon} #{r['id']} — هر {mins} دقیقه — {r['text_preview'][:30]}\n"
        await update.message.reply_text(text)
        return

    if sub == "del":
        if len(parts) < 3:
            await update.message.reply_text("UsageId:\n/schedule del <id>")
            return
        try:
            job_id = int(parts[2])
        except ValueError:
            await update.message.reply_text("ID باید عدد باشد.")
            return

        row = await scheduler_repository.get_chat_job(job_id, chat_id)

        if not row:
            await update.message.reply_text("این زمان‌بندی یافت نشد.")
            return

        # Remove from job_queue
        current_jobs = context.job_queue.get_jobs_by_name(f"sched_{job_id}")
        for job in current_jobs:
            job.schedule_removal()

        await scheduler_repository.delete_job(job_id)

        await update.message.reply_text(f"✅ زمان‌بندی #{job_id} حذف شد.")
        return

    if sub in ("add", "repeat"):
        if len(parts) < 4:
            await update.message.reply_text(f"UsageId:\n/schedule {sub} <زمان> <متن>")
            return
        try:
            val = int(parts[2])
        except ValueError:
            await update.message.reply_text("زمان باید عدد باشد.")
            return

        if val < 5:
            await update.message.reply_text("حداقل ۵ ثانیه / دقیقه.")
            return

        text = parts[3]
        job_type = "repeat" if sub == "repeat" else "once"
        interval = val * 60 if sub == "repeat" else val

        # Save to DB
        cur = await db._exec(
            "INSERT INTO scheduled_jobs (chat_id, job_type, interval_secs, text_preview, created_by) VALUES (?, ?, ?, ?, ?)",
            (chat_id, job_type, interval, text[:200], user_id),
        )
        job_id = cur.lastrowid

        # Schedule with job_queue
        if sub == "repeat":
            context.job_queue.run_repeating(
                _send_scheduled,
                interval=interval,
                data={"job_id": job_id, "chat_id": chat_id, "text": text},
                name=f"sched_{job_id}",
            )
        else:
            context.job_queue.run_once(
                _send_scheduled_once,
                when=interval,
                data={"job_id": job_id, "chat_id": chat_id, "text": text},
                name=f"sched_{job_id}",
            )

        unit = "دقیقه" if sub == "repeat" else "ثانیه"
        await update.message.reply_text(
            f"✅ زمان‌بندی ثبت شد!\n"
            f"شناسه: #{job_id}\n"
            f"نوع: {'تکراری' if sub == 'repeat' else 'یکبار'}\n"
            f"زمان: هر {val} {unit}"
        )
        return

    await update.message.reply_text("دستور نامعتبر. از /schedule کمک بگیرید.")


async def _send_scheduled(context: ContextTypes.DEFAULT_TYPE) -> None:
    """Send a scheduled message (repeating)."""
    data = context.job.data
    chat_id = data["chat_id"]
    text = data["text"]
    job_id = data["job_id"]

    try:
        await context.bot.send_message(chat_id=chat_id, text=text)
    except Exception as e:
        logger.warning(f"Auto-send failed for job {job_id}: {e}")


async def _send_scheduled_once(context: ContextTypes.DEFAULT_TYPE) -> None:
    """Send a one-shot scheduled message."""
    data = context.job.data
    chat_id = data["chat_id"]
    text = data["text"]
    job_id = data["job_id"]

    try:
        await context.bot.send_message(chat_id=chat_id, text=text)
    except Exception as e:
        logger.warning(f"Auto-send (once) failed for job {job_id}: {e}")
    finally:
        # Remove from DB
        await scheduler_repository.delete_job(job_id)


# ───────── Auto-post daily stats ─────────
async def autopost_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """
    /autopost <channel> — Auto-post daily stats to a channel
    /autopost off — Disable
    """
    if not update.message or not update.message.text:
        return

    chat_id = update.effective_chat.id
    user_id = update.effective_user.id

    if not await is_chat_admin(context.bot, chat_id, user_id):
        await update.message.reply_text("فقط ادمین‌ها می‌توانند تنظیم کنند.")
        return

    parts = update.message.text.split()
    if len(parts) < 2:
        current = await db.get_setting(chat_id, "autopost_channel", "")
        status = f"🟢 {current}" if current else "🔴 غیرفعال"
        await update.message.reply_text(
            f"📡 <b>ارسال خودکار آمار</b>\n\n"
            f"وضعیت: {status}\n\n"
            f"Usage:\n"
            f"/autopost @channel — فعال‌سازی\n"
            f"/autopost off — غیرفعال‌سازی",
            parse_mode=ParseMode.HTML,
        )
        return

    channel = parts[1]
    if channel.lower() == "off":
        await db.set_setting(chat_id, "autopost_channel", "")
        # Remove scheduled job
        jobs = context.job_queue.get_jobs_by_name(f"autopost_{chat_id}")
        for job in jobs:
            job.schedule_removal()
        await update.message.reply_text("✅ ارسال خودکار آمار غیرفعال شد.")
        return

    await db.set_setting(chat_id, "autopost_channel", channel)

    # Schedule daily stats at 23:00
    context.job_queue.run_repeating(
        _auto_stats_job,
        interval=86400,  # 24 hours
        data={"chat_id": chat_id, "channel": channel},
        name=f"autopost_{chat_id}",
    )

    await update.message.reply_text(f"✅ ارسال خودکار آمار به {channel} فعال شد (هر ۲۴ ساعت).")


async def _auto_stats_job(context: ContextTypes.DEFAULT_TYPE) -> None:
    """Auto-post daily stats to channel."""
    data = context.job.data
    chat_id = data["chat_id"]
    channel = data["channel"]

    try:
        from datetime import datetime
        now = datetime.now()
        text = (
            f"📊 گزارش روزانه — {now.strftime('%Y/%m/%d')}\n\n"
            f"آمار خودکار هر ۲۴ ساعت ارسال می‌شود."
        )
        await context.bot.send_message(chat_id=channel, text=text)
    except Exception as e:
        logger.warning(f"Auto-post failed for {channel}: {e}")


# ───────── Restore jobs on startup ─────────
async def restore_scheduled_jobs(app) -> None:
    """Restore scheduled jobs from DB on bot startup."""
    try:
        rows = await scheduler_repository.list_all_jobs()

        if not rows:
            return

        count = 0
        for r in rows:
            job_id = r["id"]
            chat_id = r["chat_id"]
            job_type = r["job_type"]
            interval = r["interval_secs"]
            text = r["text_preview"]

            if job_type == "repeat":
                app.job_queue.run_repeating(
                    _send_scheduled,
                    interval=interval,
                    data={"job_id": job_id, "chat_id": chat_id, "text": text},
                    name=f"sched_{job_id}",
                )
            else:
                # Calculate remaining time
                created = r["created_at"]
                remaining = max(1, interval - (int(time.time()) - created))
                app.job_queue.run_once(
                    _send_scheduled_once,
                    when=remaining,
                    data={"job_id": job_id, "chat_id": chat_id, "text": text},
                    name=f"sched_{job_id}",
                )
            count += 1

        logger.info(f"Restored {count} scheduled jobs from DB")
    except Exception as e:
        logger.warning(f"Could not restore scheduled jobs: {e}")


def register(app) -> None:
    from telegram.ext import CommandHandler
    app.add_handler(CommandHandler("schedule", schedule_add_cmd))
    app.add_handler(CommandHandler("autopost", autopost_cmd))
