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

Usage: docker compose exec api python seed_translations_pageinfo_generic_masters.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)
GENERIC_MASTERS = {
    "generic-masters.title": (
        "Generic Masters",
        "जेनेरिक मास्टर्स",
        "जेनेरिक मास्टर्स",
        "Generic Masters",
    ),
    "generic-masters.subtitle": (
        "One CRUD screen for every registry-driven master table",
        "प्रत्येक registry-driven master table के लिए एक ही CRUD screen",
        "प्रत्येक registry-driven master table साठी एकच CRUD screen",
        "Har registry-driven master table ke liye ek hi CRUD screen",
    ),
    "generic-masters.body.0": (
        "Browse and maintain any of the {{count}} generic master tables — UOM, banks, OEMs, warranty terms, condition/criticality codes and more — from a single screen. Pick the table from the selector; each one gets the same code / name / description form and maker-checker workflow.",
        "{{count}} generic master tables में से किसी को भी एक ही स्क्रीन से ब्राउज़ और मेंटेन करें — UOM, banks, OEMs, warranty terms, condition/criticality codes और अन्य। selector से table चुनें; हर एक को समान code / name / description फ़ॉर्म और maker-checker workflow मिलता है।",
        "{{count}} generic master tables पैकी कोणतीही एकाच स्क्रीनवरून ब्राउझ आणि मेंटेन करा — UOM, banks, OEMs, warranty terms, condition/criticality codes आणि इतर. selector मधून table निवडा; प्रत्येकाला समान code / name / description फॉर्म आणि maker-checker workflow मिळते.",
        "{{count}} generic master tables mein se koi bhi ek hi screen se browse aur maintain karein — UOM, banks, OEMs, warranty terms, condition/criticality codes aur bhi bahut kuch. Selector se table pick karein; har ek ko same code / name / description form aur maker-checker workflow milta hai.",
    ),
    "generic-masters.body.1": (
        "Deep-linkable via ?table=<registry_key>, so sidebar entries for a specific table (e.g. Bank Masters, UOM) can open straight into that table without you having to reselect it.",
        "?table=<registry_key> के ज़रिए deep-linkable, ताकि किसी खास table (जैसे Bank Masters, UOM) के लिए sidebar entries सीधे उसी table में खुल सकें, बिना आपको दोबारा select किए।",
        "?table=<registry_key> द्वारे deep-linkable, त्यामुळे एखाद्या विशिष्ट table साठी (उदा. Bank Masters, UOM) sidebar entries थेट त्याच table मध्ये उघडू शकतात, तुम्हाला पुन्हा निवड न करता.",
        "?table=<registry_key> ke through deep-linkable hai, isliye kisi specific table (jaise Bank Masters, UOM) ke liye sidebar entries seedha usi table mein khul jaate hain, aapko dobara select kiye bina.",
    ),
    "generic-masters.stepsHeading": (
        "Life of a record",
        "एक Record का जीवनचक्र",
        "एका Record चे जीवनचक्र",
        "Record ki life kaise chalti hai",
    ),
    "generic-masters.steps.0.label": ("Add Record", "Record जोड़ें", "Record जोडा", "Record Add karein"),
    "generic-masters.steps.0.caption": (
        "Code + Name saved; Code can never be changed afterwards",
        "Code + Name सेव हो जाते हैं; Code बाद में कभी नहीं बदला जा सकता",
        "Code + Name सेव्ह होतात; Code नंतर कधीही बदलता येत नाही",
        "Code + Name save ho jaate hain; Code baad mein kabhi change nahi ho sakta",
    ),
    "generic-masters.steps.1.label": ("Pending Approval", "अनुमोदन लंबित", "मंजुरी प्रलंबित", "Approval Pending"),
    "generic-masters.steps.1.caption": (
        "Unusable elsewhere until a second user signs off",
        "जब तक कोई दूसरा user साइन-ऑफ नहीं करता, तब तक यह कहीं और इस्तेमाल नहीं हो सकता",
        "जोपर्यंत दुसरा user साइन-ऑफ करत नाही, तोपर्यंत हे कुठेही वापरता येत नाही",
        "Jab tak koi doosra user sign-off nahi karta, tab tak kahin aur use nahi ho sakta",
    ),
    "generic-masters.steps.2.label": ("Approved / Active", "अनुमोदित / सक्रिय", "मंजूर / सक्रिय", "Approved / Active"),
    "generic-masters.steps.2.caption": (
        "A different user approves it — now selectable tenant-wide",
        "कोई अलग user इसे अनुमोदित करता है — अब यह पूरे tenant में चुना जा सकता है",
        "एक वेगळा user याला मंजुरी देतो — आता हे संपूर्ण tenant मध्ये निवडता येते",
        "Koi alag user isse approve karta hai — ab ye pure tenant mein select ho sakta hai",
    ),
    "generic-masters.steps.3.label": (
        "Deactivate or Deprecate",
        "निष्क्रिय करें या अप्रचलित करें",
        "निष्क्रिय करा किंवा अप्रचलित करा",
        "Deactivate ya Deprecate",
    ),
    "generic-masters.steps.3.caption": (
        "Toggle off temporarily, or archive permanently",
        "अस्थायी रूप से बंद करें, या स्थायी रूप से आर्काइव करें",
        "तात्पुरते बंद करा, किंवा कायमचे आर्काइव्ह करा",
        "Temporarily toggle off karein, ya permanently archive karein",
    ),
    "generic-masters.fieldRules.0.name": ("Master Table", "मास्टर टेबल", "मास्टर टेबल", "Master Table"),
    "generic-masters.fieldRules.0.description": (
        "Which of the generic registries you're editing — every action (create, approve, deactivate, deprecate) applies to this table only.",
        "आप कौन-सी generic registry edit कर रहे हैं — हर action (create, approve, deactivate, deprecate) सिर्फ़ इसी table पर लागू होता है।",
        "तुम्ही कोणती generic registry edit करत आहात — प्रत्येक action (create, approve, deactivate, deprecate) फक्त याच table वर लागू होते.",
        "Aap kaunsi generic registry edit kar rahe hain — har action (create, approve, deactivate, deprecate) sirf isi table par apply hota hai.",
    ),
    "generic-masters.fieldRules.1.name": ("Code", "कोड", "कोड", "Code"),
    "generic-masters.fieldRules.1.description": (
        "Unique identifier within the table. Locked and un-editable once the record is created.",
        "table के भीतर अद्वितीय पहचानकर्ता। Record बनने के बाद यह लॉक हो जाता है और एडिट नहीं किया जा सकता।",
        "table मधील अद्वितीय ओळखकर्ता. Record तयार झाल्यावर हे लॉक होते आणि एडिट करता येत नाही.",
        "Table ke andar unique identifier hai. Record create hone ke baad ye lock ho jaata hai aur edit nahi kiya ja sakta.",
    ),
    "generic-masters.fieldRules.2.name": ("Name", "नाम", "नाव", "Name"),
    "generic-masters.fieldRules.2.description": (
        "Display name — the only field the Yup schema requires besides Code.",
        "प्रदर्शित नाम — Code के अलावा Yup schema में यही एकमात्र आवश्यक फ़ील्ड है।",
        "प्रदर्शित नाव — Code व्यतिरिक्त Yup schema मध्ये आवश्यक असलेले हे एकमेव फील्ड आहे.",
        "Display name — Code ke alawa Yup schema mein bas yahi field required hai.",
    ),
    "generic-masters.fieldRules.3.name": ("Description", "विवरण", "वर्णन", "Description"),
    "generic-masters.fieldRules.3.description": (
        "Optional free text; shown as \"-\" in the table when left blank.",
        "वैकल्पिक free text; खाली छोड़ने पर table में \"-\" के रूप में दिखाया जाता है।",
        "ऐच्छिक free text; रिकामे ठेवल्यास table मध्ये \"-\" असे दाखवले जाते.",
        "Optional free text hai; blank chhodne par table mein \"-\" dikhta hai.",
    ),
    "generic-masters.fieldRules.4.name": ("Status", "स्थिति", "स्थिती", "Status"),
    "generic-masters.fieldRules.4.description": (
        "Derived, not editable: Inactive wins over a stale Active status after Deactivate; Deprecated always wins; soft-deleted rows disappear from the list entirely instead of showing a status.",
        "यह derived है, editable नहीं: Deactivate के बाद Inactive, पुरानी Active status पर हावी रहता है; Deprecated हमेशा सबसे ऊपर रहता है; soft-deleted rows किसी status को दिखाने के बजाय सूची से पूरी तरह गायब हो जाती हैं।",
        "हे derived आहे, editable नाही: Deactivate केल्यानंतर Inactive, जुन्या Active status वर वरचढ ठरते; Deprecated नेहमी सर्वांत वरचढ असते; soft-deleted rows स्थिती दाखवण्याऐवजी यादीतून पूर्णपणे नाहीशा होतात.",
        "Ye derived hai, editable nahi hai: Deactivate ke baad Inactive, purani Active status ko override kar deta hai; Deprecated hamesha sabse upar rehta hai; soft-deleted rows koi status dikhane ke bajaye list se poori tarah gayab ho jaati hain.",
    ),
    "generic-masters.tip.title": (
        "You won't see Approve on your own records",
        "आपको अपने खुद के records पर Approve नहीं दिखेगा",
        "तुम्हाला तुमच्या स्वतःच्या records वर Approve दिसणार नाही",
        "Apne khud ke records par aapko Approve nahi dikhega",
    ),
    "generic-masters.tip.body": (
        "Maker-checker (GFR Rule 21) hides the Approve button on any record you created, even if you hold master:approve — the backend rejects self-approval anyway. Get a second user to approve it, or check the Approval Queue.",
        "Maker-checker (GFR Rule 21) आपके बनाए किसी भी record पर Approve बटन छुपा देता है, भले ही आपके पास master:approve हो — backend वैसे भी self-approval को reject कर देता है। किसी दूसरे user से इसे approve करवाएं, या Approval Queue देखें।",
        "Maker-checker (GFR Rule 21) तुम्ही तयार केलेल्या कोणत्याही record वर Approve बटण लपवते, जरी तुमच्याकडे master:approve असले तरी — backend कोणत्याही परिस्थितीत self-approval नाकारते. दुसऱ्या user कडून ते approve करून घ्या, किंवा Approval Queue तपासा.",
        "Maker-checker (GFR Rule 21) aapke banaye kisi bhi record par Approve button hide kar deta hai, chahe aapke paas master:approve ho — backend waise bhi self-approval reject kar deta hai. Kisi doosre user se ise approve karwao, ya Approval Queue check karo.",
    ),
}


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 GENERIC_MASTERS.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(GENERIC_MASTERS)} generic-masters keys.")


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