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

Usage: docker compose exec api python seed_translations_pageinfo_depreciation_exceptions.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)
DEPRECIATION_EXCEPTIONS = {
    "depreciation-exceptions.title": (
        "Depreciation Exceptions",
        "मूल्यह्रास अपवाद",
        "घसारा अपवाद",
        "Depreciation Exceptions",
    ),
    "depreciation-exceptions.subtitle": (
        "Only the assets whose books disagree",
        "सिर्फ़ वे asset जिनके books आपस में मेल नहीं खाते",
        "फक्त त्या asset ज्यांची books जुळत नाहीत",
        "Sirf wo assets jinki books aapas mein match nahi karti",
    ),
    "depreciation-exceptions.body.0": (
        "Assets whose net book value or depreciation differs across the three books (Companies Act, Income Tax, Ind AS) for a period — the full comparison for every asset lives on Financial Reconciliation.",
        "वे assets जिनका net book value या depreciation किसी अवधि (period) के लिए तीनों books (Companies Act, Income Tax, Ind AS) में अलग-अलग है — प्रत्येक asset की पूरी तुलना Financial Reconciliation पर उपलब्ध है।",
        "ज्या assets चे net book value किंवा depreciation एखाद्या period साठी तिन्ही books (Companies Act, Income Tax, Ind AS) मध्ये वेगवेगळे आहे — प्रत्येक asset ची संपूर्ण तुलना Financial Reconciliation वर उपलब्ध आहे.",
        "Wo assets jinka net book value ya depreciation kisi period ke liye teenon books (Companies Act, Income Tax, Ind AS) mein alag-alag hai — har asset ki poori comparison Financial Reconciliation par milti hai.",
    ),
    "depreciation-exceptions.body.1": (
        "This page runs the same reconciliation as Financial Reconciliation, then keeps only the rows where the books don't agree, so you don't have to scan a full asset-by-asset report to find the problems.",
        "यह page वही reconciliation चलाता है जो Financial Reconciliation करता है, फिर केवल उन rows को रखता है जहाँ books आपस में मेल नहीं खातीं, ताकि आपको समस्याएँ ढूँढने के लिए पूरी asset-by-asset report खंगालनी न पड़े।",
        "हे page Financial Reconciliation प्रमाणेच reconciliation चालवते, आणि नंतर फक्त त्या rows ठेवते जिथे books जुळत नाहीत, जेणेकरून समस्या शोधण्यासाठी तुम्हाला संपूर्ण asset-by-asset report तपासावा लागू नये.",
        "Ye page bilkul waisa hi reconciliation chalata hai jaisa Financial Reconciliation karta hai, phir sirf un rows ko rakhta hai jahan books match nahi karti, taaki problems dhoondhne ke liye poori asset-by-asset report scan na karni pade.",
    ),
    "depreciation-exceptions.stepsHeading": (
        "How a check works",
        "जाँच कैसे काम करती है",
        "तपासणी कशी काम करते",
        "Check kaise kaam karta hai",
    ),
    "depreciation-exceptions.steps.0.label": ("Select Period", "Period चुनें", "Period निवडा", "Period Select karein"),
    "depreciation-exceptions.steps.0.caption": (
        "Pick the year and month to compare.",
        "तुलना करने के लिए वर्ष और महीना चुनें।",
        "तुलना करण्यासाठी वर्ष आणि महिना निवडा.",
        "Compare karne ke liye year aur month choose karein.",
    ),
    "depreciation-exceptions.steps.1.label": ("Run Reconciliation", "Reconciliation चलाएँ", "Reconciliation चालवा", "Reconciliation Run karein"),
    "depreciation-exceptions.steps.1.caption": (
        "Fetches NBV and depreciation from all three books for that period.",
        "उस period के लिए तीनों books से NBV और depreciation प्राप्त करता है।",
        "त्या period साठी तिन्ही books मधून NBV आणि depreciation आणते.",
        "Us period ke liye teenon books se NBV aur depreciation fetch karta hai.",
    ),
    "depreciation-exceptions.steps.2.label": ("Review Exceptions", "Exceptions की समीक्षा करें", "Exceptions चे पुनरावलोकन करा", "Exceptions Review karein"),
    "depreciation-exceptions.steps.2.caption": (
        "Only assets with a book difference are listed here.",
        "यहाँ केवल वे assets सूचीबद्ध हैं जिनमें book difference है।",
        "येथे फक्त त्याच assets यादीबद्ध आहेत ज्यांच्यात book difference आहे.",
        "Yahan sirf wahi assets list hote hain jinme book difference hai.",
    ),
    "depreciation-exceptions.steps.3.label": ("Investigate", "जाँच करें", "तपास करा", "Investigate karein"),
    "depreciation-exceptions.steps.3.caption": (
        "Open Financial Reconciliation for the full per-asset comparison.",
        "प्रत्येक asset की पूरी तुलना के लिए Financial Reconciliation खोलें।",
        "प्रत्येक asset ची संपूर्ण तुलना पाहण्यासाठी Financial Reconciliation उघडा.",
        "Har asset ki poori comparison ke liye Financial Reconciliation open karein.",
    ),
    "depreciation-exceptions.fieldRules.0.name": ("Year", "वर्ष", "वर्ष", "Year"),
    "depreciation-exceptions.fieldRules.0.description": (
        "Calendar year of the period being reconciled.",
        "जिस period का reconciliation किया जा रहा है, उसका calendar year।",
        "ज्या period चे reconciliation केले जात आहे त्याचे calendar year.",
        "Jis period ka reconciliation ho raha hai, uska calendar year.",
    ),
    "depreciation-exceptions.fieldRules.1.name": ("Month", "महीना", "महिना", "Month"),
    "depreciation-exceptions.fieldRules.1.description": (
        "Combined with Year into the period sent to the reconciliation report.",
        "Year के साथ मिलकर वह period बनता है जो reconciliation report को भेजा जाता है।",
        "Year सोबत मिळून तो period तयार होतो जो reconciliation report ला पाठवला जातो.",
        "Year ke saath milkar wo period banta hai jo reconciliation report ko bheja jaata hai.",
    ),
    "depreciation-exceptions.fieldRules.2.name": (
        "Companies Act / Income Tax / Ind AS NBV",
        "Companies Act / Income Tax / Ind AS NBV",
        "Companies Act / Income Tax / Ind AS NBV",
        "Companies Act / Income Tax / Ind AS NBV",
    ),
    "depreciation-exceptions.fieldRules.2.description": (
        "Net book value per book for that asset; any mismatch between the three flags the row as an exception.",
        "उस asset के लिए प्रत्येक book के अनुसार net book value; तीनों के बीच कोई भी असमानता row को exception के रूप में चिह्नित करती है।",
        "त्या asset साठी प्रत्येक book नुसार net book value; तिन्हींमधील कोणतीही तफावत row ला exception म्हणून चिन्हांकित करते.",
        "Us asset ke liye har book ke hisaab se net book value; teenon ke beech koi bhi mismatch row ko exception ke roop mein flag karta hai.",
    ),
    "depreciation-exceptions.fieldRules.3.name": (
        "Companies Act / Income Tax / Ind AS Depr.",
        "Companies Act / Income Tax / Ind AS Depr.",
        "Companies Act / Income Tax / Ind AS Depr.",
        "Companies Act / Income Tax / Ind AS Depr.",
    ),
    "depreciation-exceptions.fieldRules.3.description": (
        "Depreciation charged per book for the period; differences here also trigger an exception.",
        "उस period के लिए प्रत्येक book में लगाया गया depreciation; यहाँ अंतर होने पर भी exception ट्रिगर होता है।",
        "त्या period साठी प्रत्येक book मध्ये आकारलेले depreciation; येथे फरक असल्यासही exception ट्रिगर होते.",
        "Us period ke liye har book mein charge kiya gaya depreciation; yahan difference hone par bhi exception trigger hota hai.",
    ),
    "depreciation-exceptions.tip.title": (
        "Zero exceptions ≠ no data",
        "शून्य exceptions का मतलब data न होना नहीं है",
        "शून्य exceptions म्हणजे data नसणे असा अर्थ नाही",
        "Zero exceptions ka matlab data na hona nahi hai",
    ),
    "depreciation-exceptions.tip.body": (
        "The exception list is filtered client-side from the full reconciliation result. An empty table means every asset's books matched for that period — it doesn't confirm the run actually loaded data. If you're not sure, cross-check the same period on Financial Reconciliation, which shows the total assets compared.",
        "Exception list पूरे reconciliation result से client-side पर filter की जाती है। एक खाली table का मतलब है कि उस period के लिए हर asset की books मेल खा गईं — यह इस बात की पुष्टि नहीं करता कि run ने वाकई data load किया। अगर आपको यकीन नहीं है, तो उसी period को Financial Reconciliation पर क्रॉस-चेक करें, जो तुलना किए गए कुल assets दिखाता है।",
        "Exception list संपूर्ण reconciliation result मधून client-side वर filter केली जाते. रिकामी table म्हणजे त्या period साठी प्रत्येक asset च्या books जुळल्या — यामुळे run ने खरोखर data load केला याची खात्री होत नाही. खात्री नसल्यास, तोच period Financial Reconciliation वर cross-check करा, जे तुलना केलेल्या एकूण assets दाखवते.",
        "Exception list poore reconciliation result se client-side par filter hoti hai. Ek empty table ka matlab hai ki us period ke liye har asset ki books match ho gayin — isse ye confirm nahi hota ki run ne actually data load kiya. Agar sure nahi hain, to wahi period Financial Reconciliation par cross-check karein, jo compare kiye gaye total assets dikhata hai.",
    ),
}


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 DEPRECIATION_EXCEPTIONS.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(DEPRECIATION_EXCEPTIONS)} depreciation-exceptions keys.")


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