"""Data ingestion agent"""
from sqlalchemy.orm import Session
from datetime import datetime, timedelta
import logging
from typing import Optional
from app.agents.base import BaseAgent
from app.data_sources.base import BaseDataSource
from app.data_sources.flashscore.source import FlashscoreSource
from app.data_sources.mock_source import MockSource
from app.core.config import settings
from app.core.db.repositories.match_repository import MatchRepository
from app.core.db.repositories.team_repository import TeamRepository
from app.core.db.repositories.league_repository import LeagueRepository
from app.core.db.models.match import Match, MatchStatus
from app.core.db.models.team import Team
from app.core.db.models.sport import League

logger = logging.getLogger(__name__)


class DataIngestAgent(BaseAgent):
    """Agent for ingesting match data from external sources"""
    
    def __init__(self, db: Session):
        super().__init__(db, "DataIngestAgent")
        self.match_repo = MatchRepository(db)
        self.team_repo = TeamRepository(db)
        self.league_repo = LeagueRepository(db)
        
        # Initialize data source
        if settings.flashscore_enabled:
            try:
                self.data_source: BaseDataSource = FlashscoreSource()
            except Exception as e:
                self.db.rollback()
                logger.warning(f"Failed to initialize Flashscore, using mock: {e}")
                self.data_source = MockSource()
        else:
            self.data_source = MockSource()
    
    def run(self) -> bool:
        """Run data ingestion"""
        run_id = self.start_run()
        matches_processed = 0
        records_created = 0
        records_updated = 0
        
        try:
            # Get leagues
            leagues_data = self.data_source.get_leagues("football")
            logger.info(f"Found {len(leagues_data)} leagues")
            
            for league_data in leagues_data[:5]:  # Limit for MVP
                # Get or create league
                league = self.league_repo.get_by_source_id(league_data.source_id)
                if not league:
                    country_id = None
                    if league_data.country:
                        country_id = self.league_repo.get_or_create_country(league_data.country).id
                    league = League(
                        source_id=league_data.source_id,
                        name=league_data.name,
                        country_id=country_id,
                        code=f"league_{league_data.source_id}"
                    )
                    league = self.league_repo.create(league)
                    records_created += 1
                
                # Get matches for the next 30 days
                from_date = datetime.now()
                to_date = from_date + timedelta(days=30)
                
                matches_data = self.data_source.get_matches(
                    league_data.source_id,
                    from_date=from_date,
                    to_date=to_date
                )
                
                logger.info(f"Found {len(matches_data)} matches for {league.name}")
                
                for match_data in matches_data:
                    # Get or create teams
                    home_team = self.team_repo.get_or_create_by_source_id(
                        f"{league_data.source_id}_{match_data.home_team_name}",
                        match_data.home_team_name
                    )
                    away_team = self.team_repo.get_or_create_by_source_id(
                        f"{league_data.source_id}_{match_data.away_team_name}",
                        match_data.away_team_name
                    )
                    
                    # Get or create match
                    existing_match = self.match_repo.get_by_source_id(match_data.source_id)
                    
                    if existing_match:
                        # Update existing match
                        existing_match.status = match_data.status
                        if match_data.home_score is not None:
                            existing_match.home_score = match_data.home_score
                        if match_data.away_score is not None:
                            existing_match.away_score = match_data.away_score
                        existing_match.match_date = match_data.match_date
                        existing_match = self.match_repo.update(existing_match)
                        records_updated += 1
                    else:
                        # Create new match
                        match = Match(
                            league_id=league.id,
                            home_team_id=home_team.id,
                            away_team_id=away_team.id,
                            match_date=match_data.match_date,
                            status=match_data.status,
                            home_score=match_data.home_score,
                            away_score=match_data.away_score,
                            source_id=match_data.source_id,
                            source_url=match_data.source_url
                        )
                        match = self.match_repo.create(match)
                        records_created += 1
                    
                    matches_processed += 1
            
            # Update run statistics
            run = self.run_repo.get_by_id(run_id)
            if run:
                run.matches_processed = matches_processed
                run.records_created = records_created
                run.records_updated = records_updated
                self.db.commit()
            
            self.finish_run(success=True)
            logger.info(f"Ingested {matches_processed} matches, created {records_created}, updated {records_updated}")
            return True
            
        except Exception as e:
            error_msg = str(e)
            logger.error(f"Data ingestion failed: {error_msg}", exc_info=True)
            self.finish_run(success=False, error=error_msg)
            return False
        finally:
            if hasattr(self.data_source, 'close'):
                self.data_source.close()

