"""
First-run seeder: populates the database with default settings, channels,
admin user, and system prompt derived from the original hardcoded values in run.py.
All functions are idempotent — they only insert if the row doesn't exist yet.
"""

from app.core.database import get_session
from app.core.security import hash_password
from app.core.logger import get_logger
from app.core.config import DEFAULTS, SETTING_CATEGORIES

logger = get_logger()


def seed_settings():
    from app.models.settings import Setting

    db = get_session()
    try:
        inserted = 0
        for key, value in DEFAULTS.items():
            if not db.query(Setting).filter(Setting.key == key).first():
                db.add(Setting(
                    key=key,
                    value=value,
                    category=SETTING_CATEGORIES.get(key, "general"),
                ))
                inserted += 1
        db.commit()
        if inserted:
            logger.info(f"[INIT] Seeded {inserted} default settings.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_settings failed: {exc}")
    finally:
        db.close()


def seed_admin_user():
    from app.models.user import User

    db = get_session()
    try:
        if db.query(User).count() == 0:
            db.add(User(
                username="admin",
                password_hash=hash_password("admin123"),
                is_admin=True,
                is_active=True,
            ))
            db.commit()
            logger.info("[INIT] Default admin user created  →  admin / admin123")
            logger.warning("[INIT] PLEASE change the admin password after first login!")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_admin_user failed: {exc}")
    finally:
        db.close()


def seed_channels():
    from app.models.channel import Channel

    db = get_session()
    try:
        if db.query(Channel).count() == 0:
            defaults = [
                # Source channels (original hardcoded values)
                Channel(chat_id="-1001243016337", channel_type="source",      platform="telegram", title="Source Channel 1", is_active=True),
                Channel(chat_id="-1002585687463", channel_type="source",      platform="telegram", title="Source Channel 2", is_active=True),
                Channel(chat_id="-1003986296490", channel_type="source",      platform="telegram", title="Source Channel 3", is_active=True),
                # Destination: Telegram
                Channel(username="FinanceGPTlab",  channel_type="destination", platform="telegram", title="FinanceGPTlab (Telegram)", is_active=True),
                # Destination: Bale
                Channel(chat_id="4882920821",      channel_type="destination", platform="bale",     title="FinanceGPTlab (Bale)",     is_active=True),
            ]
            for ch in defaults:
                db.add(ch)
            db.commit()
            logger.info("[INIT] Default channels seeded.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_channels failed: {exc}")
    finally:
        db.close()


def seed_forward_rules():
    """
    Migrate the old global forwarding settings (ai.enabled, message.signature*,
    the always-on Bale relay) into one ForwardRule per existing source channel,
    pointing at the existing active Telegram destination. Idempotent — only
    runs once, when the forward_rules table is still empty, so the live
    instance's current behaviour is preserved automatically after upgrade.
    """
    from app.models.channel import Channel
    from app.models.forward_rule import ForwardRule
    from app.core.config import get_setting

    db = get_session()
    try:
        if db.query(ForwardRule).count() > 0:
            return

        destination = db.query(Channel).filter(
            Channel.channel_type == "destination", Channel.platform == "telegram"
        ).order_by(Channel.id).first()
        if not destination:
            logger.warning("[INIT] seed_forward_rules skipped: no Telegram destination channel found.")
            return

        sources = db.query(Channel).filter(
            Channel.channel_type == "source", Channel.platform == "telegram"
        ).order_by(Channel.id).all()
        if not sources:
            return

        ai_enabled = get_setting("ai.enabled", "true").lower() in ("true", "1")
        sig_enabled = get_setting("message.signature_enabled", "false").lower() in ("true", "1")
        sig_text = get_setting("message.signature", "") or None

        created = 0
        for src in sources:
            db.add(ForwardRule(
                name=f"قانون {src.display_name}",
                source_channel_id=src.id,
                destination_channel_id=destination.id,
                ai_enabled=ai_enabled,
                signature_enabled=sig_enabled,
                signature_text=sig_text,
                forward_to_bale=True,  # preserves today's unconditional Bale relay
                is_active=src.is_active,
            ))
            created += 1
        db.commit()
        logger.info(f"[INIT] Seeded {created} forward rule(s) from existing channels/settings.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_forward_rules failed: {exc}")
    finally:
        db.close()


def seed_default_prompt():
    from app.models.prompt_history import PromptHistory

    db = get_session()
    try:
        if db.query(PromptHistory).count() == 0:
            db.add(PromptHistory(
                system_prompt="You are a professional Persian content rewriter.",
                user_prompt_template=(
                    "متن زیر را به فارسی روان و حرفه‌ای بازنویسی کن.\n"
                    "- معنا حفظ شود.\n"
                    "- جمله‌بندی تازه باشد.\n"
                    "- فقط متن نهایی را بده.\n\n"
                    "متن:\n{text}"
                ),
                note="پرامپت پیش‌فرض (نسخه اولیه)",
                created_by="system",
                is_active=True,
            ))
            db.commit()
            logger.info("[INIT] Default prompt seeded.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_default_prompt failed: {exc}")
    finally:
        db.close()


