"""HygieneGate — pre-filter for screener."""

from __future__ import annotations

import pandas as pd

from .base import GateNode


class HygieneGate(GateNode):
    name  = "hygiene"
    label = "위생 게이트"
    default_params = {
        "min_market_cap_won": 50_000_000_000,
        "min_avg_value_won":  500_000_000,
        "min_listed_days":    60,
        "skip_managed":       True,
        "skip_preferred":     True,
        "skip_spac":          True,
        "skip_halted_days":   3,
    }
    param_schema = {
        "type": "object",
        "properties": {
            "min_market_cap_won": {"type": "integer", "minimum": 0},
            "min_avg_value_won":  {"type": "integer", "minimum": 0},
            "min_listed_days":    {"type": "integer", "minimum": 0},
            "skip_managed":       {"type": "boolean"},
            "skip_preferred":     {"type": "boolean"},
            "skip_spac":          {"type": "boolean"},
            "skip_halted_days":   {"type": "integer", "minimum": 0},
        },
    }

    def filter(self, ctx, params: dict) -> pd.Index:
        master = ctx.master.copy()
        prices = ctx.prices

        # 시총
        master = master[master["market_cap"].fillna(0) >= params["min_market_cap_won"]]

        # 우선주·관리·스팩
        if params.get("skip_preferred", True):
            master = master[master["is_preferred"] == 0]
        if params.get("skip_managed", True):
            master = master[master["is_managed"] == 0]
        if params.get("skip_spac", True):
            master = master[master["is_spac"] == 0]

        candidates = master.index

        # 20일 평균 거래대금
        if not prices.empty:
            recent20 = (
                prices[prices["ticker"].isin(candidates)]
                .sort_values("date")
                .groupby("ticker")
                .tail(20)
            )
            avg_value = recent20.groupby("ticker")["value"].mean()
            ok = avg_value[avg_value >= params["min_avg_value_won"]].index
            candidates = candidates.intersection(ok)

        # 최근 N일 거래정지 (volume==0 N일 이상)
        halted_days = params.get("skip_halted_days", 3)
        if halted_days > 0 and not prices.empty:
            recent = (
                prices[prices["ticker"].isin(candidates)]
                .sort_values("date")
                .groupby("ticker")
                .tail(halted_days)
            )
            zero_count = (
                recent.assign(z=lambda d: (d["volume"] == 0).astype(int))
                      .groupby("ticker")["z"].sum()
            )
            healthy = zero_count[zero_count < halted_days].index
            candidates = candidates.intersection(healthy)

        # 상장 N일 — MVP에선 listed_date null 허용, null이면 통과
        return pd.Index(candidates)
