# # -----------------------------------------------------------------------------
# # Planner view = Forecasting + Replenishment Suggestions.
# # Expects a forecast source (US4) via API /forecast or a CSV fallback.
# # Also reads inventory so we can compute suggested replenishment = sum(next N days) - on_hand.
# # -----------------------------------------------------------------------------

# import streamlit as st
# import pandas as pd
# from utils import api

# def _normalize_on_hand(df: pd.DataFrame) -> pd.DataFrame:
#     """Make sure 'on_hand' exists for suggestion math."""
#     if "on_hand" not in df.columns:
#         for alt in ("qty_on_hand", "quantity", "stock"):
#             if alt in df.columns:
#                 df = df.rename(columns={alt: "on_hand"})
#                 break
#         else:
#             df["on_hand"] = 0
#     return df

# def _replenishment_suggestions(inventory: pd.DataFrame, forecasts: pd.DataFrame, days: int = 14) -> pd.DataFrame:
#     """
#     Simple heuristic:
#       For each (SKU, warehouse_id), suggested_qty = max(0, sum(next 'days' of forecast) - on_hand)
#     Assumes 'forecasts' includes: ['SKU', 'warehouse_id', 'date', 'forecast'].
#     """
#     if inventory is None or inventory.empty or forecasts is None or forecasts.empty:
#         return pd.DataFrame()

#     inventory = _normalize_on_hand(inventory)

#     # Sum next N days of forecast per SKU/warehouse
#     # If 'date' is string, we do not require parsing for sum since it's just grouped sum over head(days).
#     # A stricter approach would filter by today's date, but this keeps it simple and demo-friendly.
#     horizon = (
#         forecasts
#         .sort_values("date")
#         .groupby(["SKU", "warehouse_id"], as_index=False)
#         .head(days)
#         .groupby(["SKU", "warehouse_id"], as_index=False)["forecast"]
#         .sum()
#         .rename(columns={"forecast": "forecast_horizon"})
#     )

#     merged = inventory.merge(
#         horizon, left_on=["sku", "warehouse_id"], right_on=["SKU", "warehouse_id"], how="left"
#     )
#     merged["forecast_horizon"] = merged["forecast_horizon"].fillna(0)
#     merged["suggested_qty"] = (merged["forecast_horizon"] - merged["on_hand"]).clip(lower=0).astype(int)

#     # Friendly column subset if present
#     keep = [c for c in ["sku", "warehouse_id", "on_hand", "forecast_horizon", "suggested_qty"] if c in merged.columns]
#     return merged[keep].sort_values("suggested_qty", ascending=False)

# def show() -> None:
#     st.subheader("Planner View: Forecasting & Replenishment Suggestions")

#     forecasts = api.get_forecasts()         # US4 endpoint (or CSV fallback)
#     inv = api.get_inventory()               # needed for on_hand

#     # Help users see something even if US4 isn't up yet
#     if forecasts is None or forecasts.empty:
#         st.info("Forecast API/CSV not found yet (US4). Showing a small placeholder so the page renders.")
#         sample = pd.DataFrame([{
#             "SKU": "SKU-EXAMPLE", "warehouse_id": 1, "date": "2025-10-01",
#             "forecast": 5, "projected_stockout_date": "2025-11-02"
#         }])
#         st.dataframe(sample, width='stretch')
#         return

#     # Optional: visualization with simple filters
#     with st.expander("📈 Show forecast lines"):
#         sku_list = sorted(forecasts["SKU"].unique().tolist())
#         wh_list = sorted(forecasts["warehouse_id"].unique().tolist())
#         sku_sel = st.multiselect("Select SKU(s)", sku_list, sku_list[:1])
#         wh_sel = st.multiselect("Select warehouse(s)", wh_list, wh_list[:1])

#         filtered = forecasts[
#             forecasts["SKU"].isin(sku_sel) & forecasts["warehouse_id"].isin(wh_sel)
#         ]
#         if not filtered.empty:
#             # Pivot to plot per SKU/warehouse
#             pivot = filtered.pivot_table(
#                 index="date", columns=["SKU", "warehouse_id"], values="forecast", aggfunc="sum"
#             )
#             st.line_chart(pivot)
#         else:
#             st.write("Select at least one SKU and warehouse to see a chart.")

#     # Suggestions table (needs both inv + forecasts)
#     if inv is None or inv.empty:
#         st.warning("Inventory data not available; replenishment suggestions require inventory on-hand.")
#         return

#     st.markdown("### 📦 Replenishment suggestions (next 14 days)")
#     suggestions = _replenishment_suggestions(inv, forecasts, days=14)
#     st.dataframe(suggestions, width='stretch')
    
#     show()

