"""One-off seed: registers translation_keys English source_text and hi/mr/hinglish
translation_values for the "permission-catalog" PageInfoButton content.

Usage: docker compose exec api python seed_translations_pageinfo_permission_catalog.py
"""
import asyncio
import uuid
from datetime import datetime, timezone

from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine

from ams.core.config import settings

NAMESPACE = "help"

# key -> (english, hi, mr, hinglish)
PERMISSION_CATALOG = {
    "permission-catalog.title": (
        "Permission Catalog",
        "परमिशन कैटलॉग",
        "परमिशन कॅटलॉग",
        "Permission Catalog",
    ),
    "permission-catalog.subtitle": (
        "How the catalog feeds roles, and what each column means",
        "कैटलॉग roles को कैसे फ़ीड करता है, और हर कॉलम का क्या मतलब है",
        "कॅटलॉग roles ला कसे feed करते, आणि प्रत्येक कॉलमचा अर्थ काय आहे",
        "Catalog roles ko kaise feed karta hai, aur har column ka kya matlab hai",
    ),
    "permission-catalog.body.0": (
        "The full list of permissions across every module — the same catalog Role Create/Edit pull from when building a role's checkbox list.",
        "हर module में मौजूद permissions की पूरी सूची — यही catalog है जिससे Role Create/Edit किसी role की checkbox list बनाते समय डेटा लेता है।",
        "प्रत्येक module मधील permissions ची संपूर्ण यादी — हाच catalog आहे ज्यातून Role Create/Edit एखाद्या role ची checkbox list तयार करताना डेटा घेतो.",
        "Har module mein mojood permissions ki poori list — yahi catalog hai jisse Role Create/Edit kisi role ki checkbox list banate waqt data leta hai.",
    ),
    "permission-catalog.body.1": (
        "This page is read-only: permissions themselves are defined in backend code. Use Sync Catalog to pull in newly added definitions, or Reseed Standard Roles to re-apply built-in role grants after a code change.",
        "यह पेज read-only है: permissions स्वयं backend code में परिभाषित होती हैं। नई जोड़ी गई definitions लाने के लिए Sync Catalog का उपयोग करें, या code बदलने के बाद built-in role grants को फिर से लागू करने के लिए Reseed Standard Roles चलाएँ।",
        "हे पेज read-only आहे: permissions स्वतः backend code मध्ये परिभाषित असतात. नव्याने जोडलेल्या definitions आणण्यासाठी Sync Catalog वापरा, किंवा code बदलल्यानंतर built-in role grants पुन्हा लागू करण्यासाठी Reseed Standard Roles चालवा.",
        "Ye page read-only hai: permissions khud backend code mein define hoti hain. Nayi add hui definitions laane ke liye Sync Catalog use karein, ya code change ke baad built-in role grants dobara apply karne ke liye Reseed Standard Roles chalayein.",
    ),
    "permission-catalog.stepsHeading": (
        "How permissions reach a role",
        "Permissions किसी role तक कैसे पहुँचती हैं",
        "Permissions एखाद्या role पर्यंत कशा पोहोचतात",
        "Permissions kisi role tak kaise pahunchti hain",
    ),
    "permission-catalog.steps.0.label": (
        "Defined in Code", "Code में परिभाषित", "Code मध्ये परिभाषित", "Code mein Defined",
    ),
    "permission-catalog.steps.0.caption": (
        "Backend modules declare each permission key",
        "Backend modules हर permission key को घोषित करते हैं",
        "Backend modules प्रत्येक permission key जाहीर करतात",
        "Backend modules har permission key declare karte hain",
    ),
    "permission-catalog.steps.1.label": (
        "Sync Catalog", "कैटलॉग सिंक करें", "कॅटलॉग सिंक करा", "Sync Catalog",
    ),
    "permission-catalog.steps.1.caption": (
        "Upserts by name — never deletes existing entries",
        "नाम के आधार पर upsert करता है — मौजूदा entries को कभी नहीं मिटाता",
        "नावाच्या आधारे upsert करते — विद्यमान entries कधीही delete करत नाही",
        "Naam ke base par upsert karta hai — existing entries ko kabhi delete nahi karta",
    ),
    "permission-catalog.steps.2.label": (
        "Role Builder", "रोल बिल्डर", "रोल बिल्डर", "Role Builder",
    ),
    "permission-catalog.steps.2.caption": (
        "Role Create/Edit pick from this catalog",
        "Role Create/Edit इसी catalog से चुनते हैं",
        "Role Create/Edit याच catalog मधून निवडतात",
        "Role Create/Edit isi catalog se pick karte hain",
    ),
    "permission-catalog.steps.3.label": (
        "Reseed Roles", "रोल्स रीसीड करें", "रोल्स रीसीड करा", "Reseed Roles",
    ),
    "permission-catalog.steps.3.caption": (
        "Re-applies standard-role grants to match code",
        "Code से मेल खाने के लिए standard-role grants फिर से लागू करता है",
        "Code शी जुळण्यासाठी standard-role grants पुन्हा लागू करते",
        "Code ke match karne ke liye standard-role grants dobara apply karta hai",
    ),
    "permission-catalog.fieldRules.0.name": (
        "Permission key", "परमिशन Key", "परमिशन Key", "Permission key",
    ),
    "permission-catalog.fieldRules.0.description": (
        "Machine name like assets:create, defined in backend code and used verbatim by Role Create/Edit.",
        "assets:create जैसा machine name, जो backend code में परिभाषित होता है और Role Create/Edit द्वारा ज्यों-का-त्यों उपयोग किया जाता है।",
        "assets:create सारखे machine name, जे backend code मध्ये परिभाषित असते आणि Role Create/Edit द्वारे जसेच्या तसे वापरले जाते.",
        "assets:create jaisa machine name, jo backend code mein define hota hai aur Role Create/Edit dwara waisa hi use hota hai.",
    ),
    "permission-catalog.fieldRules.1.name": (
        "Description", "विवरण", "वर्णन", "Description",
    ),
    "permission-catalog.fieldRules.1.description": (
        "Plain-English explanation of the grant; shows \"No description\" if the backend definition omitted one.",
        "grant की सरल भाषा में व्याख्या; यदि backend definition में कोई विवरण नहीं दिया गया हो तो \"No description\" दिखाता है।",
        "grant चे सोप्या भाषेत स्पष्टीकरण; जर backend definition मध्ये वर्णन दिलेले नसेल तर \"No description\" दाखवते.",
        "Grant ki simple bhasha mein explanation; agar backend definition mein description nahi diya gaya to \"No description\" dikhata hai.",
    ),
    "permission-catalog.fieldRules.2.name": (
        "Module", "मॉड्यूल", "मॉड्यूल", "Module",
    ),
    "permission-catalog.fieldRules.2.description": (
        "Groups permissions by feature area; a module's card disappears only when none of its permissions match your search.",
        "permissions को feature area के अनुसार समूहित करता है; किसी module का card तभी गायब होता है जब उसकी कोई भी permission आपकी search से मेल न खाए।",
        "permissions ला feature area नुसार गटबद्ध करते; एखाद्या module चे card तेव्हाच अदृश्य होते जेव्हा त्याची कोणतीही permission तुमच्या search शी जुळत नाही.",
        "Permissions ko feature area ke hisaab se group karta hai; kisi module ka card tabhi gayab hota hai jab uski koi bhi permission aapki search se match na kare.",
    ),
    "permission-catalog.fieldRules.3.name": (
        "Search", "सर्च", "सर्च", "Search",
    ),
    "permission-catalog.fieldRules.3.description": (
        "Filters by permission key or description only — a module name alone won't match unless it also appears in a key or description.",
        "केवल permission key या description के आधार पर filter करता है — अकेला module name तब तक मेल नहीं खाएगा जब तक वह किसी key या description में भी न दिखे।",
        "फक्त permission key किंवा description च्या आधारे filter करते — एकटे module name तेव्हाच जुळेल जेव्हा ते एखाद्या key किंवा description मध्येही दिसेल.",
        "Sirf permission key ya description ke base par filter karta hai — akela module name tab tak match nahi karega jab tak wo kisi key ya description mein bhi na dikhe.",
    ),
    "permission-catalog.tip.title": (
        "Syncing doesn't grant anything",
        "Sync करने से कुछ भी grant नहीं होता",
        "Sync केल्याने काहीही grant होत नाही",
        "Sync karne se kuch bhi grant nahi hota",
    ),
    "permission-catalog.tip.body": (
        "Sync Catalog only adds new permission rows here — it never assigns them to a role. After adding permissions in code, run Reseed Standard Roles for built-in roles, or edit custom roles manually in Role Permissions.",
        "Sync Catalog यहाँ केवल नई permission rows जोड़ता है — यह उन्हें कभी किसी role को असाइन नहीं करता। code में permissions जोड़ने के बाद, built-in roles के लिए Reseed Standard Roles चलाएँ, या custom roles को Role Permissions में मैन्युअल रूप से एडिट करें।",
        "Sync Catalog येथे फक्त नवीन permission rows जोडते — ते कधीही त्या एखाद्या role ला assign करत नाही. code मध्ये permissions जोडल्यानंतर, built-in roles साठी Reseed Standard Roles चालवा, किंवा custom roles Role Permissions मध्ये manually edit करा.",
        "Sync Catalog yahan sirf nayi permission rows add karta hai — ye unhe kabhi kisi role ko assign nahi karta. Code mein permissions add karne ke baad, built-in roles ke liye Reseed Standard Roles chalayein, ya custom roles ko Role Permissions mein manually edit karein.",
    ),
}


