"""
Imports sample data into every Datasource (Master) that currently has zero
records under a given tenant. Same standalone-script pattern as
scripts/seed_leave_management_app.py: inserts SQLAlchemy ORM rows directly
through AsyncSessionLocal, bypassing the auth/JWT layer, with cross-master
"reference" field values resolved as real MasterRecord ids created earlier
in this same run (looked up by master name + a human key, not hardcoded
ids, since a Master's id is only known once it already exists in the DB).

The specific masters/data below (Country/State/District, Office/Section/
Seat, Payment types/status/Payments, Reply types, Application Status,
Gateway) match the "KSRTC" tenant's actual Datasources as of this writing —
this is deliberately a one-off seed for that tenant's existing schema, not
a generic fixture generator, since a generic version would need to guess
plausible values for arbitrary future field names.

Idempotency: each master is skipped (with a printed note) if it already has
any records, so re-running after partial data entry never creates dupes.

Usage:
    backend/.venv/Scripts/python.exe backend/scripts/import_sample_data.py
"""

import asyncio
import sys
import uuid
from datetime import datetime, timezone
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from sqlalchemy import select, func  # noqa: E402

from app.core.database import AsyncSessionLocal  # noqa: E402
from app.models.identity import Tenant, User  # noqa: E402
from app.models.master import Master, MasterRecord  # noqa: E402

TENANT_ID = uuid.UUID("e5b46349-0866-4023-84aa-9dae5ea54db0")


def uid() -> uuid.UUID:
    return uuid.uuid4()


def ts(y: int, m: int, d: int, hh: int = 10, mm: int = 0) -> str:
    return datetime(y, m, d, hh, mm, tzinfo=timezone.utc).isoformat()


