"""filter_data handler — apply column-level filters to a dataset."""
import traceback
import polars as pl

from ..session_store import SessionStore, _generate_id
from ._helpers import _build_filter_expr, _resolve_dataset
import logging
logger = logging.getLogger(__name__)


async def _handle_filter_data(
    dataset_id: str,
    filters: list[dict],
    logic: str = 'and',
) -> dict:
    """Apply filters and store filtered dataset."""
    entry, err = _resolve_dataset(dataset_id)
    if err:
        return err

    lf: pl.LazyFrame = entry['lazyframe']
    full_schema = entry.get('schema', {})

    exprs = [_build_filter_expr(
        f['column'], f.get('op', 'eq'), f.get('value'),
    ) for f in filters]

    if not exprs:
        return {'error': 'No filter expressions could be built', 'truncated': False}

    if logic == 'and':
        combined = exprs[0]
        for e in exprs[1:]:
            combined = combined & e
    else:
        combined = exprs[0]
        for e in exprs[1:]:
            combined = combined | e

    filtered_lf = lf.filter(combined)

    # Estimate row count (fast streaming count)
    try:
        row_count = filtered_lf.select(pl.len()).collect(streaming=True).item()
    except Exception:
        logger.error("unknown failed: {}".format(traceback.format_exc()))
        row_count = None

    new_id = _generate_id('flt')
    store = SessionStore()
    store.store_dataset(
        dataset_id=new_id,
        lazyframe=filtered_lf,
        schema=full_schema,
        metadata={
            'row_count': row_count,
            'parent_dataset_id': dataset_id,
            'filter_count': len(filters),
            'logic': logic,
        },
        parent_id=dataset_id,
    )

    return {
        'filtered_dataset_id': new_id,
        'row_count': row_count,
        'column_deltas': {'kept': list(full_schema.keys()), 'dropped': []},
    }
