"""One-off seed: registers translation_keys English source_text and hi/mr/hinglish
translation_values for the "assets-create" (Create/Edit Asset) PageInfoButton content.

Usage: docker compose exec api python seed_translations_pageinfo_assets_create.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)
ASSETS_CREATE = {
    "assets-create.title": (
        "Create / Edit Asset",
        "Asset बनाएं / संपादित करें",
        "Asset तयार करा / संपादित करा",
        "Asset Create / Edit karein",
    ),
    "assets-create.subtitle": (
        "Register a new asset, or update an existing one",
        "नई asset रजिस्टर करें, या किसी मौजूदा को अपडेट करें",
        "नवीन asset नोंदणी करा, किंवा विद्यमान असेट अपडेट करा",
        "Naya asset register karein, ya kisi existing asset ko update karein",
    ),
    "assets-create.body.0": (
        "This form writes directly to the enterprise Asset Register — every field here maps to a column on the backend asset record, so nothing typed here is cosmetic.",
        "यह फ़ॉर्म सीधे enterprise Asset Register में लिखता है — यहाँ हर फ़ील्ड backend asset record के किसी column से मैप होती है, इसलिए यहाँ टाइप की गई कोई भी चीज़ केवल दिखावटी नहीं है।",
        "हा फॉर्म थेट enterprise Asset Register मध्ये लिहितो — येथील प्रत्येक फील्ड backend asset record मधील एका column शी जोडलेली असते, त्यामुळे येथे टाइप केलेली कोणतीही गोष्ट केवळ दिखाव्यासाठी नाही.",
        "Ye form directly enterprise Asset Register mein likhta hai — yahan har field backend asset record ke ek column se map hoti hai, isliye yahan type ki gayi koi bhi cheez sirf cosmetic nahi hai.",
    ),
    "assets-create.body.1": (
        "Picking an Asset Class first unlocks Category and Sub-Category; picking a Purchase Order or Budget Line here links this asset's cost to procurement and budget tracking.",
        "पहले Asset Class चुनने से Category और Sub-Category अनलॉक होती हैं; यहाँ Purchase Order या Budget Line चुनने से इस asset की cost, procurement और budget tracking से जुड़ जाती है।",
        "प्रथम Asset Class निवडल्यास Category आणि Sub-Category अनलॉक होतात; येथे Purchase Order किंवा Budget Line निवडल्यास या asset ची cost procurement आणि budget tracking शी जोडली जाते.",
        "Pehle Asset Class select karne se Category aur Sub-Category unlock hoti hain; yahan Purchase Order ya Budget Line select karne se is asset ki cost procurement aur budget tracking se link ho jaati hai.",
    ),
    "assets-create.stepsHeading": (
        "How the form is organized",
        "फ़ॉर्म कैसे व्यवस्थित है",
        "फॉर्म कसा आयोजित केला आहे",
        "Form kaise organize kiya gaya hai",
    ),
    "assets-create.steps.0.label": ("Basic Information", "बुनियादी जानकारी", "मूलभूत माहिती", "Basic Information"),
    "assets-create.steps.0.caption": (
        "Name and Asset Class — choosing a class reveals Category/Sub-Category and a valuation badge",
        "Name और Asset Class — class चुनने पर Category/Sub-Category और एक valuation badge दिखाई देता है",
        "Name आणि Asset Class — class निवडल्यावर Category/Sub-Category आणि एक valuation badge दिसतो",
        "Name aur Asset Class — class select karne par Category/Sub-Category aur ek valuation badge dikhta hai",
    ),
    "assets-create.steps.1.label": ("Identification", "पहचान", "ओळख", "Identification"),
    "assets-create.steps.1.caption": (
        "Serial number, model, manufacturer — all optional",
        "Serial number, model, manufacturer — सभी वैकल्पिक",
        "Serial number, model, manufacturer — सर्व ऐच्छिक",
        "Serial number, model, manufacturer — sab optional hain",
    ),
    "assets-create.steps.2.label": ("Financial Details", "वित्तीय विवरण", "आर्थिक तपशील", "Financial Details"),
    "assets-create.steps.2.caption": (
        "Cost, acquisition date, Funding Source, and optional PO / Budget Line linkage",
        "Cost, acquisition date, Funding Source, और वैकल्पिक PO / Budget Line लिंकेज",
        "Cost, acquisition date, Funding Source, आणि ऐच्छिक PO / Budget Line लिंकेज",
        "Cost, acquisition date, Funding Source, aur optional PO / Budget Line linkage",
    ),
    "assets-create.steps.3.label": ("Location & Ownership", "स्थान और स्वामित्व", "स्थान आणि मालकी", "Location & Ownership"),
    "assets-create.steps.3.caption": (
        "Physical location, Org Unit, and any useful-life override",
        "भौतिक location, Org Unit, और कोई भी useful-life override",
        "भौतिक location, Org Unit, आणि कोणताही useful-life override",
        "Physical location, Org Unit, aur koi bhi useful-life override",
    ),
    "assets-create.steps.4.label": ("Save", "सहेजें", "जतन करा", "Save"),
    "assets-create.steps.4.caption": (
        "Create adds it to the register; edit updates the existing asset in place",
        "Create इसे register में जोड़ता है; edit मौजूदा asset को उसी जगह अपडेट करता है",
        "Create ते register मध्ये जोडते; edit विद्यमान असेट त्याच ठिकाणी अपडेट करते",
        "Create ise register mein add karta hai; edit existing asset ko wahin update kar deta hai",
    ),
    "assets-create.fieldRules.0.name": ("Name", "Name", "Name", "Name"),
    "assets-create.fieldRules.0.description": (
        "Free-text label shown in the register and search — required.",
        "Register और search में दिखाया जाने वाला free-text लेबल — आवश्यक।",
        "Register आणि search मध्ये दाखवला जाणारा free-text लेबल — आवश्यक.",
        "Register aur search mein dikhne wala free-text label — required hai.",
    ),
    "assets-create.fieldRules.1.name": ("Asset Class", "Asset Class", "Asset Class", "Asset Class"),
    "assets-create.fieldRules.1.description": (
        "Drives the Category/Sub-Category options and shows whether the class typically depreciates, appreciates, or is held static.",
        "यह Category/Sub-Category के विकल्प तय करता है और दिखाता है कि class सामान्यतः depreciate होती है, appreciate होती है, या static रहती है।",
        "हे Category/Sub-Category चे पर्याय ठरवते आणि class साधारणपणे depreciate होते, appreciate होते, की static राहते हे दाखवते.",
        "Ye Category/Sub-Category ke options decide karta hai aur dikhata hai ki class generally depreciate hoti hai, appreciate hoti hai, ya static rehti hai.",
    ),
    "assets-create.fieldRules.2.name": ("Acquisition Cost", "Acquisition Cost", "Acquisition Cost", "Acquisition Cost"),
    "assets-create.fieldRules.2.description": (
        "Must be greater than 0. If a Budget Line is selected, exceeding its available amount still lets you save — it's only flagged as over-budget.",
        "0 से अधिक होना चाहिए। यदि कोई Budget Line चुनी गई है, तो उसकी available amount से अधिक होने पर भी आप save कर सकते हैं — इसे केवल over-budget के रूप में फ्लैग किया जाता है।",
        "0 पेक्षा जास्त असणे आवश्यक आहे. जर एखादी Budget Line निवडली असेल, तर तिच्या available amount पेक्षा जास्त असले तरीही तुम्ही save करू शकता — ते फक्त over-budget म्हणून फ्लॅग केले जाते.",
        "0 se zyada hona chahiye. Agar koi Budget Line select ki gayi hai, to uski available amount se zyada hone par bhi aap save kar sakte hain — ise sirf over-budget flag kiya jaata hai.",
    ),
    "assets-create.fieldRules.3.name": ("Funding Source", "Funding Source", "Funding Source", "Funding Source"),
    "assets-create.fieldRules.3.description": (
        "Must be picked from the active Funding Source master; free text is not accepted.",
        "इसे active Funding Source master से ही चुना जाना चाहिए; free text स्वीकार नहीं किया जाता।",
        "हे active Funding Source master मधूनच निवडणे आवश्यक आहे; free text स्वीकारला जात नाही.",
        "Isse active Funding Source master se hi select karna hoga; free text accept nahi hota.",
    ),
    "assets-create.fieldRules.4.name": (
        "Purchase Order / Budget Line",
        "Purchase Order / Budget Line",
        "Purchase Order / Budget Line",
        "Purchase Order / Budget Line",
    ),
    "assets-create.fieldRules.4.description": (
        "Both optional. Selecting a PO that already carries its own budget overrides and locks the Budget Line to that PO's budget.",
        "दोनों वैकल्पिक हैं। ऐसा PO चुनने पर जिसका अपना budget पहले से जुड़ा हो, यह Budget Line को override करके उस PO के budget पर लॉक कर देता है।",
        "दोन्ही ऐच्छिक आहेत. ज्या PO चा स्वतःचा budget आधीच जोडलेला आहे तो निवडल्यास, ते Budget Line ला override करून त्या PO च्या budget वर लॉक करते.",
        "Dono optional hain. Agar aap aisa PO select karte hain jiska apna budget pehle se attached hai, to ye Budget Line ko override karke us PO ke budget par lock kar deta hai.",
    ),
    "assets-create.tip.title": (
        "PO budgets override manual picks",
        "PO budgets मैन्युअल चयन को override कर देते हैं",
        "PO budgets मॅन्युअल निवडीला override करतात",
        "PO budgets manual picks ko override kar dete hain",
    ),
    "assets-create.tip.body": (
        "If the selected Purchase Order already has a budget attached, it silently takes over and locks the Budget Line field — you can't pick a different budget while that PO stays selected. Clear the PO first if you need a different budget.",
        "यदि selected Purchase Order से पहले से कोई budget जुड़ा है, तो यह चुपचाप उसे ले लेता है और Budget Line फ़ील्ड को लॉक कर देता है — जब तक वह PO चयनित रहता है, आप कोई दूसरा budget नहीं चुन सकते। यदि आपको कोई अलग budget चाहिए तो पहले PO को clear करें।",
        "जर निवडलेल्या Purchase Order ला आधीच एखादा budget जोडलेला असेल, तर ते शांतपणे ताबा घेते आणि Budget Line फील्ड लॉक करते — तो PO निवडलेला असेपर्यंत तुम्ही वेगळा budget निवडू शकत नाही. वेगळा budget हवा असल्यास आधी PO clear करा.",
        "Agar selected Purchase Order ke saath pehle se koi budget attached hai, to ye silently usse le leta hai aur Budget Line field ko lock kar deta hai — jab tak wo PO selected rehta hai, aap koi alag budget select nahi kar sakte. Agar alag budget chahiye to pehle PO clear 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 ASSETS_CREATE.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(ASSETS_CREATE)} assets-create keys.")


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