def seed_default_roles():
    """Seed the built-in conversational roles listed in the spec (section 9)."""
    from app.models.role import Role

    db = get_session()
    try:
        if db.query(Role).count() == 0:
            roles = [
                ("مدیر", "گفتگو را هدایت و جمع‌بندی می‌کند", "تو مدیر بحث هستی؛ گفتگو را هدایت کن، نظم بده و در صورت لزوم جمع‌بندی کن."),
                ("تحلیل‌گر", "موضوع را تحلیل می‌کند", "موضوع را با دقت و منطق تحلیل کن و دیدگاه کارشناسی ارائه بده."),
                ("منتقد", "نقاط ضعف را نقد می‌کند", "با نگاه نقادانه نقاط ضعف و ابهام‌های گفته‌های دیگران را مطرح کن."),
                ("موافق", "از دیدگاه‌ها حمایت می‌کند", "با استدلال از دیدگاه مطرح‌شده حمایت کن و آن را تقویت کن."),
                ("مخالف", "دیدگاه مخالف ارائه می‌دهد", "دیدگاه مخالف و چالش‌برانگیز ارائه بده تا بحث عمیق‌تر شود."),
                ("مبتدی", "سؤالات ساده می‌پرسد", "مثل یک تازه‌کار سؤالات ساده و کنجکاوانه بپرس."),
                ("متخصص", "دانش تخصصی ارائه می‌دهد", "با دانش تخصصی و جزئیات دقیق به بحث کمک کن."),
                ("معلم", "توضیح می‌دهد و آموزش می‌دهد", "مفاهیم را ساده و آموزشی توضیح بده."),
                ("دانشجو", "یاد می‌گیرد و سؤال می‌کند", "با اشتیاق یاد بگیر و برای درک بهتر سؤال بپرس."),
                ("سرمایه‌گذار", "از منظر بازده و ریسک نگاه می‌کند", "از منظر سرمایه‌گذاری به ریسک، بازده و فرصت‌ها بپرداز."),
                ("خبرنگار", "گزارش و پرسش‌گری می‌کند", "مثل یک خبرنگار سؤالات کاوشگرانه بپرس و نکات مهم را برجسته کن."),
            ]
            for name, desc, prompt in roles:
                db.add(Role(name=name, description=desc, behavior_prompt=prompt, is_builtin=True))
            db.commit()
            logger.info("[INIT] Default roles seeded.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_default_roles failed: {exc}")
    finally:
        db.close()


def seed_default_personas():
    """Seed a couple of starter personas."""
    from app.models.persona import Persona

    db = get_session()
    try:
        if db.query(Persona).count() == 0:
            db.add(Persona(
                name="کاربر عادی", display_name="کاربر", personality="دوستانه و کنجکاو",
                knowledge_level="متوسط", tone="دوستانه", formality="نیمه‌رسمی",
                emoji_usage="کم", avg_message_length="کوتاه",
                writing_style="ساده و روان", interests="اقتصاد و بازارها",
            ))
            db.add(Persona(
                name="کارشناس بازار", display_name="کارشناس", personality="جدی و تحلیلی",
                knowledge_level="پیشرفته", tone="حرفه‌ای", formality="رسمی",
                emoji_usage="هیچ", avg_message_length="متوسط",
                writing_style="دقیق و مستند", interests="تحلیل تکنیکال و بنیادی",
            ))
            db.commit()
            logger.info("[INIT] Default personas seeded.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_default_personas failed: {exc}")
    finally:
        db.close()


def seed_default_ai_provider():
    """Seed one AI provider from the working forward AI settings (encrypted)."""
    from app.models.ai_provider import AIProvider
    from app.core import crypto

    db = get_session()
    try:
        if db.query(AIProvider).count() == 0:
            db.add(AIProvider(
                name="Provider پیش‌فرض",
                provider_type="custom",
                base_url=DEFAULTS.get("ai.base_url", ""),
                api_key=crypto.encrypt(DEFAULTS.get("ai.api_key", "")),
                model=DEFAULTS.get("ai.model", ""),
                context_window=8192,
                max_tokens=1024,
                temperature=float(DEFAULTS.get("ai.temperature", "0.7")),
                is_active=True,
            ))
            db.commit()
            logger.info("[INIT] Default AI provider seeded.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_default_ai_provider failed: {exc}")
    finally:
        db.close()


def seed_permissions():
    """Seed the RBAC permission catalog (idempotent, keeps it in sync)."""
    from app.models.permission import Permission
    from app.core.rbac import PERMISSION_CATALOG

    db = get_session()
    try:
        existing = {p.code for p in db.query(Permission).all()}
        inserted = 0
        for code, name, module, desc in PERMISSION_CATALOG:
            if code not in existing:
                db.add(Permission(code=code, name=name, module=module, description=desc))
                inserted += 1
        db.commit()
        if inserted:
            logger.info(f"[INIT] Seeded {inserted} permissions.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_permissions failed: {exc}")
    finally:
        db.close()


def seed_admin_roles():
    """Seed built-in RBAC roles."""
    import json
    from app.models.admin_role import AdminRole
    from app.core.rbac import DEFAULT_ROLES

    db = get_session()
    try:
        if db.query(AdminRole).count() == 0:
            for name, spec in DEFAULT_ROLES.items():
                db.add(AdminRole(
                    name=name,
                    description=spec["description"],
                    permissions=json.dumps(spec["permissions"], ensure_ascii=False),
                    is_system=True,
                ))
            db.commit()
            logger.info("[INIT] Default admin roles seeded.")
    except Exception as exc:
        db.rollback()
        logger.error(f"[INIT] seed_admin_roles failed: {exc}")
    finally:
        db.close()


def seed_all():
    seed_settings()
    seed_admin_user()
    seed_channels()
    seed_forward_rules()
    seed_default_prompt()
    seed_default_roles()
    seed_default_personas()
    seed_default_ai_provider()
    seed_permissions()
    seed_admin_roles()