async def main() -> None:
    async with AsyncSessionLocal() as db:
        async with db.begin():
            tenant = await db.get(Tenant, TENANT_ID)
            if tenant is None:
                raise SystemExit(f"tenant {TENANT_ID} not found")

            masters = (
                await db.execute(select(Master).where(Master.tenant_id == TENANT_ID))
            ).scalars().all()
            master_by_name = {m.name: m for m in masters}

            admin_user = (
                await db.execute(select(User).where(User.tenant_id == TENANT_ID))
            ).scalars().first()
            if admin_user is None:
                raise SystemExit("no user found on this tenant to attribute created_by to")

            async def has_records(master_id: uuid.UUID) -> bool:
                count = (
                    await db.execute(
                        select(func.count()).select_from(MasterRecord).where(
                            MasterRecord.tenant_id == TENANT_ID,
                            MasterRecord.master_id == master_id,
                        )
                    )
                ).scalar()
                return count > 0

            # ids keyed by (master name, human key) so later masters can
            # reference records created for earlier ones by name.
            ids: dict[tuple[str, str], uuid.UUID] = {}

            async def seed(master_name: str, rows: list[tuple[str, dict]]) -> None:
                master = master_by_name.get(master_name)
                if master is None:
                    print(f"skip '{master_name}': no such datasource for this tenant")
                    return
                if await has_records(master.id):
                    print(f"skip '{master_name}': already has records")
                    return
                for key, field_values in rows:
                    record_id = uid()
                    ids[(master_name, key)] = record_id
                    db.add(
                        MasterRecord(
                            id=record_id,
                            tenant_id=TENANT_ID,
                            master_id=master.id,
                            created_by=admin_user.id,
                            field_values=field_values,
                        )
                    )
                await db.flush()
                print(f"seeded '{master_name}': {len(rows)} records")

            def ref(master_name: str, key: str) -> str:
                return str(ids[(master_name, key)])

            # -----------------------------------------------------------
            # Country -> State -> District
            # -----------------------------------------------------------
            await seed("Country", [
                ("india", {"name": "India", "is_active": "Active"}),
            ])

            await seed("State", [
                ("karnataka", {"name": "Karnataka", "abbreviation": "KA", "country_id": ref("Country", "india"), "is_active": "Active"}),
                ("kerala", {"name": "Kerala", "abbreviation": "KL", "country_id": ref("Country", "india"), "is_active": "Active"}),
                ("tamil_nadu", {"name": "Tamil Nadu", "abbreviation": "TN", "country_id": ref("Country", "india"), "is_active": "Active"}),
            ])

            await seed("District", [
                ("bengaluru_urban", {"district_name": "Bengaluru Urban", "state_id": ref("State", "karnataka"), "district_code": "BLR", "is_active": "Active"}),
                ("mysuru", {"district_name": "Mysuru", "state_id": ref("State", "karnataka"), "district_code": "MYS", "is_active": "Active"}),
                ("mangaluru", {"district_name": "Dakshina Kannada", "state_id": ref("State", "karnataka"), "district_code": "DK", "is_active": "Active"}),
                ("kozhikode", {"district_name": "Kozhikode", "state_id": ref("State", "kerala"), "district_code": "KKD", "is_active": "Active"}),
            ])

            # -----------------------------------------------------------
            # Office type -> Office -> Section -> Seat
            # -----------------------------------------------------------
            await seed("Office type", [
                ("divisional", {"name": "Divisional Office", "is_active": "Active"}),
                ("depot", {"name": "Depot", "is_active": "Active"}),
                ("booking_counter", {"name": "Booking Counter", "is_active": "Active"}),
            ])

            await seed("Office", [
                (
                    "blr_central",
                    {
                        "office_type_id": ref("Office type", "divisional"),
                        "name": "Bengaluru Central Division",
                        "code": "BLR-DIV-01",
                        "short_code": "BLRC",
                        "phone_number": "080-22221111",
                        "building_name": "KSRTC Central Office",
                        "city": "Bengaluru",
                        "email": "blr.central@ksrtc.example.gov.in",
                        "is_active": "Active",
                    },
                ),
                (
                    "mysuru_depot",
                    {
                        "office_type_id": ref("Office type", "depot"),
                        "name": "Mysuru City Depot",
                        "code": "MYS-DEP-01",
                        "short_code": "MYSD",
                        "phone_number": "0821-2412345",
                        "building_name": "Mysuru Bus Stand Complex",
                        "city": "Mysuru",
                        "email": "mysuru.depot@ksrtc.example.gov.in",
                        "is_active": "Active",
                    },
                ),
                (
                    "majestic_counter",
                    {
                        "office_type_id": ref("Office type", "booking_counter"),
                        "name": "Majestic Booking Counter",
                        "code": "BLR-BC-01",
                        "short_code": "MJBC",
                        "phone_number": "080-22222222",
                        "building_name": "Kempegowda Bus Station",
                        "city": "Bengaluru",
                        "email": "majestic.counter@ksrtc.example.gov.in",
                        "is_active": "Active",
                    },
                ),
            ])

            await seed("Section", [
                ("blr_admin", {"name": "Administration", "office": ref("Office", "blr_central"), "is_active": "Active"}),
                ("blr_operations", {"name": "Operations", "office": ref("Office", "blr_central"), "is_active": "Active"}),
                ("mysuru_maintenance", {"name": "Maintenance", "office": ref("Office", "mysuru_depot"), "is_active": "Active"}),
                ("majestic_ticketing", {"name": "Ticketing", "office": ref("Office", "majestic_counter"), "is_active": "Active"}),
            ])

            await seed("Seat", [
                ("majestic_counter_1", {"name": "Counter 1", "section": ref("Section", "majestic_ticketing"), "is_active": "Active"}),
                ("majestic_counter_2", {"name": "Counter 2", "section": ref("Section", "majestic_ticketing"), "is_active": "Active"}),
                ("majestic_counter_3", {"name": "Counter 3", "section": ref("Section", "majestic_ticketing"), "is_active": "Inactive"}),
            ])

            # -----------------------------------------------------------
            # Payment types / Payment status -> Payments
            # -----------------------------------------------------------
            await seed("Payment types", [
                ("cash", {"name": "Cash", "is_active": "Active"}),
                ("card", {"name": "Card", "is_active": "Active"}),
                ("upi", {"name": "UPI", "is_active": "Active"}),
                ("net_banking", {"name": "Net Banking", "is_active": "Active"}),
            ])

            await seed("Payment status", [
                ("pending", {"name": "Pending", "is_active": "Active"}),
                ("success", {"name": "Success", "is_active": "Active"}),
                ("failed", {"name": "Failed", "is_active": "Active"}),
                ("refunded", {"name": "Refunded", "is_active": "Active"}),
            ])

            await seed("Payments", [
                (
                    "pay_1",
                    {
                        "payment_type_id": ref("Payment types", "upi"),
                        "amount": 450.00,
                        "payment_status_id": ref("Payment status", "success"),
                        "is_active": "Active",
                        "deleted_at": None,
                        "user_id": str(admin_user.id),
                        "payment_reference_number": "PAY-2026-000101",
                        "receipt": "Bengaluru -> Mysuru, 2 seats",
                        "paid_at": ts(2026, 9, 10),
                    },
                ),
                (
                    "pay_2",
                    {
                        "payment_type_id": ref("Payment types", "card"),
                        "amount": 890.50,
                        "payment_status_id": ref("Payment status", "success"),
                        "is_active": "Active",
                        "deleted_at": None,
                        "user_id": str(admin_user.id),
                        "payment_reference_number": "PAY-2026-000102",
                        "receipt": "Bengaluru -> Mangaluru, 1 seat",
                        "paid_at": ts(2026, 9, 12),
                    },
                ),
                (
                    "pay_3",
                    {
                        "payment_type_id": ref("Payment types", "cash"),
                        "amount": 220.00,
                        "payment_status_id": ref("Payment status", "pending"),
                        "is_active": "Active",
                        "deleted_at": None,
                        "user_id": str(admin_user.id),
                        "payment_reference_number": "PAY-2026-000103",
                        "receipt": "Mysuru -> Kozhikode, 1 seat",
                        "paid_at": ts(2026, 9, 14),
                    },
                ),
                (
                    "pay_4",
                    {
                        "payment_type_id": ref("Payment types", "net_banking"),
                        "amount": 610.00,
                        "payment_status_id": ref("Payment status", "failed"),
                        "is_active": "Inactive",
                        "deleted_at": ts(2026, 9, 13),
                        "user_id": str(admin_user.id),
                        "payment_reference_number": "PAY-2026-000104",
                        "receipt": "Bengaluru -> Mysuru, 3 seats (payment failed)",
                        "paid_at": ts(2026, 9, 13),
                    },
                ),
            ])

            # -----------------------------------------------------------
            # Reply types / Application Status (standalone lookups)
            # -----------------------------------------------------------
            await seed("Reply types", [
                ("general", {"name": "General", "is_active": "Active"}),
                ("complaint", {"name": "Complaint", "is_active": "Active"}),
                ("suggestion", {"name": "Suggestion", "is_active": "Active"}),
                ("query", {"name": "Query", "is_active": "Active"}),
            ])

            await seed("Application Status", [
                ("draft", {"name": "Draft", "is_active": "Active"}),
                ("submitted", {"name": "Submitted", "is_active": "Active"}),
                ("approved", {"name": "Approved", "is_active": "Active"}),
                ("rejected", {"name": "Rejected", "is_active": "Active"}),
            ])

            # -----------------------------------------------------------
            # Gateway — obviously-fake sample/test keys, not real secrets.
            # -----------------------------------------------------------
            await seed("Gateway", [
                (
                    "razorpay",
                    {
                        "name": "Razorpay",
                        "public_key": "rzp_test_sample00000001",
                        "api_key": "rzp_test_sample00000001",
                        "secret_key": "sample_test_secret_do_not_use_0001",
                        "gateway_url": "https://api.razorpay.com/v1",
                        "is_active": "Active",
                    },
                ),
                (
                    "payu",
                    {
                        "name": "PayU",
                        "public_key": "payu_test_sample00000002",
                        "api_key": "payu_test_sample00000002",
                        "secret_key": "sample_test_secret_do_not_use_0002",
                        "gateway_url": "https://test.payu.in/_payment",
                        "is_active": "Inactive",
                    },
                ),
            ])

            print("\nDone.")


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