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

Usage: docker compose exec api python seed_translations_pageinfo_org_units.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)
ORG_UNITS = {
    "org-units.title": (
        "Organisation Units Master",
        "ऑर्गनाइज़ेशन यूनिट्स मास्टर",
        "ऑर्गनायझेशन युनिट्स मास्टर",
        "Organisation Units Master",
    ),
    "org-units.subtitle": (
        "Departments, branches and divisions — the tree assets and custodians are scoped to",
        "विभाग, शाखाएँ और डिवीज़न — वह tree जिसके अंतर्गत assets और custodians scope किए जाते हैं",
        "विभाग, शाखा आणि विभागणी — ते tree ज्याअंतर्गत assets आणि custodians scope केले जातात",
        "Departments, branches aur divisions — wo tree jiske andar assets aur custodians scope kiye jaate hain",
    ),
    "org-units.body.0": (
        "Manage the organisation's department and unit hierarchy — create, edit, and organise every unit from here.",
        "संगठन की department और unit hierarchy को यहाँ से manage करें — हर unit को यहीं से create, edit और organise करें।",
        "संस्थेच्या department आणि unit hierarchy चे इथून व्यवस्थापन करा — प्रत्येक unit इथूनच create, edit आणि organise करा.",
        "Organisation ki department aur unit hierarchy yahan se manage karein — har unit ko yahin se create, edit aur organise karein.",
    ),
    "org-units.body.1": (
        "Every asset, custodian and approval is scoped to an org unit, so this structure should mirror your real org chart before you start creating assets or users.",
        "हर asset, custodian और approval किसी org unit के दायरे में scope होती है, इसलिए assets या users बनाना शुरू करने से पहले यह structure आपके वास्तविक org chart जैसा ही होना चाहिए।",
        "प्रत्येक asset, custodian आणि approval एखाद्या org unit च्या कक्षेत scope केलेली असते, त्यामुळे assets किंवा users तयार करण्यापूर्वी हे structure तुमच्या प्रत्यक्ष org chart सारखेच असावे.",
        "Har asset, custodian aur approval kisi org unit ke andar scope hoti hai, isliye assets ya users create karna shuru karne se pehle ye structure aapke real org chart jaisa hi hona chahiye.",
    ),
    "org-units.stepsHeading": (
        "Approval lifecycle",
        "अनुमोदन जीवनचक्र",
        "मान्यता जीवनचक्र",
        "Approval lifecycle",
    ),
    "org-units.steps.0.label": ("Create", "बनाएँ", "तयार करा", "Create"),
    "org-units.steps.0.caption": (
        "New unit saves as Pending Approval",
        "नया unit Pending Approval के रूप में save होता है",
        "नवीन unit Pending Approval म्हणून save होते",
        "Naya unit Pending Approval status mein save hota hai",
    ),
    "org-units.steps.1.label": ("Approve", "अनुमोदित करें", "मान्यता द्या", "Approve"),
    "org-units.steps.1.caption": (
        "A different user approves it — maker-checker (GFR Rule 21)",
        "कोई अन्य user इसे approve करता है — maker-checker (GFR Rule 21)",
        "दुसरा user तो approve करतो — maker-checker (GFR Rule 21)",
        "Koi doosra user ise approve karta hai — maker-checker (GFR Rule 21)",
    ),
    "org-units.steps.2.label": ("Active", "सक्रिय", "सक्रिय", "Active"),
    "org-units.steps.2.caption": (
        "Unit is live and usable across the system",
        "Unit live हो जाता है और पूरे system में उपयोग योग्य होता है",
        "Unit live होते आणि संपूर्ण system मध्ये वापरण्यायोग्य असते",
        "Unit live ho jaata hai aur pure system mein usable hota hai",
    ),
    "org-units.steps.3.label": ("Dissolve", "भंग करें", "विसर्जित करा", "Dissolve"),
    "org-units.steps.3.caption": (
        "Soft-delete; can be restored anytime",
        "Soft-delete; कभी भी restore किया जा सकता है",
        "Soft-delete; कधीही restore करता येते",
        "Soft-delete hota hai; kabhi bhi restore kiya ja sakta hai",
    ),
    "org-units.steps.4.label": ("Delete", "हटाएँ", "हटवा", "Delete"),
    "org-units.steps.4.caption": (
        "Hard delete — only offered once dissolved, irreversible",
        "Hard delete — केवल dissolved होने के बाद ही उपलब्ध, अपरिवर्तनीय",
        "Hard delete — फक्त dissolved झाल्यावरच उपलब्ध, अपरिवर्तनीय",
        "Hard delete hota hai — sirf dissolved hone ke baad hi available, ye irreversible hai",
    ),
    "org-units.fieldRules.0.name": ("Unit Name", "यूनिट नाम", "युनिट नाव", "Unit Name"),
    "org-units.fieldRules.0.description": (
        "Display name of the unit, e.g. Finance Department.",
        "unit का display name, जैसे Finance Department।",
        "unit चे display name, उदा. Finance Department.",
        "Unit ka display name, jaise Finance Department.",
    ),
    "org-units.fieldRules.1.name": ("Client Type", "क्लाइंट टाइप", "क्लायंट टाईप", "Client Type"),
    "org-units.fieldRules.1.description": (
        "Government or Enterprise — determines which Org Unit Type options are available.",
        "Government या Enterprise — यह तय करता है कि कौन-से Org Unit Type विकल्प उपलब्ध होंगे।",
        "Government किंवा Enterprise — हे ठरवते की कोणते Org Unit Type पर्याय उपलब्ध असतील.",
        "Government ya Enterprise — ye decide karta hai ki kaunse Org Unit Type options available honge.",
    ),
    "org-units.fieldRules.2.name": ("Org Unit Type", "ऑर्ग यूनिट टाइप", "ऑर्ग युनिट टाईप", "Org Unit Type"),
    "org-units.fieldRules.2.description": (
        "e.g. department, division, cpse — resets when Client Type changes.",
        "जैसे department, division, cpse — Client Type बदलने पर यह reset हो जाता है।",
        "उदा. department, division, cpse — Client Type बदलल्यावर हे reset होते.",
        "Jaise department, division, cpse — Client Type change hone par ye reset ho jaata hai.",
    ),
    "org-units.fieldRules.3.name": ("Parent Unit", "पैरेंट यूनिट", "पॅरेंट युनिट", "Parent Unit"),
    "org-units.fieldRules.3.description": (
        "Where this unit sits in the tree; leave blank only for a top-level unit.",
        "यह unit tree में कहाँ स्थित है; केवल top-level unit के लिए इसे खाली छोड़ें।",
        "हे unit tree मध्ये कुठे आहे; फक्त top-level unit साठी हे रिकामे ठेवा.",
        "Ye unit tree mein kahan hai; sirf top-level unit ke liye ise blank chhodein.",
    ),
    "org-units.fieldRules.4.name": ("Cost Centre Code", "कॉस्ट सेंटर कोड", "कॉस्ट सेंटर कोड", "Cost Centre Code"),
    "org-units.fieldRules.4.description": (
        "Optional finance code; also searchable from this list's search box.",
        "वैकल्पिक finance code; इस list के search box से भी खोजा जा सकता है।",
        "पर्यायी finance code; या list च्या search box मधून देखील शोधता येते.",
        "Optional finance code hai; is list ke search box se bhi search kiya ja sakta hai.",
    ),
    "org-units.tip.title": (
        "You can't approve your own unit",
        "आप अपने खुद के unit को approve नहीं कर सकते",
        "तुम्ही स्वतःच्या unit ला approve करू शकत नाही",
        "Aap apne khud ke unit ko approve nahi kar sakte",
    ),
    "org-units.tip.body": (
        "If you created a pending unit, the Approve button is hidden for you even with ou:approve — a different authorised user must approve it. Dissolve is reversible (Restore); permanent delete only appears after a unit is already dissolved.",
        "अगर आपने कोई pending unit बनाई है, तो ou:approve होने पर भी आपके लिए Approve button छिपा रहता है — किसी अन्य authorised user को ही इसे approve करना होगा। Dissolve reversible है (Restore); permanent delete केवल तभी दिखता है जब unit पहले से dissolved हो।",
        "जर तुम्ही एखादी pending unit तयार केली असेल, तर ou:approve असूनही तुमच्यासाठी Approve button लपलेले असते — दुसऱ्या authorised user लाच ती approve करावी लागेल. Dissolve reversible आहे (Restore); permanent delete फक्त unit आधीच dissolved असल्यावरच दिसते.",
        "Agar aapne koi pending unit banayi hai, to ou:approve hone ke bawajood aapke liye Approve button hidden rehta hai — kisi doosre authorised user ko hi ise approve karna hoga. Dissolve reversible hai (Restore); permanent delete tabhi dikhta hai jab unit already dissolved ho.",
    ),
}


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 ORG_UNITS.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(ORG_UNITS)} org-units keys.")


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