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

Usage: docker compose exec api python seed_translations_pageinfo_invoice_verification.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)
INVOICE_VERIFICATION = {
    "invoice-verification.title": (
        "Invoice Verification",
        "इनवॉइस सत्यापन",
        "इनव्हॉइस पडताळणी",
        "Invoice Verification",
    ),
    "invoice-verification.body.0": (
        "Runs a 3-way match: the invoice amount is checked against the linked Purchase Order and, if selected, its Goods Receipt Note, within a 2% tolerance computed by the server.",
        "यह एक 3-way match चलाता है: invoice amount की तुलना जुड़े हुए Purchase Order से, और यदि चुना गया हो तो उसके Goods Receipt Note से, server द्वारा गणना किए गए 2% tolerance के भीतर की जाती है।",
        "हे एक 3-way match चालवते: invoice amount ची तुलना जोडलेल्या Purchase Order शी, आणि निवडले असल्यास त्याच्या Goods Receipt Note शी, server ने काढलेल्या 2% tolerance च्या मर्यादेत केली जाते.",
        "Ye ek 3-way match run karta hai: invoice amount ko linked Purchase Order se, aur agar select kiya ho to uske Goods Receipt Note se, server dwara calculate kiye gaye 2% tolerance ke andar check kiya jaata hai.",
    ),
    "invoice-verification.body.1": (
        "Can be reached directly from a Goods Receipt Note's \"Verify Invoice\" action, which pre-selects both the PO and GRN for you.",
        "इसे सीधे किसी Goods Receipt Note की \"Verify Invoice\" action से भी खोला जा सकता है, जो आपके लिए PO और GRN दोनों को पहले से select कर देती है।",
        "हे थेट एखाद्या Goods Receipt Note च्या \"Verify Invoice\" action वरून देखील उघडता येते, जी तुमच्यासाठी PO आणि GRN दोन्ही आधीच select करते.",
        "Isse directly kisi Goods Receipt Note ke \"Verify Invoice\" action se bhi open kiya ja sakta hai, jo aapke liye PO aur GRN dono pre-select kar deta hai.",
    ),
    "invoice-verification.stepsHeading": (
        "Verification flow",
        "सत्यापन प्रक्रिया",
        "पडताळणी प्रक्रिया",
        "Verification flow",
    ),
    "invoice-verification.steps.0.label": ("Create", "बनाएं", "तयार करा", "Create"),
    "invoice-verification.steps.0.caption": (
        "Link the invoice to a PO (and optionally a GRN).",
        "invoice को किसी PO से जोड़ें (और वैकल्पिक रूप से एक GRN से भी)।",
        "invoice ला एखाद्या PO शी जोडा (आणि पर्यायाने एखाद्या GRN शी देखील).",
        "Invoice ko ek PO se link karein (aur optionally ek GRN se bhi).",
    ),
    "invoice-verification.steps.1.label": ("Auto-Match", "ऑटो-मैच", "ऑटो-मॅच", "Auto-Match"),
    "invoice-verification.steps.1.caption": (
        "Server compares invoice vs PO vs GRN within a 2% tolerance.",
        "server invoice की तुलना PO और GRN से 2% tolerance के भीतर करता है।",
        "server invoice ची तुलना PO आणि GRN शी 2% tolerance च्या मर्यादेत करतो.",
        "Server invoice ko PO aur GRN ke against 2% tolerance ke andar compare karta hai.",
    ),
    "invoice-verification.steps.2.label": ("Review", "समीक्षा", "पुनरावलोकन", "Review"),
    "invoice-verification.steps.2.caption": (
        "Exceptions are inspected against the attached documents.",
        "Exceptions की जांच attached documents के विरुद्ध की जाती है।",
        "Exceptions ची तपासणी संलग्न documents विरुद्ध केली जाते.",
        "Exceptions ko attached documents ke against inspect kiya jaata hai.",
    ),
    "invoice-verification.steps.3.label": ("Verify", "सत्यापित करें", "पडताळणी करा", "Verify"),
    "invoice-verification.steps.3.caption": (
        "Mark Matched or Exception to close out the check.",
        "जांच बंद करने के लिए इसे Matched या Exception के रूप में mark करें।",
        "तपासणी पूर्ण करण्यासाठी ती Matched किंवा Exception म्हणून mark करा.",
        "Check close karne ke liye ise Matched ya Exception mark karein.",
    ),
    "invoice-verification.fieldRules.0.name": ("Purchase Order *", "Purchase Order *", "Purchase Order *", "Purchase Order *"),
    "invoice-verification.fieldRules.0.description": (
        "The PO this invoice is verified against; its vendor and total seed the match.",
        "वह PO जिसके विरुद्ध यह invoice सत्यापित किया जा रहा है; उसका vendor और total ही match की शुरुआती जानकारी बनाते हैं।",
        "जो PO या invoice विरुद्ध पडताळला जात आहे; त्याचा vendor आणि total हेच match साठी सुरुवातीचा आधार असतात.",
        "Wo PO jiske against ye invoice verify kiya ja raha hai; uska vendor aur total hi match ke starting values set karte hain.",
    ),
    "invoice-verification.fieldRules.1.name": ("Invoice Amount *", "Invoice Amount *", "Invoice Amount *", "Invoice Amount *"),
    "invoice-verification.fieldRules.1.description": (
        "Pre-filled from the PO total but editable — compared to PO/GRN within 2% to set status.",
        "PO के total से pre-filled होता है लेकिन editable है — status तय करने के लिए PO/GRN से 2% के भीतर तुलना की जाती है।",
        "PO च्या total वरून pre-filled असते पण editable आहे — status ठरवण्यासाठी PO/GRN शी 2% च्या मर्यादेत तुलना केली जाते.",
        "PO ke total se pre-fill hota hai lekin editable hai — status set karne ke liye PO/GRN se 2% ke andar compare kiya jaata hai.",
    ),
    "invoice-verification.fieldRules.2.name": ("Goods Receipt Note", "Goods Receipt Note", "Goods Receipt Note", "Goods Receipt Note"),
    "invoice-verification.fieldRules.2.description": (
        "Optional — when linked, the GRN amount is also checked against the invoice.",
        "वैकल्पिक — जुड़े होने पर, GRN amount की भी invoice से जांच की जाती है।",
        "पर्यायी — जोडलेले असल्यास, GRN amount ची देखील invoice शी तपासणी केली जाते.",
        "Optional hai — link hone par, GRN amount ko bhi invoice ke against check kiya jaata hai.",
    ),
    "invoice-verification.fieldRules.3.name": ("Status", "Status", "Status", "Status"),
    "invoice-verification.fieldRules.3.description": (
        "Set by the server (matched / exception / review / pending) — not typed manually.",
        "यह server द्वारा सेट किया जाता है (matched / exception / review / pending) — इसे manually type नहीं किया जाता।",
        "हे server द्वारे सेट केले जाते (matched / exception / review / pending) — ते manually type केले जात नाही.",
        "Ye server dwara set hota hai (matched / exception / review / pending) — manually type nahi kiya jaata.",
    ),
    "invoice-verification.tip.title": (
        "A failed file upload doesn't roll back the invoice",
        "फ़ाइल अपलोड विफल होने पर भी invoice वापस नहीं होता",
        "file upload अयशस्वी झाल्यासही invoice मागे घेतले जात नाही",
        "File upload fail ho jaaye to bhi invoice rollback nahi hota",
    ),
    "invoice-verification.tip.body": (
        "If the invoice file fails to upload during creation, the invoice record is still saved — retry the attachment from the review panel on the right instead of creating it again.",
        "यदि creation के दौरान invoice file अपलोड होने में विफल हो जाती है, तो भी invoice record सेव रहता है — इसे फिर से बनाने के बजाय दाईं ओर के review panel से attachment को दोबारा try करें।",
        "जर निर्मितीदरम्यान invoice file अपलोड होण्यात अयशस्वी झाली, तरीही invoice record save राहतो — पुन्हा नव्याने तयार करण्याऐवजी उजवीकडील review panel मधून attachment पुन्हा try करा.",
        "Agar creation ke dauran invoice file upload nahi ho paati, to bhi invoice record save reh jaata hai — dobara banane ke bajaye right side ke review panel se attachment retry 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 INVOICE_VERIFICATION.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(INVOICE_VERIFICATION)} invoice-verification keys.")


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