"""Service for generating matriculation numbers."""

from sqlalchemy.orm import Session

from app.models.application import Application, ApplicationStatus


class MatriculationService:
    """Service for generating unique matriculation numbers."""

    @staticmethod
    def get_department_code(programme: str) -> str:
        """Map programme to department code."""
        programme_lower = programme.lower()
        if "accounting" in programme_lower or "finance" in programme_lower:
            return "ACC"
        elif "computer" in programme_lower or "software" in programme_lower or "artificial intelligence" in programme_lower:
            return "CSC"
        elif "digital media" in programme_lower or "content" in programme_lower or "creative" in programme_lower:
            return "DIG"
        else:
            return "GEN"  # Generic fallback

    @staticmethod
    def generate_matric_number(db: Session, application: Application) -> str:
        """Generate a unique matriculation number in format: POU/YYYY/DEPT/XXXXXX."""
        from datetime import datetime

        year = datetime.now().year
        dept_code = MatriculationService.get_department_code(application.programme)
        
        # Find the highest sequential number for this year and department
        existing_matrics = db.query(Application).filter(
            Application.matric_number.isnot(None),
            Application.status == ApplicationStatus.APPROVED
        ).all()
        
        # Extract sequential numbers for this year and department
        sequential_numbers = []
        prefix = f"POU/{year}/{dept_code}/"
        
        for app in existing_matrics:
            if app.matric_number and app.matric_number.startswith(prefix):
                try:
                    seq_num = int(app.matric_number.split("/")[-1])
                    sequential_numbers.append(seq_num)
                except (ValueError, IndexError):
                    continue
        
        # Get the next sequential number
        if sequential_numbers:
            next_seq = max(sequential_numbers) + 1
        else:
            next_seq = 1
        
        # Format: POU/YYYY/DEPT/XXXXXX (6 digits)
        matric_number = f"{prefix}{next_seq:06d}"
        
        # Ensure uniqueness (in case of race condition)
        while db.query(Application).filter(Application.matric_number == matric_number).first():
            next_seq += 1
            matric_number = f"{prefix}{next_seq:06d}"
        
        return matric_number
