"""
Convexity SDK - Create Analytic Dashboard

This sample demonstrates how to:
- Verify that the organization, project, connections, and datasets exist
- Create an analytic dashboard with KPI widgets, charts, and tables

Prerequisites:
- A valid API key with WRITE or ADMIN permission
- The "Convexity SDK samples" org, "griffin it" project, Databricks
  connections, and datasets must already exist.
  Run the previous samples in order:
    1. create_org_and_project.py
    2. create_databricks_connections.py
    3. create_datasets.py
"""

import sys
import uuid

from convexity_api_client.models.chart_config import ChartConfig
from convexity_api_client.models.chart_field import ChartField
from convexity_api_client.models.chart_field_transform_type_0 import ChartFieldTransformType0
from convexity_api_client.models.create_dashboard_request import CreateDashboardRequest
from convexity_api_client.models.dashboard_chart_widget import DashboardChartWidget
from convexity_api_client.models.dashboard_layout import DashboardLayout
from convexity_api_client.models.dashboard_sql_chart_widget import DashboardSqlChartWidget
from convexity_api_client.models.dashboard_table_widget import DashboardTableWidget
from convexity_api_client.models.dashboard_text_widget import DashboardTextWidget
from convexity_api_client.models.dashboard_text_widget_text_align_type_0 import DashboardTextWidgetTextAlignType0
from convexity_api_client.models.kpi_chart_config import KpiChartConfig
from convexity_api_client.models.kpi_chart_config_value_format_type_0 import KpiChartConfigValueFormatType0
from convexity_api_client.models.layout_item import LayoutItem
from convexity_api_client.models.line_chart_config import LineChartConfig

from convexity_sdk import ConvexityClient

ORG_SLUG = "convexity-sdk-samples"
PROJECT_SLUG = "griffin-it"

# ── Initialise SDK client ───────────────────────────────────────────────
client = ConvexityClient()


# ── Helper: generate a unique widget ID ─────────────────────────────────
def widget_id() -> str:
    return str(uuid.uuid4())


# ── Step 1: Verify organization exists ──────────────────────────────────
org = client.organizations.get_by_slug(ORG_SLUG)
if org is None or not hasattr(org, "id"):
    print(
        f'ERROR: Organization "{ORG_SLUG}" not found.\nPlease run create_org_and_project.py first.',
        file=sys.stderr,
    )
    raise SystemExit(1)
print(f"Found organization: {org.name} (id={org.id})")

# ── Step 2: Verify project exists ──────────────────────────────────────
project = client.projects.get_by_slug(org.id, PROJECT_SLUG)
if project is None or not hasattr(project, "id"):
    print(
        f'ERROR: Project "{PROJECT_SLUG}" not found in org "{ORG_SLUG}".\nPlease run create_org_and_project.py first.',
        file=sys.stderr,
    )
    raise SystemExit(1)
print(f"Found project: {project.name} (id={project.id})")

# ── Step 3: Verify datasets exist ──────────────────────────────────────
ds_resp = client.datasets.list(project.id)
ds_by_name = {d.name: d for d in ds_resp.datasets}

REQUIRED_DATASETS = [
    "kpi",
    "monthly_demand",
    "item_category_mapping",
    "family_monthly_forecast_12mo",
]
missing = [n for n in REQUIRED_DATASETS if n not in ds_by_name]
if missing:
    print(
        f"ERROR: Dataset(s) {', '.join(missing)} not found.\nPlease run create_datasets.py first.",
        file=sys.stderr,
    )
    raise SystemExit(1)

kpi_ds = ds_by_name["kpi"]
monthly_demand_ds = ds_by_name["monthly_demand"]
item_category_ds = ds_by_name["item_category_mapping"]
forecast_ds = ds_by_name["family_monthly_forecast_12mo"]

print(f"  Found dataset: kpi (id={kpi_ds.id})")
print(f"  Found dataset: monthly_demand (id={monthly_demand_ds.id})")
print(f"  Found dataset: item_category_mapping (id={item_category_ds.id})")
print(f"  Found dataset: family_monthly_forecast_12mo (id={forecast_ds.id})")

# ── Step 4: Build widgets ──────────────────────────────────────────────

# --- Title widget ---
title_id = widget_id()
title_widget = DashboardTextWidget(
    id=title_id,
    title="Dashboard Title",
    show_title=False,
    show_description=False,
    content="# Griffin IT — Analytic Dashboard\nKey metrics, demand trends, and inventory insights at a glance.",
    text_align=DashboardTextWidgetTextAlignType0.CENTER,
    show_border=False,
)

# --- KPI: Total Items ---
kpi_total_items_id = widget_id()
kpi_total_items_widget = DashboardChartWidget(
    id=kpi_total_items_id,
    title="Total Items",
    chart_config=ChartConfig(
        id=widget_id(),
        dataset_id=kpi_ds.id,
        config=KpiChartConfig(
            value_field=ChartField(
                name="total_items",
                display_name="Total Items",
                transform=ChartFieldTransformType0.NONE,
            ),
            value_format=KpiChartConfigValueFormatType0.NUMBER,
            decimal_places=0,
        ),
    ),
)

# --- KPI: Total Inventory Value ---
kpi_inventory_value_id = widget_id()
kpi_inventory_value_widget = DashboardChartWidget(
    id=kpi_inventory_value_id,
    title="Total Inventory Value",
    chart_config=ChartConfig(
        id=widget_id(),
        dataset_id=kpi_ds.id,
        config=KpiChartConfig(
            value_field=ChartField(
                name="total_inventory_value",
                display_name="Inventory Value",
                transform=ChartFieldTransformType0.NONE,
            ),
            value_format=KpiChartConfigValueFormatType0.CURRENCY,
            prefix="$",
            decimal_places=0,
        ),
    ),
)

