"""
Seeds one comprehensive demo Page — "Component Showcase" — into an EXISTING
tenant, exercising every Page Designer block type and layout container
(free-form canvas rewrite, this session) against real data already in that
tenant (the Masters/Form the KSRTC sample-data scripts seeded earlier).

Standalone script (same pattern as scripts/provision_tenant.py /
scripts/seed_leave_management_app.py): inserts a Page row directly through
AsyncSessionLocal, bypassing the API/auth layer — blocks are built as plain
dicts matching PageBlockDef's JSON shape (app/schemas/navigation.py), not
API calls, since there's no bootstrap route to author a page from nothing.

Idempotency: looked up by tenant_id + name first; if found, exits without
creating a duplicate.

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

import asyncio
import sys
import uuid
from pathlib import Path

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

from sqlalchemy import select  # 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  # noqa: E402
from app.models.navigation import Page  # noqa: E402
from app.models.workflow import Form  # noqa: E402

TENANT_ID = uuid.UUID("e5b46349-0866-4023-84aa-9dae5ea54db0")
PAGE_NAME = "Component Showcase"
CANVAS_WIDTH = 1400
GAP = 20


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


def block(type_: str, w: int, h: int, **kwargs) -> dict:
    """A bare block dict with everything except its layout — flow() below
    fills in x/y once the whole row/container's content is known."""
    b = {"id": uid(), "type": type_, "_w": w, "_h": h}
    b.update(kwargs)
    return b


def flow(items: list[dict], container_width: int, gap: int = GAP, start_y: int = 0) -> tuple[list[dict], int]:
    """Packs `items` left-to-right, wrapping to a new row when the next one
    would overflow container_width, assigning each a "layout" from its own
    _w/_h — the same left-to-right-then-wrap idea pageLayout.ts's
    computeDefaultLayout uses for a single row, just applied once here to
    build an initial, non-overlapping arrangement. Returns (items, total_height)."""
    x = 0
    y = start_y
    row_h = 0
    out = []
    for item in items:
        w, h = item.pop("_w"), item.pop("_h")
        if x > 0 and x + w > container_width:
            x = 0
            y += row_h + gap
            row_h = 0
        item["layout"] = {"x": x, "y": y, "w": w, "h": h}
        out.append(item)
        x += w + gap
        row_h = max(row_h, h)
    total_height = y + row_h + gap
    return out, total_height


def heading(text: str, w: int = CANVAS_WIDTH - 40) -> dict:
    return block("text", w, 36, text=text, text_style="heading")


