"""Refresh line entity schemas with optional catalog_item_record_id.

Does not add slots, jobs, or checkout. Header amount stays explicit.
"""
from __future__ import annotations

import json
from pathlib import Path
import re
import sys

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))

from tests.test_phase11_pack_migration_materialization import _load_migration

MIGRATION = ROOT / "alembic/versions/160_line_catalog_item_relation.py"


def write(path: Path, text: str) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(text, encoding="utf-8")


def _entity(composition: dict, key: str) -> dict:
    return next(item for item in composition["entities"] if item["entity_key"] == key)


def _schema_json(entity: dict) -> str:
    return json.dumps({"fields": entity["schema"]["fields"]}, indent=2) + "\n"


def labels(entity: dict) -> list[dict]:
    return [{"key": field["key"], "label": field["name"]} for field in entity["schema"]["fields"]]


def nuxt_detail(entity_key: str, title: str, fields_json: str) -> str:
    return f'''<script setup>
import AdminRecordDetail from "./AdminRecordDetail.vue";
defineProps({{ recordId: {{ type: String, required: true }} }});
const fields = {fields_json};
</script>
<template><AdminRecordDetail entity-key="{entity_key}" :record-id="recordId" title="{title}" :fields="fields" /></template>
'''


def _replace_schema_const(path: Path, const_name: str, entity: dict) -> None:
    text = path.read_text(encoding="utf-8")
    blob = json.dumps({"fields": entity["schema"]["fields"]})
    updated, count = re.subn(
        rf"const {const_name} = \{{.*?\}};",
        f"const {const_name} = {blob};",
        text,
        count=1,
        flags=re.S,
    )
    if count != 1:
        raise SystemExit(f"expected one {const_name} in {path}")
    write(path, updated)


def main() -> None:
    module = _load_migration(str(MIGRATION))
    quote_line = _entity(module.quote_lifecycle_v1_2(), "quote_line")
    invoice_line = _entity(module.billing_management_v1_2(), "invoice_line")
    order_line = _entity(module.order_lifecycle_v1_2(), "order_line")
    schemas = {
        "quote_line": quote_line,
        "invoice_line": invoice_line,
        "order_line": order_line,
    }
    for framework, lib in (("nuxt_app", "lib"), ("react_app", "src/lib"), ("html", "js")):
        for key, entity in schemas.items():
            write(
                ROOT / "boilerplates" / framework / lib / "entity-schemas" / f"{key}.json",
                _schema_json(entity),
            )

    nuxt = ROOT / "boilerplates/nuxt_app/components/starter/blocks"
    write(nuxt / "QuoteLineDetail.vue", nuxt_detail("quote_line", "Quote line", json.dumps(labels(quote_line))))
    write(nuxt / "InvoiceLineDetail.vue", nuxt_detail("invoice_line", "Invoice line", json.dumps(labels(invoice_line))))
    write(nuxt / "OrderLineDetail.vue", nuxt_detail("order_line", "Order line", json.dumps(labels(order_line))))

    _replace_schema_const(
        ROOT / "boilerplates/html/js/capability-phase3-blocks.js",
        "quoteLineSchema",
        quote_line,
    )
    _replace_schema_const(
        ROOT / "boilerplates/html/js/invoice-blocks.js",
        "invoiceLineSchema",
        invoice_line,
    )
    _replace_schema_const(
        ROOT / "boilerplates/html/js/order-blocks.js",
        "orderLineSchema",
        order_line,
    )
    print("wave4 line catalog_item relation schemas materialized")


if __name__ == "__main__":
    main()