# --- KPI: In Transit Value ---
kpi_in_transit_id = widget_id()
kpi_in_transit_widget = DashboardChartWidget(
    id=kpi_in_transit_id,
    title="In Transit Value",
    chart_config=ChartConfig(
        id=widget_id(),
        dataset_id=kpi_ds.id,
        config=KpiChartConfig(
            value_field=ChartField(
                name="in_transit_value",
                display_name="In Transit Value",
                transform=ChartFieldTransformType0.NONE,
            ),
            value_format=KpiChartConfigValueFormatType0.CURRENCY,
            prefix="$",
            decimal_places=0,
        ),
    ),
)

# --- Chart: Monthly Demand (line chart) ---
monthly_demand_chart_id = widget_id()
monthly_demand_widget = DashboardChartWidget(
    id=monthly_demand_chart_id,
    title="Monthly Demand",
    chart_config=ChartConfig(
        id=widget_id(),
        dataset_id=monthly_demand_ds.id,
        config=LineChartConfig(
            x=ChartField(name="month"),
            y=ChartField(
                name="demand",
                display_name="Demand",
                transform=ChartFieldTransformType0.SUM,
            ),
        ),
    ),
)

# --- Table: Item Category Mapping ---
item_category_table_id = widget_id()
item_category_widget = DashboardTableWidget(
    id=item_category_table_id,
    title="Item Category Mapping",
    dataset_id=item_category_ds.id,
    page_size=10,
)

# --- Chart: Family Monthly Forecast 12mo (line chart) ---
forecast_chart_id = widget_id()
forecast_widget = DashboardChartWidget(
    id=forecast_chart_id,
    title="Family Monthly Forecast (12mo)",
    chart_config=ChartConfig(
        id=widget_id(),
        dataset_id=forecast_ds.id,
        config=LineChartConfig(
            x=ChartField(name="month"),
            y=ChartField(
                name="forecast_units",
                display_name="Forecast Units",
                transform=ChartFieldTransformType0.SUM,
            ),
        ),
    ),
)

# --- SQL Chart: Monthly Demand by Category (custom SQL) ---
sql_demand_chart_id = widget_id()
sql_demand_widget = DashboardSqlChartWidget(
    id=sql_demand_chart_id,
    title="Monthly Demand by Category (SQL)",
    query="""
    SELECT
        d.month,
        c.product_family,
        SUM(d.demand) AS total_demand
    FROM monthly_demand d
    JOIN item_category_mapping c ON CAST(d.item_id AS INTEGER) = c.item_id
    GROUP BY d.month, c.product_family
    ORDER BY d.month
    """,
    row_limit=1000,
    chart_config=ChartConfig(
        id=f"sqlchart:{sql_demand_chart_id}",
        dataset_id=f"sqlchart:{sql_demand_chart_id}",
        title="Monthly Demand by Category",
        config=LineChartConfig(
            x=ChartField(name="month"),
            y=ChartField(
                name="total_demand",
                display_name="Total Demand",
                transform=ChartFieldTransformType0.SUM,
            ),
            series=ChartField(name="product_family"),
            show_legend=True,
            legend_position="bottom",
        ),
    ),
)

# ── Step 5: Define layout ──────────────────────────────────────────────
# Grid is 24 columns wide.
# Row 0: Title (full width, short)
# Row 2: Three KPI cards side by side
# Row 6: Monthly Demand chart (left half) + Forecast chart (right half)
# Row 14: Item Category Mapping table (full width)
# Row 22: SQL Chart (full width)

layout = DashboardLayout(
    columns=24,
    layouts=[
        LayoutItem(i=title_id, x=0, y=0, w=24, h=2),
        LayoutItem(i=kpi_total_items_id, x=0, y=2, w=8, h=4),
        LayoutItem(i=kpi_inventory_value_id, x=8, y=2, w=8, h=4),
        LayoutItem(i=kpi_in_transit_id, x=16, y=2, w=8, h=4),
        LayoutItem(i=monthly_demand_chart_id, x=0, y=6, w=12, h=8),
        LayoutItem(i=forecast_chart_id, x=12, y=6, w=12, h=8),
        LayoutItem(i=item_category_table_id, x=0, y=14, w=24, h=8),
        LayoutItem(i=sql_demand_chart_id, x=0, y=22, w=24, h=8),
    ],
)

widgets = [
    title_widget,
    kpi_total_items_widget,
    kpi_inventory_value_widget,
    kpi_in_transit_widget,
    monthly_demand_widget,
    item_category_widget,
    forecast_widget,
    sql_demand_widget,
]

# ── Step 6: Create the dashboard ───────────────────────────────────────
print("\nCreating analytic dashboard …")

body = CreateDashboardRequest(
    name="Analytic Dashboard",
    project_id=project.id,
    description="Key metrics, demand trends, and inventory insights for Griffin IT.",
    tags=["analytics", "inventory", "forecast"],
    widgets=widgets,
    layout=layout,
)

dashboard = client.dashboards.create(body=body, project_id=project.id)
if dashboard is None or not hasattr(dashboard, "id"):
    print("ERROR: Failed to create dashboard.", file=sys.stderr)
    raise SystemExit(1)

print(f"  Created dashboard: {dashboard.name} (id={dashboard.id})")
print("\nDone!")
client.close()
