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


class JoinMultipleTool(BaseTool):
    def execute(self, inputs: Dict[str, pl.DataFrame]) -> Dict[str, pl.DataFrame]:
        if self.config is None:
            return {"Output": pl.DataFrame()}

        sorted_keys = sorted(
            inputs.keys(),
            key=lambda k: int(k.replace("Input", "").lstrip("#") or "0"),
        )
        dfs = [inputs[k] for k in sorted_keys]
        if not dfs:
            return {"Output": pl.DataFrame()}

        by_pos = self._cfg_attr("JoinByRecPos", "value", "True") == "True"
        output_join_only = self._cfg_attr("OutputJoinOnly", "value", "False") == "True"

        # Prefix all columns with Input_#N_
        prefixed: list[pl.DataFrame] = []
        for i, df in enumerate(dfs, start=1):
            prefix = f"Input_#{i}_"
            renamed = {c: f"{prefix}{c}" for c in df.columns}
            prefixed.append(df.rename(renamed))

        if by_pos:
            # Join by row position — add index then join on it
            indexed = [df.with_row_index(f"__pos_{i}__") for i, df in enumerate(prefixed)]
            result = indexed[0]
            for i in range(1, len(indexed)):
                lk = f"__pos_{0}__"
                rk = f"__pos_{i}__"
                result = result.join(indexed[i], left_on=lk, right_on=rk, how="inner")
            pos_cols = [f"__pos_{i}__" for i in range(len(indexed)) if f"__pos_{i}__" in result.columns]
            result = result.drop(pos_cols)
        else:
            # Join by named fields — best effort: join first pair, then extend
            result = prefixed[0]
            for i in range(1, len(prefixed)):
                result = pl.concat([result, prefixed[i]], how="diagonal_relaxed")

        return {"Output": result}
