from __future__ import annotations
from typing import Dict
import polars as pl
from tools.base import BaseTool


class CrossTabTool(BaseTool):
    def execute(self, inputs: Dict[str, pl.DataFrame]) -> Dict[str, pl.DataFrame]:
        df = inputs.get("Input", pl.DataFrame())
        if self.config is None or df.is_empty():
            return {"Output": df}

        header_el = self.config.find("HeaderField")
        data_el = self.config.find("DataField")
        if header_el is None or data_el is None:
            return {"Output": df}

        header_field = header_el.attrib.get("field", "")
        data_field = data_el.attrib.get("field", "")
        method = data_el.attrib.get("method", "Sum").upper()
        groups = [
            f.attrib["name"]
            for f in self.config.findall("GroupFields/Field")
            if f.attrib["name"] in df.columns
        ]

        if not header_field or not data_field:
            return {"Output": df}

        con = self.ctx.duckdb_con
        con.register("__ct_input__", df.to_arrow())

        group_clause = ", ".join(f'"{g}"' for g in groups) if groups else "1"
        agg_methods = {
            "SUM": "SUM", "COUNT": "COUNT", "AVG": "AVG", "MIN": "MIN",
            "MAX": "MAX", "FIRST": "FIRST", "LAST": "LAST",
        }
        agg_fn = agg_methods.get(method, "SUM")

        sql = f"""
            PIVOT __ct_input__
            ON "{header_field}"
            USING {agg_fn}("{data_field}")
            GROUP BY {group_clause}
        """
        try:
            result = pl.from_arrow(con.execute(sql).arrow())
        except Exception as e:
            raise RuntimeError(f"CrossTab PIVOT failed: {e}") from e
        finally:
            con.execute("DROP VIEW IF EXISTS __ct_input__")

        return {"Output": result}
