from __future__ import annotations

import pandas as pd


def read_stock_metadata(path: str) -> pd.DataFrame:
    frame = pd.read_csv(path)
    aliases = {
        "scrip": "symbol", "ticker": "symbol", "company": "company_name", "name": "company_name",
        "sector_name": "sector", "status": "listing_status", "ISIN": "isin",
    }
    frame = frame.rename(columns={column: aliases.get(str(column).strip(), str(column).strip().lower()) for column in frame.columns})
    if "symbol" not in frame:
        raise ValueError("Metadata file requires symbol/SCRIP/ticker")
    frame["symbol"] = frame["symbol"].astype("string").str.strip().str.upper()
    return frame


def build_stock_master(equities: pd.DataFrame, metadata: pd.DataFrame | None = None) -> pd.DataFrame:
    if equities.empty:
        return pd.DataFrame(columns=[
            "symbol", "company_name", "sector", "listing_status", "first_seen_date", "last_seen_date",
            "isin", "listed_since", "market",
        ])
    ordered = equities.sort_values(["symbol", "date"])
    grouped = ordered.groupby("symbol", sort=True)
    master = grouped["date"].agg(first_seen_date="min", last_seen_date="max").reset_index()
    for column in ("company_name", "sector"):
        if column in ordered:
            values = grouped[column].agg(lambda series: series.dropna().iloc[-1] if series.notna().any() else pd.NA)
            master = master.merge(values.rename(column).reset_index(), on="symbol", how="left")
        else:
            master[column] = pd.NA
    master["listing_status"] = "UNKNOWN"
    for column in ("isin", "listed_since", "market"):
        master[column] = pd.NA
    if metadata is not None and not metadata.empty:
        normalized = metadata.copy()
        normalized["symbol"] = normalized["symbol"].astype("string").str.strip().str.upper()
        available = [column for column in ("symbol", "company_name", "sector", "listing_status", "isin", "listed_since", "market") if column in normalized]
        normalized = normalized[available].drop_duplicates("symbol", keep="last")
        master = master.set_index("symbol")
        normalized = normalized.set_index("symbol")
        for column in normalized.columns:
            values = normalized[column].to_dict()
            master[column] = [
                values.get(symbol)
                if pd.notna(values.get(symbol, pd.NA)) else master.at[symbol, column]
                for symbol in master.index
            ]
        master = master.reset_index()
    return master.sort_values("symbol").reset_index(drop=True)