async def seed_for_session(session: AsyncSession) -> tuple[int, int]:
    now = datetime.now(timezone.utc)
    keys_upserted = 0
    values_upserted = 0
    for key, (en, hi, mr, hinglish) in PERMISSION_CATALOG.items():
        key_id = (await session.execute(
            text("SELECT id FROM translation_keys WHERE namespace = :ns AND key = :key"),
            {"ns": NAMESPACE, "key": key},
        )).scalar_one_or_none()
        if key_id:
            await session.execute(
                text("UPDATE translation_keys SET source_text = :src WHERE id = :id"),
                {"src": en, "id": key_id},
            )
        else:
            key_id = str(uuid.uuid4())
            await session.execute(
                text("""INSERT INTO translation_keys (id, namespace, key, source_text, created_at)
                        VALUES (:id, :ns, :key, :src, :now)"""),
                {"id": key_id, "ns": NAMESPACE, "key": key, "src": en, "now": now},
            )
            keys_upserted += 1

        for lang_code, value in (("hi", hi), ("mr", mr), ("hinglish", hinglish)):
            existing = (await session.execute(
                text("SELECT id FROM translation_values WHERE key_id = :kid AND language_code = :lc"),
                {"kid": key_id, "lc": lang_code},
            )).scalar_one_or_none()
            if existing:
                await session.execute(
                    text("UPDATE translation_values SET value = :val, updated_at = :now WHERE id = :id"),
                    {"val": value, "now": now, "id": existing},
                )
            else:
                await session.execute(
                    text("""INSERT INTO translation_values (id, key_id, language_code, value, updated_by, updated_at)
                            VALUES (:id, :kid, :lc, :val, NULL, :now)"""),
                    {"id": str(uuid.uuid4()), "kid": key_id, "lc": lang_code, "val": value, "now": now},
                )
                values_upserted += 1
    await session.commit()
    return keys_upserted, values_upserted


async def main() -> None:
    engine = create_async_engine(settings.DATABASE_URL, echo=False)
    Session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

    async with Session() as session:
        tenants = (await session.execute(
            text("SELECT id::text AS id, slug FROM public.tenants WHERE status != 'archived'")
        )).fetchall()

    for tenant in tenants:
        schema = f"tenant_{tenant.id.replace('-', '_')}"
        async with Session() as session:
            await session.execute(text(f"SET search_path TO {schema}, public"))
            try:
                k, v = await seed_for_session(session)
                print(f"  seeded {k} new keys, {v} new values: {tenant.slug}")
            except Exception as exc:
                print(f"  SKIPPED {tenant.slug}: {exc}")
                await session.rollback()

    await engine.dispose()
    print(f"Done — {len(tenants)} tenant(s) processed, {len(PERMISSION_CATALOG)} permission-catalog keys.")


if __name__ == "__main__":
    asyncio.run(main())
