"""One-off seed: registers translation_keys English source_text and hi/mr/hinglish
translation_values for 87 "app"-namespace UI strings (asset rental agreements,
meter readings, verification requests, asset creation form, budget allocation)
that are already wrapped in t(key, englishFallback) calls in the frontend but
were never seeded — so hi/mr/hinglish users have been seeing raw English.

Usage: docker compose exec api python seed_translations_gap_batch1_assets.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 = "app"

# key -> (english, hi, mr, hinglish)
GAP_BATCH1_ASSETS = {
    "assets.common.purchaseOrder": (
        "Purchase Order",
        "परचेज़ ऑर्डर",
        "परचेज़ ऑर्डर",
        "Purchase Order",
    ),
    "assets.create.available": (
        "available",
        "उपलब्ध",
        "उपलब्ध",
        "available",
    ),
    "assets.create.budgetActual": (
        "Actual spent",
        "वास्तविक व्यय",
        "प्रत्यक्ष खर्च",
        "Actual spent",
    ),
    "assets.create.budgetApproved": (
        "Approved",
        "स्वीकृत",
        "मंजूर",
        "Approved",
    ),
    "assets.create.budgetAvailable": (
        "Available",
        "उपलब्ध",
        "उपलब्ध",
        "Available",
    ),
    "assets.create.budgetCommitted": (
        "Committed",
        "प्रतिबद्ध",
        "वचनबद्ध",
        "Committed",
    ),
    "assets.create.budgetFromPO": (
        "Inherited from the selected purchase order.",
        "चयनित परचेज़ ऑर्डर से इनहेरिट किया गया।",
        "निवडलेल्या परचेज़ ऑर्डरवरून इनहेरिट केले आहे.",
        "Selected purchase order se inherit hota hai.",
    ),
    "assets.create.budgetLine": (
        "Budget Line (optional)",
        "बजट लाइन (वैकल्पिक)",
        "बजट लाइन (ऐच्छिक)",
        "Budget Line (optional)",
    ),
    "assets.create.overBudgetWarn": (
        "This asset's cost exceeds the remaining budget — you can still save (it will show as over-budget in reports).",
        "इस asset की लागत शेष बजट से अधिक है — आप फिर भी सेव कर सकते हैं (यह reports में over-budget के रूप में दिखेगा)।",
        "या asset ची किंमत उर्वरित बजटपेक्षा जास्त आहे — तरीही तुम्ही सेव करू शकता (हे reports मध्ये over-budget म्हणून दिसेल).",
        "Is asset ki cost bache hue budget se zyada hai — aap fir bhi save kar sakte hain (ye reports mein over-budget dikhega).",
    ),
    "assets.create.purchaseOrder": (
        "Purchase Order (optional)",
        "परचेज़ ऑर्डर (वैकल्पिक)",
        "परचेज़ ऑर्डर (ऐच्छिक)",
        "Purchase Order (optional)",
    ),
    "assets.create.rentalAsset": (
        "Rental Asset — this asset is rented out to an external party",
        "किराया asset — यह asset किसी बाहरी पक्ष को किराए पर दिया गया है",
        "भाडे asset — ही asset एखाद्या बाह्य पक्षाला भाड्याने दिली आहे",
        "Rental asset — ye asset kisi external party ko rent par diya gaya hai",
    ),
    "assets.detail.field.budgetLine": (
        "Budget Line",
        "बजट लाइन",
        "बजट लाइन",
        "Budget Line",
    ),
    "assets.detail.field.purchaseOrder": (
        "Purchase Order",
        "परचेज़ ऑर्डर",
        "परचेज़ ऑर्डर",
        "Purchase Order",
    ),
    "assets.detail.requestVerification": (
        "Request Verification",
        "सत्यापन अनुरोध करें",
        "पडताळणी विनंती करा",
        "Verification request karein",
    ),
    "assets.detail.tab.rental": (
        "Rental",
        "किराया",
        "भाडे",
        "Rental",
    ),
    "assets.list.allPurchaseOrders": (
        "All Purchase Orders",
        "सभी परचेज़ ऑर्डर",
        "सर्व परचेज़ ऑर्डर",
        "Sabhi Purchase Orders",
    ),
    "assets.meter.addReading": (
        "Add Reading",
        "रीडिंग जोड़ें",
        "रीडिंग जोडा",
        "Reading add karein",
    ),
    "assets.meter.empty": (
        "No meter readings recorded",
        "कोई मीटर रीडिंग दर्ज नहीं है",
        "कोणतीही मीटर रीडिंग नोंदवलेली नाही",
        "Koi meter reading record nahi hui",
    ),
    "assets.meter.loading": (
        "Loading readings...",
        "रीडिंग लोड हो रही हैं...",
        "रीडिंग लोड होत आहेत...",
        "Readings load ho rahi hain...",
    ),
    "assets.meter.meterType": (
        "Meter Type",
        "मीटर प्रकार",
        "मीटर प्रकार",
        "Meter Type",
    ),
    "assets.meter.meterTypePh": (
        "e.g. odometer",
        "जैसे odometer",
        "उदा. odometer",
        "jaise odometer",
    ),
    "assets.meter.recordedAt": (
        "Recorded At",
        "दर्ज समय",
        "नोंदवलेली वेळ",
        "Recorded At",
    ),
    "assets.meter.recordedBy": (
        "Recorded By",
        "दर्ज करने वाला",
        "नोंदवणारा",
        "Recorded By",
    ),
    "assets.meter.recording": (
        "Recording...",
        "रिकॉर्ड हो रहा है...",
        "रेकॉर्ड होत आहे...",
        "Record ho raha hai...",
    ),
    "assets.meter.value": (
        "Value",
        "मान",
        "मूल्य",
        "Value",
    ),
    "assets.rental.addRental": (
        "Add Rental Agreement",
        "किराया अनुबंध जोड़ें",
        "भाडे करार जोडा",
        "Rental Agreement add karein",
    ),
    "assets.rental.addRentalTitle": (
        "Add Rental Agreement",
        "किराया अनुबंध जोड़ें",
        "भाडे करार जोडा",
        "Rental Agreement add karein",
    ),
    "assets.rental.amount": (
        "Amount *",
        "राशि *",
        "रक्कम *",
        "Amount *",
    ),
    "assets.rental.billingCycle": (
        "Billing Cycle *",
        "बिलिंग चक्र *",
        "बिलिंग चक्र *",
        "Billing Cycle *",
    ),
    "assets.rental.col.cycle": (
        "Billing Cycle",
        "बिलिंग चक्र",
        "बिलिंग चक्र",
        "Billing Cycle",
    ),
    "assets.rental.col.end": (
        "End",
        "समाप्ति",
        "समाप्ती",
        "End",
    ),
    "assets.rental.col.rate": (
        "Rate",
        "दर",
        "दर",
        "Rate",
    ),
    "assets.rental.col.renter": (
        "Renter",
        "किरायेदार",
        "भाडेकरू",
        "Renter",
    ),
    "assets.rental.col.start": (
        "Start",
        "आरंभ",
        "आरंभ",
        "Start",
    ),
    "assets.rental.create": (
        "Create",
        "बनाएं",
        "तयार करा",
        "Create karein",
    ),
    "assets.rental.cycle.monthly": (
        "Monthly",
        "मासिक",
        "मासिक",
        "Monthly",
    ),
    "assets.rental.cycle.oneTime": (
        "One-time",
        "एक बार",
        "एकवेळ",
        "One-time",
    ),
    "assets.rental.cycle.quarterly": (
        "Quarterly",
        "त्रैमासिक",
        "त्रैमासिक",
        "Quarterly",
    ),
    "assets.rental.due": (
        "Due",
        "देय",
        "देय",
        "Due",
    ),
    "assets.rental.empty": (
        "No rental agreements registered for this asset",
        "इस asset के लिए कोई किराया अनुबंध दर्ज नहीं है",
        "या asset साठी कोणताही भाडे करार नोंदवलेला नाही",
        "Is asset ke liye koi rental agreement register nahi hua",
    ),
    "assets.rental.endDate": (
        "End Date",
        "समाप्ति तिथि",
        "समाप्ती तारीख",
        "End Date",
    ),
    "assets.rental.endDateHint": (
        "Leave blank for an ongoing/open-ended rental.",
        "चालू/खुले किराए के लिए इसे खाली छोड़ दें।",
        "चालू/खुल्या भाड्यासाठी हे रिकामे ठेवा.",
        "Ongoing/open-ended rental ke liye ise blank chhod dein.",
    ),
    "assets.rental.heading": (
        "Rental Agreements",
        "किराया अनुबंध",
        "भाडे करार",
        "Rental Agreements",
    ),
    "assets.rental.incomeEntries": (
        "Income Entries",
        "आय प्रविष्टियाँ",
        "उत्पन्न नोंदी",
        "Income Entries",
    ),
    "assets.rental.loading": (
        "Loading rental agreements...",
        "किराया अनुबंध लोड हो रहे हैं...",
        "भाडे करार लोड होत आहेत...",
        "Rental agreements load ho rahe hain...",
    ),
    "assets.rental.noEntries": (
        "No income entries yet — run the rental income batch from the Rental Income Report.",
        "अभी तक कोई आय प्रविष्टि नहीं है — Rental Income Report से rental income batch चलाएं।",
        "अद्याप कोणतीही उत्पन्न नोंद नाही — Rental Income Report मधून rental income batch चालवा.",
        "Abhi tak koi income entry nahi hai — Rental Income Report se rental income batch chalayein.",
    ),
    "assets.rental.notes": (
        "Notes",
        "टिप्पणियाँ",
        "टिपा",
        "Notes",
    ),
    "assets.rental.ongoing": (
        "Ongoing",
        "चालू",
        "चालू",
        "Ongoing",
    ),
    "assets.rental.periodOutstanding": (
        "Period {{period}} — outstanding {{amount}}",
        "अवधि {{period}} — बकाया {{amount}}",
        "कालावधी {{period}} — थकबाकी {{amount}}",
        "Period {{period}} — outstanding {{amount}}",
    ),
    "assets.rental.rate": (
        "Rental Rate *",
        "किराया दर *",
        "भाडे दर *",
        "Rental Rate *",
    ),
    "assets.rental.received": (
        "Received",
        "प्राप्त",
        "प्राप्त",
        "Received",
    ),
    "assets.rental.receivedDate": (
        "Received Date",
        "प्राप्ति तिथि",
        "प्राप्ती तारीख",
        "Received Date",
    ),
    "assets.rental.recordPayment": (
        "Record Payment",
        "भुगतान दर्ज करें",
        "पेमेंट नोंदवा",
        "Payment record karein",
    ),
    "assets.rental.recordPaymentBtn": (
        "Record Payment",
        "भुगतान दर्ज करें",
        "पेमेंट नोंदवा",
        "Payment record karein",
    ),
    "assets.rental.recordPaymentTitle": (
        "Record Payment",
        "भुगतान दर्ज करें",
        "पेमेंट नोंदवा",
        "Payment record karein",
    ),
    "assets.rental.recording": (
        "Recording...",
        "रिकॉर्ड हो रहा है...",
        "रेकॉर्ड होत आहे...",
        "Record ho raha hai...",
    ),
    "assets.rental.renterContact": (
        "Renter Contact",
        "किरायेदार संपर्क",
        "भाडेकरू संपर्क",
        "Renter Contact",
    ),
    "assets.rental.renterName": (
        "Renter Name *",
        "किरायेदार का नाम *",
        "भाडेकरूचे नाव *",
        "Renter Name *",
    ),
    "assets.rental.startDate": (
        "Start Date *",
        "आरंभ तिथि *",
        "आरंभ तारीख *",
        "Start Date *",
    ),
    "assets.rental.terminate": (
        "Terminate",
        "समाप्त करें",
        "समाप्त करा",
        "Terminate",
    ),
    "assets.rental.viewIncome": (
        "View income entries",
        "आय प्रविष्टियाँ देखें",
        "उत्पन्न नोंदी पहा",
        "Income entries dekhein",
    ),
    "assets.verifyRequest.assignedTo": (
        "Will be assigned to",
        "को सौंपा जाएगा",
        "यास नियुक्त केले जाईल",
        "Ko assign hoga",
    ),
    "assets.verifyRequest.created": (
        "Verification requested — the custodian has been notified.",
        "सत्यापन का अनुरोध किया गया — अभिरक्षक को सूचित कर दिया गया है।",
        "पडताळणीची विनंती केली — ताबेदाराला सूचित करण्यात आले आहे.",
        "Verification request kar diya gaya — custodian ko notify kar diya gaya hai.",
    ),
    "assets.verifyRequest.error": (
        "Failed to create verification request.",
        "सत्यापन अनुरोध बनाने में विफल।",
        "पडताळणी विनंती तयार करण्यात अयशस्वी.",
        "Verification request create karne mein fail ho gaya.",
    ),
    "assets.verifyRequest.historyTitle": (
        "Verification Requests",
        "सत्यापन अनुरोध",
        "पडताळणी विनंत्या",
        "Verification Requests",
    ),
    "assets.verifyRequest.loadingCustodian": (
        "Loading custodian...",
        "अभिरक्षक लोड हो रहा है...",
        "ताबेदार लोड होत आहे...",
        "Custodian load ho raha hai...",
    ),
    "assets.verifyRequest.noCustodian": (
        "This asset has no active custodian — a verification request cannot be assigned.",
        "इस asset का कोई सक्रिय अभिरक्षक नहीं है — सत्यापन अनुरोध सौंपा नहीं जा सकता।",
        "या asset ला कोणताही सक्रिय ताबेदार नाही — पडताळणी विनंती नियुक्त करता येणार नाही.",
        "Is asset ka koi active custodian nahi hai — verification request assign nahi ho sakti.",
    ),
    "assets.verifyRequest.note": (
        "Note (optional)",
        "नोट (वैकल्पिक)",
        "नोट (ऐच्छिक)",
        "Note (optional)",
    ),
    "assets.verifyRequest.notePh": (
        "Any context for the custodian",
        "अभिरक्षक के लिए कोई भी संदर्भ",
        "ताबेदारासाठी कोणताही संदर्भ",
        "Custodian ke liye koi bhi context",
    ),
    "assets.verifyRequest.submit": (
        "Request Verification",
        "सत्यापन अनुरोध करें",
        "पडताळणी विनंती करा",
        "Verification request karein",
    ),
    "assets.verifyRequest.submitting": (
        "Requesting...",
        "अनुरोध किया जा रहा है...",
        "विनंती केली जात आहे...",
        "Request ho raha hai...",
    ),
    "assets.verifyRequest.subtitle": (
        "Ask this asset's custodian to physically verify it by scanning its tag.",
        "इस asset के अभिरक्षक से इसके tag को स्कैन करके भौतिक सत्यापन करने के लिए कहें।",
        "या asset च्या ताबेदाराला याचा tag स्कॅन करून प्रत्यक्ष पडताळणी करण्यास सांगा.",
        "Is asset ke custodian se uska tag scan karke physical verification karne ko kahein.",
    ),
    "assets.verifyRequest.title": (
        "Request Verification",
        "सत्यापन अनुरोध करें",
        "पडताळणी विनंती करा",
        "Verification request karein",
    ),
    "budget.allocation.cancel": (
        "Cancel",
        "रद्द करें",
        "रद्द करा",
        "Cancel",
    ),
    "budget.allocation.close": (
        "Close",
        "बंद करें",
        "बंद करा",
        "Close",
    ),
    "budget.allocation.colActual": (
        "Actual",
        "वास्तविक",
        "प्रत्यक्ष",
        "Actual",
    ),
    "budget.allocation.colCommitted": (
        "Committed",
        "प्रतिबद्ध",
        "वचनबद्ध",
        "Committed",
    ),
    "budget.allocation.currentValueSuffix": (
        "(current)",
        "(वर्तमान)",
        "(सद्यस्थिती)",
        "(current)",
    ),
    "budget.allocation.edit": (
        "Edit",
        "संपादित करें",
        "संपादित करा",
        "Edit",
    ),
    "budget.allocation.editPendingNote": (
        "Only pending budget lines can be edited. Once approved, a line is locked.",
        "केवल pending बजट लाइनों को संपादित किया जा सकता है। स्वीकृत होने के बाद, लाइन लॉक हो जाती है।",
        "फक्त pending बजट लाइन्स संपादित करता येतात. मंजूर झाल्यानंतर, लाइन लॉक होते.",
        "Sirf pending budget lines edit ho sakti hain. Approve hone ke baad, line lock ho jaati hai.",
    ),
    "budget.allocation.editTitle": (
        "Edit Budget Line",
        "बजट लाइन संपादित करें",
        "बजट लाइन संपादित करा",
        "Budget Line edit karein",
    ),
    "budget.allocation.saveChanges": (
        "Save Changes",
        "परिवर्तन सहेजें",
        "बदल जतन करा",
        "Changes Save karein",
    ),
    "budget.allocation.saving": (
        "Saving...",
        "सहेजा जा रहा है...",
        "जतन होत आहे...",
        "Save ho raha hai...",
    ),
    "budget.allocation.updateFailed": (
        "Failed to update budget.",
        "बजट अपडेट करने में विफल।",
        "बजट अपडेट करण्यात अयशस्वी.",
        "Budget update karne mein fail ho gaya.",
    ),
    "budget.allocation.updatedFlash": (
        "Budget line updated.",
        "बजट लाइन अपडेट हो गई।",
        "बजट लाइन अपडेट झाली.",
        "Budget line update ho gayi.",
    ),
    "budget.allocation.view": (
        "View",
        "देखें",
        "पहा",
        "View",
    ),
    "budget.allocation.viewTitle": (
        "Budget Line Details",
        "बजट लाइन विवरण",
        "बजट लाइन तपशील",
        "Budget Line Details",
    ),
}


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 GAP_BATCH1_ASSETS.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(GAP_BATCH1_ASSETS)} gap-batch1-assets keys.")


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