"""
Builds the FleetSecure GRC app (the Core + Tenant mockups) in the GRC tenant:
37 datasources and 6 forms, all stored as database tables, with 10 sample
records each; 6 notification tasks the forms run on submit; ~30 portal
pages with their menus; a dashboard per role, which is where it lands; and two portal users — a GRC Tenant Admin for the
Core pages and an Implementation Team user for the Tenant pages.

Everything goes through the running API (default http://127.0.0.1:8000),
signed in as the tenant administrator, so it is validated, stored and
audited exactly as if they had built it in the Studio. Safe to re-run.

The two portal users share one password, generated on the first run and
written to GRC_APP_CREDENTIALS.local.txt at the repository root (gitignored).

Usage:
    backend/.venv/Scripts/python.exe backend/scripts/build_grc_app.py [--api http://127.0.0.1:8000]
"""

import argparse
import asyncio
import re
import sys
from pathlib import Path

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

from grc_app.build import ROLE_CORE, ROLE_TENANT, Build, make_password  # noqa: E402
from grc_app.client import Api, user_identity  # noqa: E402
from grc_app.dashboards import Dashboards  # noqa: E402
from grc_app.model_tenant import FORMS, FORMS_AFTER  # noqa: E402
from grc_app.pages import Pages  # noqa: E402

TENANT = "GRC"
DESIGNER = "vidyakumar.s@saasvaap.com"
CREDENTIALS = BACKEND.parent / "GRC_APP_CREDENTIALS.local.txt"
USERS = [
    {"name": "GRC Tenant Admin", "email": "grc.tenantadmin@example.com", "role": ROLE_CORE, "phone": "+97455110001"},
    {"name": "Implementation Team", "email": "implementation.team@example.com", "role": ROLE_TENANT, "phone": "+97455110002"},
]

# Dark navy sidebar like the mockups' layout shell.
PORTAL_MENU = {
    "position": "left", "item_style": "pill", "density": "comfortable", "width": 272, "show_icons": True, "show_group_labels": True,
    "background_color": "#0b1324", "text_color": "#cbd5e1", "hover_background": "#16223a", "active_background": "#2563eb",
    "active_text": "#ffffff", "group_label_color": "#64748b", "border_color": "#16223a", "tooltips": "collapsed", "search_enabled": True,
    "search_placeholder": "Search menu…", "logo_height": 32, "logo_show_title": True, "collapsible": True, "default_collapsed": False,
    "collapsible_groups": True, "groups_default_collapsed": False,
}


def saved_password() -> str | None:
    if not CREDENTIALS.exists():
        return None
    m = re.search(r"^Password: (\S+)$", CREDENTIALS.read_text(encoding="utf-8"), re.M)
    return m.group(1) if m else None


def write_credentials(password: str, tenant_id: str) -> None:
    lines = [
        "FleetSecure GRC app — portal sign-in (local test accounts; do not commit)",
        "",
        "Sign in at http://localhost:5173/login, choose the GRC tenant.",
        f"Tenant id: {tenant_id}",
        "",
        *[f"{u['name']}: {u['email']}  ({'Core pages' if u['role'] == ROLE_CORE else 'Tenant pages'})" for u in USERS],
        f"Password: {password}",
        "",
    ]
    CREDENTIALS.write_text("\n".join(lines), encoding="utf-8")


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--api", default="http://127.0.0.1:8000")
    args = parser.parse_args()

    tenant_id, designer_id, _ = asyncio.run(user_identity(TENANT, DESIGNER))
    admin = Api(args.api, tenant_id, designer_id)
    build = Build(admin)
    password = saved_password() or make_password()

    accounts = build.build_data(USERS, password)
    pages = Pages(build)
    pages.grant_all_data()
    as_core = Api(args.api, tenant_id, accounts[ROLE_CORE]["id"], accounts[ROLE_CORE]["vendor_id"])
    as_tenant = Api(args.api, tenant_id, accounts[ROLE_TENANT]["id"], accounts[ROLE_TENANT]["vendor_id"])

    print("Sample submissions")
    for f in FORMS:
        build.seed_form(f, as_core if f["group"] == "core" else as_tenant)
    build.build_after_forms()
    pages.grant_all_data()
    for f in FORMS_AFTER:
        build.seed_form(f, as_tenant)

    print("Pages")
    pages.build_core()
    pages.build_tenant()
    print("Menus and role grants")
    pages.build_menus()
    pages.grant_roles()
    print("Dashboards (each role's landing page)")
    Dashboards(build, pages).publish()

    print("Portal appearance")
    admin.patch("/tenants/me/portal-menu", PORTAL_MENU)

    # The sample records were added directly, so their forms' on-submit tasks
    # never ran — run them once for a few of them, as the portal users would
    # have, so both bells start with real notifications.
    if not as_core.get("/notifications", limit=1):
        print("Sample notifications")
        forms = {f["key"]: f for f in [*FORMS, *FORMS_AFTER]}
        runs = [("client_tenant", 0, as_core), ("client_tenant", 6, as_core), ("soa", 0, as_tenant), ("kpi_assignment", 3, as_tenant),
                ("kpi_result", 1, as_tenant), ("kpi_result", 5, as_tenant), ("audit_plan", 0, as_tenant), ("audit_assessment", 2, as_tenant)]
        for key, i, api in runs:
            task = build.tasks[build.FORM_TASKS[key]]
            api.post(f"/tasks/{task['id']}/run", {"context": build._values(forms[key]["rows"][i])})

    write_credentials(password, str(tenant_id))
    print(f"Done. Portal sign-in details: {CREDENTIALS}")


if __name__ == "__main__":
    main()
