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

Usage: docker compose exec api python seed_translations_pageinfo_inventory_allocations.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)
INVENTORY_ALLOCATIONS = {
    "inventory-allocations.title": (
        "Inventory Allocations",
        "इन्वेंटरी आवंटन",
        "इन्व्हेंटरी वाटप",
        "Inventory Allocations",
    ),
    "inventory-allocations.subtitle": (
        "Issue stock to a user and track when it comes back",
        "किसी उपयोगकर्ता को स्टॉक जारी करें और ट्रैक करें कि यह कब वापस आता है",
        "एखाद्या वापरकर्त्याला स्टॉक जारी करा आणि तो कधी परत येतो ते ट्रॅक करा",
        "Kisi user ko stock issue karein aur track karein ki wo kab wapas aata hai",
    ),
    "inventory-allocations.body.0": (
        "Track inventory items allocated to a user, capped at each item's available stock.",
        "किसी उपयोगकर्ता को आवंटित इन्वेंटरी आइटम को ट्रैक करें, जो प्रत्येक आइटम के उपलब्ध स्टॉक तक सीमित होते हैं।",
        "एखाद्या वापरकर्त्याला वाटप केलेल्या इन्व्हेंटरी आयटमचा मागोवा घ्या, जे प्रत्येक आयटमच्या उपलब्ध स्टॉकपर्यंत मर्यादित असतात.",
        "User ko allocate kiye gaye inventory items ko track karein, jo har item ke available stock tak capped hote hain.",
    ),
    "inventory-allocations.body.1": (
        "Each row is one issue transaction: an item, a quantity, and who it went to. It stays Active until a return is recorded, which fills in the Returned date.",
        "प्रत्येक row एक issue transaction है: एक item, एक quantity, और यह किसे दी गई। जब तक कोई return दर्ज नहीं होता, यह Active बनी रहती है, जिससे Returned date भर जाती है।",
        "प्रत्येक row म्हणजे एक issue transaction आहे: एक item, एक quantity, आणि ती कोणाला दिली गेली. जोपर्यंत एखादा return नोंदवला जात नाही तोपर्यंत ती Active राहते, ज्यामुळे Returned date भरली जाते.",
        "Har row ek issue transaction hai: ek item, ek quantity, aur ye kisko gaya. Jab tak return record nahi hota, ye Active rehti hai, jisse Returned date fill ho jaati hai.",
    ),
    "inventory-allocations.stepsHeading": (
        "How an allocation is recorded",
        "आवंटन कैसे दर्ज किया जाता है",
        "वाटप कसे नोंदवले जाते",
        "Allocation kaise record hota hai",
    ),
    "inventory-allocations.steps.0.label": ("Select Item", "आइटम चुनें", "आयटम निवडा", "Select Item"),
    "inventory-allocations.steps.0.caption": (
        "Loads its live stock",
        "इसका लाइव स्टॉक लोड करता है",
        "त्याचा लाइव्ह स्टॉक लोड करते",
        "Iska live stock load karta hai",
    ),
    "inventory-allocations.steps.1.label": ("Check Stock", "स्टॉक जाँचें", "स्टॉक तपासा", "Check Stock"),
    "inventory-allocations.steps.1.caption": (
        "On-hand minus reserved",
        "On-hand माइनस reserved",
        "On-hand वजा reserved",
        "On-hand minus reserved",
    ),
    "inventory-allocations.steps.2.label": ("Choose User", "उपयोगकर्ता चुनें", "वापरकर्ता निवडा", "Choose User"),
    "inventory-allocations.steps.2.caption": (
        "From inventory candidates",
        "इन्वेंटरी candidates में से",
        "इन्व्हेंटरी candidates मधून",
        "Inventory candidates mein se",
    ),
    "inventory-allocations.steps.3.label": ("Set Quantity", "मात्रा सेट करें", "प्रमाण सेट करा", "Set Quantity"),
    "inventory-allocations.steps.3.caption": (
        "Capped at available",
        "उपलब्ध मात्रा तक सीमित",
        "उपलब्ध प्रमाणापर्यंत मर्यादित",
        "Available tak capped",
    ),
    "inventory-allocations.steps.4.label": ("Active / Returned", "Active / Returned", "Active / Returned", "Active / Returned"),
    "inventory-allocations.steps.4.caption": (
        "Flips on return date",
        "Return date पर बदल जाता है",
        "Return date वर बदलते",
        "Return date par flip ho jaata hai",
    ),
    "inventory-allocations.fieldRules.0.name": ("Item", "आइटम", "आयटम", "Item"),
    "inventory-allocations.fieldRules.0.description": (
        "Item being allocated; selecting it fetches its current available-to-allocate stock.",
        "जो आइटम आवंटित की जा रही है; इसे चुनने पर इसका मौजूदा available-to-allocate स्टॉक प्राप्त होता है।",
        "जी आयटम वाटप केली जात आहे; ती निवडल्यावर तिचा सध्याचा available-to-allocate स्टॉक मिळतो.",
        "Jo item allocate ki ja rahi hai; ise select karne par iska current available-to-allocate stock fetch hota hai.",
    ),
    "inventory-allocations.fieldRules.1.name": (
        "Allocated To (User)",
        "आवंटित किया गया (उपयोगकर्ता)",
        "वाटप केले (वापरकर्ता)",
        "Allocated To (User)",
    ),
    "inventory-allocations.fieldRules.1.description": (
        "Employee receiving the stock, picked from the inventory-scoped candidate list.",
        "स्टॉक प्राप्त करने वाला employee, जिसे inventory-scoped candidate list में से चुना जाता है।",
        "स्टॉक प्राप्त करणारा employee, जो inventory-scoped candidate list मधून निवडला जातो.",
        "Stock receive karne wala employee, jo inventory-scoped candidate list mein se pick kiya jaata hai.",
    ),
    "inventory-allocations.fieldRules.2.name": ("Quantity", "मात्रा", "प्रमाण", "Quantity"),
    "inventory-allocations.fieldRules.2.description": (
        "Must not exceed available stock (on-hand minus reserved) — Allocate stays disabled otherwise.",
        "उपलब्ध स्टॉक (on-hand माइनस reserved) से अधिक नहीं होनी चाहिए — अन्यथा Allocate बटन disabled रहता है।",
        "उपलब्ध स्टॉक (on-hand वजा reserved) पेक्षा जास्त नसावे — अन्यथा Allocate बटण disabled राहते.",
        "Available stock (on-hand minus reserved) se zyada nahi honi chahiye — warna Allocate button disabled rehta hai.",
    ),
    "inventory-allocations.fieldRules.3.name": ("Returned", "Returned", "Returned", "Returned"),
    "inventory-allocations.fieldRules.3.description": (
        "Blank and shown as Active until a return date is recorded for the allocation.",
        "जब तक आवंटन के लिए कोई return date दर्ज नहीं होती, यह खाली रहती है और Active दिखाई देती है।",
        "जोपर्यंत वाटपासाठी return date नोंदवली जात नाही, तोपर्यंत हे रिकामे राहते आणि Active दाखवले जाते.",
        "Jab tak allocation ke liye return date record nahi hoti, ye blank rehta hai aur Active dikhta hai.",
    ),
    "inventory-allocations.tip.title": (
        "Allocated-to list empty?",
        "Allocated-to लिस्ट खाली है?",
        "Allocated-to यादी रिकामी आहे?",
        "Allocated-to list empty hai?",
    ),
    "inventory-allocations.tip.body": (
        "The picker only lists inventory-scoped candidate users, not the full admin user directory — an empty list usually means your role has no visible candidates, not that no users exist.",
        "यह picker केवल inventory-scoped candidate users को सूचीबद्ध करता है, पूरी admin user directory को नहीं — खाली लिस्ट का आमतौर पर मतलब है कि आपकी role के लिए कोई candidate दिखाई नहीं देता, यह नहीं कि कोई उपयोगकर्ता मौजूद नहीं है।",
        "हा picker फक्त inventory-scoped candidate users सूचीबद्ध करतो, संपूर्ण admin user directory नाही — रिकामी यादीचा साधारणपणे अर्थ असा होतो की तुमच्या role साठी कोणतेही candidates दृश्यमान नाहीत, कोणतेही users अस्तित्वात नाहीत असे नाही.",
        "Ye picker sirf inventory-scoped candidate users list karta hai, poori admin user directory nahi — empty list ka usually matlab hota hai ki aapki role ke liye koi candidate visible nahi hai, ye nahi ki koi user exist nahi karta.",
    ),
}


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 INVENTORY_ALLOCATIONS.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(INVENTORY_ALLOCATIONS)} inventory-allocations keys.")


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