"""Feature engineering agent"""
from sqlalchemy.orm import Session
from datetime import datetime, timedelta
import logging

from app.agents.base import BaseAgent
from app.core.db.repositories.match_repository import MatchRepository
from app.ml.features import FeatureBuilder
from app.core.db.models.feature import Feature

logger = logging.getLogger(__name__)


class FeatureAgent(BaseAgent):
    """Agent for building features"""

    def __init__(self, db: Session):
        super().__init__(db, "FeatureAgent")
        self.match_repo = MatchRepository(db)
        self.feature_builder = FeatureBuilder(db)

    def run(self) -> bool:
        """Run feature engineering"""
        run_id = self.start_run()

        processed = 0
        created = 0
        updated = 0

        try:
            now = datetime.now()

            # upcoming window
            upcoming_from = now - timedelta(days=30)
            upcoming_to = now + timedelta(days=30)

            # training window (2 years finished)
            finished_from = now - timedelta(days=365 * 2)
            finished_to = None  # include 'finished' even if kickoff_at is in the future
            upcoming = self.match_repo.get_upcoming(
                from_date=upcoming_from,
                to_date=upcoming_to,
                limit=2000
            )
            finished = self.match_repo.get_finished(
                from_date=finished_from,
                to_date=finished_to,
                limit=5000
            )

            # unique by match.id (avoid duplicates)
            seen = set()
            all_matches = []
            for m in list(upcoming) + list(finished):
                if m.id in seen:
                    continue
                seen.add(m.id)
                all_matches.append(m)

            logger.info(f"Building features for {len(all_matches)} matches (upcoming={len(upcoming)}, finished={len(finished)})")

            for m in all_matches:
                processed += 1

                existing = self.db.query(Feature).filter(Feature.match_id == m.id).first()
                feat = self.feature_builder.build_features_for_match(m)

                if existing:
                    # copy fields from feat to existing (keep match_id)
                    for col in Feature.__table__.columns.keys():
                        if col in ("id", "match_id"):
                            continue
                        if hasattr(feat, col):
                            setattr(existing, col, getattr(feat, col))
                    existing.calculated_at = datetime.utcnow()
                    updated += 1
                else:
                    self.db.add(feat)
                    created += 1

                if processed % 100 == 0:
                    self.db.commit()
                    logger.info(f"Processed {processed} features (created={created}, updated={updated})")

            self.db.commit()

            run = self.run_repo.get_by_id(run_id)
            if run:
                run.records_created = created
                run.records_updated = updated
                self.db.commit()

            self.finish_run(success=True)
            logger.info(f"Features done: created={created}, updated={updated}, processed={processed}")
            return True

        except Exception as e:
            error_msg = str(e)
            logger.error(f"Feature engineering failed: {error_msg}", exc_info=True)
            self.db.rollback()
            self.finish_run(success=False, error=error_msg)
            return False