# -------------------------------------------------------------------------
# Planner View: Forecasting + Replenishment Suggestions
# Uses WarehouseAPI instead of old utils.api
# -------------------------------------------------------------------------

import streamlit as st
import pandas as pd

# New API client
from api_client import WarehouseAPI


# ------------------------- Normalization Helpers -------------------------

def _normalize_on_hand(df: pd.DataFrame) -> pd.DataFrame:
    """Ensure on_hand column exists."""
    if "on_hand" not in df.columns:
        for alt in ("qty_on_hand", "quantity", "stock"):
            if alt in df.columns:
                df = df.rename(columns={alt: "on_hand"})
                break
        else:
            df["on_hand"] = 0
    return df


def _normalize_sku(df: pd.DataFrame) -> pd.DataFrame:
    """Make sure sku column exists and is standardized."""
    for col in ["SKU", "sku_id", "sku_code", "item_sku"]:
        if col in df.columns:
            return df.rename(columns={col: "sku"})
    return df


# ------------------------- Replenishment Logic ---------------------------

def _replenishment_suggestions(inventory: pd.DataFrame, forecasts: pd.DataFrame, days: int = 14) -> pd.DataFrame:
    """
    For each SKU + warehouse:
        suggested_qty = max(0, 14-day-forecast-total - on_hand)
    """
    if inventory is None or inventory.empty or forecasts is None or forecasts.empty:
        return pd.DataFrame()

    inventory = _normalize_on_hand(_normalize_sku(inventory))
    forecasts = _normalize_sku(forecasts)

    # Forecast must have `sku`, not `SKU`
    if "SKU" in forecasts.columns:
        forecasts = forecasts.rename(columns={"SKU": "sku"})

    # Sum next N days of forecast per SKU + warehouse
    horizon = (
        forecasts.sort_values("date")
        .groupby(["sku", "warehouse_id"], as_index=False)
        .head(days)
        .groupby(["sku", "warehouse_id"], as_index=False)["forecast"]
        .sum()
        .rename(columns={"forecast": "forecast_horizon"})
    )

    # Merge with inventory
    merged = inventory.merge(
        horizon,
        on=["sku", "warehouse_id"],
        how="left"
    )

    merged["forecast_horizon"] = merged["forecast_horizon"].fillna(0)
    merged["suggested_qty"] = (merged["forecast_horizon"] - merged["on_hand"]).clip(lower=0).astype(int)

    keep = [c for c in ["sku", "warehouse_id", "on_hand", "forecast_horizon", "suggested_qty"] if c in merged.columns]
    return merged[keep].sort_values("suggested_qty", ascending=False)


# ------------------------- Streamlit Page -------------------------

def show() -> None:
    st.subheader("Planner View: Forecasting & Replenishment Suggestions")

    api = WarehouseAPI()

    # Load data
    try:
        # forecasts = api.get_forecasts()
        forecasts = None
        inventory = api.get_inventory()
    except Exception as e:
        st.error(f"API Error: {e}")
        return

    # If forecast missing → show placeholder
    if forecasts is None or forecasts.empty:
        st.info("Forecast API not ready. Showing placeholder...")
        sample = pd.DataFrame([{
            "sku": "SKU-EXAMPLE",
            "warehouse_id": 1,
            "date": "2025-10-01",
            "forecast": 5,
            "projected_stockout_date": "2025-11-02"
        }])
        st.dataframe(sample, width='stretch')
        return

    # Normalize SKU column
    forecasts = _normalize_sku(forecasts)
    inventory = _normalize_sku(inventory)

    # ------------------- Forecast Visualization -------------------

    with st.expander("📈 Show forecast lines"):
        sku_list = sorted(forecasts["sku"].unique().tolist())
        wh_list = sorted(forecasts["warehouse_id"].unique().tolist())

        sku_sel = st.multiselect("Select SKU(s)", sku_list, sku_list[:1])
        wh_sel = st.multiselect("Select warehouses(s)", wh_list, wh_list[:1])

        filtered = forecasts[
            forecasts["sku"].isin(sku_sel) & forecasts["warehouse_id"].isin(wh_sel)
        ]

        if not filtered.empty:
            pivot = filtered.pivot_table(
                index="date",
                columns=["sku", "warehouse_id"],
                values="forecast",
                aggfunc="sum"
            )
            st.line_chart(pivot)
        else:
            st.write("Select at least one SKU and warehouse.")

    # ------------------- Replenishment Suggestions -------------------

    if inventory is None or inventory.empty:
        st.warning("Inventory data unavailable — cannot compute suggestions.")
        return

    st.markdown("### 📦 Replenishment Suggestions (Next 14 Days)")
    suggestions = _replenishment_suggestions(inventory, forecasts, days=14)

    st.dataframe(suggestions, width='stretch')


# REQUIRED FOR STREAMLIT PAGE RENDERING
show()
