import streamlit as st
import pandas as pd

# Import KPI function & fallback loader
from utils.kpi import compute_kpis
from utils.data_loaders import load_all

# Import the new API client (same level as dashboard.py)
from api_client import WarehouseAPI


def _low_stock_table(inventory: pd.DataFrame, default_threshold: int = 100) -> pd.DataFrame:
    """Generate a low stock alert table with safe fallbacks."""
    if inventory is None or inventory.empty:
        return pd.DataFrame()

    # Normalize on_hand column
    if "on_hand" not in inventory.columns:
        for alt in ("qty_on_hand", "quantity", "stock"):
            if alt in inventory.columns:
                inventory = inventory.rename(columns={alt: "on_hand"})
                break
        else:
            inventory["on_hand"] = 0

    # Determine condition logic
    if "reorder_point" in inventory.columns:
        cond = inventory["on_hand"] <= inventory["reorder_point"]
    else:
        cond = inventory["on_hand"] <= default_threshold

    alerts = inventory.loc[cond].copy()

    if not alerts.empty:
        sort_cols = [c for c in ["on_hand", "sku", "warehouse_id"] if c in alerts.columns]
        alerts = alerts.sort_values(sort_cols)

    return alerts


def show() -> None:
    st.subheader("Manager View: Global KPIs & Low-Stock Alerts")

    api = WarehouseAPI()   # Create API client instance

    # Try API first
    try:
        inv = api.get_inventory()
        skus = api.get_products()    # uses get_products() since "skus" no longer exists
        orders = api.get_orders()
        api_ok = True
    except Exception as e:
        st.warning(f"API unavailable, falling back to CSVs. Error: {e}")
        api_ok = False
        inv = skus = orders = None

    # CSV fallback logic
    if not api_ok or any(x is None for x in (inv, skus, orders)):
        data = load_all()
        inv = inv if inv is not None else data["inventory"]
        skus = skus if skus is not None else data["skus"]
        orders = orders if orders is not None else data["orders"]

    # ---- KPI CALCULATION ----
    # Old signature: compute_kpis(orders, order_status, inv, skus)
    # New simplified: compute_kpis(orders, inv, skus)

    kpis = compute_kpis(orders, inv, skus)

    # ---- KPI DISPLAY ----
    c1, c2, c3, c4 = st.columns(4)
    c1.metric("On-time delivery %", f"{kpis.get('on_time_pct', '—')}%")

    inv_val = kpis.get("inventory_value", None)
    c2.metric("Inventory value", f"${inv_val:,}" if isinstance(inv_val, (int, float)) else "—")

    c3.metric("Backorders", kpis.get("backorders", "—"))
    c4.metric("Return rate %", f"{kpis.get('return_rate', '—')}%")

    # ---- LOW STOCK ALERTS ----
    st.markdown("### 🔻 Low-stock alerts")
    alerts = _low_stock_table(inv)

    df_display = alerts.rename(columns={
    "product_id": "Product ID",
    "warehouse_id": "Warehouse",
    "q_on_hand": "On Hand",
    "q_reserved": "Reserved",
    "last_update": "Last Updated",
    "condition": "Condition",
    "sku": "SKU",
    "q_in_transit": "In Transit",
    "reorder_point": "Reorder Point",
    "location": "Location",
    "safety_stock": "Safety Stock",
    "inventory_id": "Inventory ID"
})
    if alerts.empty:
        
        st.dataframe(df_display, use_container_width=True)
    else:
        # st.success("No low-stock items right now ✅")
        st.dataframe(df_display, use_container_width=True)
        


# REQUIRED BY STREAMLIT PAGE ENGINE
show()

# # -----------------------------------------------------------------------------
# # 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, use_container_width=True)
#         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, use_container_width=True)
    
#     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, use_container_width=True)
        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()


import streamlit as st
from utils import api

def show() -> None:
    st.subheader("Clerk View: Transaction Entry & Log")

    with st.form("tx_form", clear_on_submit=True):
        sku = st.text_input("SKU", placeholder="e.g., SKU-12345")
        qty = st.number_input("Quantity", min_value=1, step=1)
        ttype = st.selectbox("Type", ["receive", "ship", "transfer"])
        warehouse = st.text_input("Warehouse ID", placeholder="e.g., 1")
        submitted = st.form_submit_button("Submit transaction")

    if submitted:
        payload = {"sku": sku, "qty": int(qty), "type": ttype, "warehouse": warehouse}
        res = api.post_transaction(payload)
        if res.get("accepted", False):
            st.success("Transaction recorded ✅ (mock if API not available)")
        else:
            st.error("Failed to record transaction. Please try again.")

    st.markdown("### 📜 Recent transactions")
    st.info("Waiting for Transactions API (US3). This list will auto-populate when it’s live.")

show()  