def sub(text: str, w: int = CANVAS_WIDTH - 40) -> dict:
    return block("text", w, 24, text=text, text_style="subheading")


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

        existing = (
            await db.execute(select(Page).where(Page.tenant_id == TENANT_ID, Page.name == PAGE_NAME))
        ).scalar_one_or_none()
        if existing is not None:
            print(f"'{PAGE_NAME}' already exists (pages.id={existing.id}) — nothing to do.")
            print("Delete that row first if you want to reseed from scratch.")
            return

        masters = {m.name: m for m in (await db.execute(select(Master).where(Master.tenant_id == TENANT_ID))).scalars().all()}
        for needed in ("Office", "Payments", "Payment status", "Payment types"):
            if needed not in masters:
                raise SystemExit(f"expected Master '{needed}' not found — run scripts/import_sample_data.py first")
        office_id = str(masters["Office"].id)
        payments_id = str(masters["Payments"].id)
        payment_status_id = str(masters["Payment status"].id)
        payment_types_id = str(masters["Payment types"].id)

        form = (
            await db.execute(select(Form).where(Form.tenant_id == TENANT_ID, Form.is_current == True))  # noqa: E712
        ).scalars().first()
        form_id = str(form.form_id) if form else None

        admin = (await db.execute(select(User).where(User.tenant_id == TENANT_ID))).scalars().first()

        blocks: list[dict] = []
        y_cursor = 0

        # ---------------------------------------------------------------
        # Intro
        # ---------------------------------------------------------------
        row, dy = flow([heading("Component Showcase")], CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy
        row, dy = flow(
            [block("text", CANVAS_WIDTH - 40, 24, text="One of every Page Designer block type and layout container, wired to real data in this tenant.", text_style="paragraph")],
            CANVAS_WIDTH,
            start_y=y_cursor,
        )
        blocks += row
        y_cursor = dy

        # ---------------------------------------------------------------
        # Content blocks
        # ---------------------------------------------------------------
        row, dy = flow([sub("Content")], CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy

        content_items = [
            block("text", 340, 70, text="A plain text block — heading, subheading, or paragraph style.", text_style="paragraph"),
            block("rich_text", 340, 120, html="<p><strong>Rich Text</strong> — bold, <em>italic</em>, and lists:</p><ul><li>Formatted with a full editor</li><li>Stored as HTML</li></ul>"),
            block("image", 320, 180, image_url="https://picsum.photos/320/180"),
            block("video", 320, 180, video_url="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"),
            block("icon", 60, 60, icon_name="Star"),
            block("button", 160, 40, label="Click Me", button_style="primary"),
            block("html", 320, 120, html="<div style=\"font-family:sans-serif;padding:8px\"><b>Custom HTML block</b><p>Renders inside a sandboxed iframe.</p></div>"),
        ]
        if form_id:
            content_items.append(block("form", 400, 320, data_source=f"form:{form_id}"))
        row, dy = flow(content_items, CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy + 20

        # ---------------------------------------------------------------
        # Data & charts
        # ---------------------------------------------------------------
        row, dy = flow([sub("Data & charts")], CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy

        data_items = [
            block("data_list", 480, 260, data_source=f"master:{office_id}"),
            block("detail_view", 320, 260, data_source=f"master:{office_id}", columns=["name", "city", "phone_number", "email"]),
            block("label", 240, 70, data_source=f"master:{payments_id}", columns=["amount"], label="First payment amount"),
            block("data_grid", 480, 300, data_source=f"master:{payment_status_id}", allow_create=True, allow_edit=True, allow_delete=True),
            block("inbox", 400, 300, data_source=f"master:{office_id}"),
            block("kpi_card", 220, 120, data_source=f"master:{payments_id}", color="#10b981"),
            block("bar_chart", 380, 260, data_source=f"master:{office_id}", color="#4f46e5"),
            block("line_chart", 420, 260, data_source=f"master:{payments_id}", x_field="paid_at", x_bucket="day", series=[{"field": "amount", "aggregate": "sum", "label": "Amount"}], color="#0ea5e9"),
            block("pie_chart", 340, 260, data_source=f"master:{payment_types_id}", color="#f59e0b"),
            block(
                "table",
                480,
                220,
                table_columns=["Leave Type", "Entitlement"],
                table_rows=[["Annual Leave", "18 days"], ["Sick Leave", "12 days"], ["Casual Leave", "8 days"]],
            ),
        ]
        row, dy = flow(data_items, CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy + 20

        # ---------------------------------------------------------------
        # Layout containers
        # ---------------------------------------------------------------
        row, dy = flow([sub("Layout")], CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy

        # Section — titled free-form box
        section_children, section_h = flow(
            [
                block("text", 300, 24, text="Inside a Section", text_style="paragraph"),
                block("button", 140, 40, label="Section button", button_style="secondary"),
            ],
            660,
        )
        section = block("section", 700, section_h + 60, label="Section example", children=section_children)

        # Panel — bordered box, with background/padding/border styling set
        # directly (PreviewBlock already renders these — see
        # components/PageBlockRenderer.tsx — even though the Inspector UI
        # for them isn't built yet, Phase 7).
        panel_children, panel_h = flow(
            [
                block("text", 300, 24, text="Inside a Panel", text_style="paragraph"),
                block("icon", 40, 40, icon_name="Heart"),
            ],
            580,
        )
        panel = block(
            "panel",
            660,
            panel_h + 60,
            label="Panel example (styled)",
            children=panel_children,
            background_color="#f0f9ff",
            padding=16,
            border_color="#0ea5e9",
            border_width=2,
        )
        row, dy = flow([section, panel], CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy

        # Grid — auto-arranging columns
        grid_children = [
            block("icon", 100, 100, icon_name="Rocket"),
            block("icon", 100, 100, icon_name="Globe"),
            block("icon", 100, 100, icon_name="Cloud"),
            block("icon", 100, 100, icon_name="Zap"),
            block("icon", 100, 100, icon_name="Heart"),
            block("icon", 100, 100, icon_name="Star"),
        ]
        for g in grid_children:
            g.pop("_w", None)
            g.pop("_h", None)
        grid = {"id": uid(), "type": "grid", "grid_columns": 3, "grid_gap": 16, "children": grid_children}

        # Tabs — named tabs, each its own free-form box
        tab1_children, tab1_h = flow([block("text", 300, 24, text="First tab's content", text_style="paragraph")], 640)
        tab2_children, tab2_h = flow([block("text", 300, 24, text="Second tab's content", text_style="paragraph")], 640)
        tabs = {
            "id": uid(),
            "type": "tabs",
            "groups": [
                {"id": uid(), "label": "Overview", "children": tab1_children},
                {"id": uid(), "label": "Details", "children": tab2_children},
            ],
        }
        row, dy = flow([{**grid, "_w": 400, "_h": 360}, {**tabs, "_w": 680, "_h": 200}], CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy

        # Accordion — named, expandable free-form boxes
        acc1_children, acc1_h = flow([block("text", 400, 24, text="Expandable section one", text_style="paragraph")], 640)
        acc2_children, acc2_h = flow([block("text", 400, 24, text="Expandable section two", text_style="paragraph")], 640)
        accordion = block(
            "accordion",
            680,
            160,
            groups=[
                {"id": uid(), "label": "Section A", "children": acc1_children},
                {"id": uid(), "label": "Section B", "children": acc2_children},
            ],
        )
        divider = block("divider", 300, 8)
        spacer = block("spacer", 40, 40)
        menu = block("menu", 260, 220)
        row, dy = flow([accordion, divider, spacer, menu], CANVAS_WIDTH, start_y=y_cursor)
        blocks += row
        y_cursor = dy

        page = Page(
            tenant_id=TENANT_ID,
            name=PAGE_NAME,
            blocks=blocks,
            canvas_width=CANVAS_WIDTH,
            status="draft",
            created_by=admin.id if admin else None,
        )
        db.add(page)
        await db.flush()
        await db.commit()
        print(f"Seeded '{PAGE_NAME}' (pages.id={page.id}) under tenant {TENANT_ID} — {len(blocks)} top-level blocks.")


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