from datetime import date

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from app.database import Base
from app.models import Evaluation, Grade, Section, Student, Subject, User
from app.services.article112 import add_business_days, calculate_article112


def make_db():
    engine = create_engine("sqlite:///:memory:")
    Base.metadata.create_all(engine)
    return sessionmaker(bind=engine)()


def seed_evaluation(db, scores):
    user = User(username="doc", full_name="Docente", role="docente", password_hash="x")
    section = Section(name="1ERO A", grade_level="1ERO", letter="A")
    subject = Subject(name="Matemática")
    db.add_all([user, section, subject])
    db.flush()
    evaluation = Evaluation(section_id=section.id, subject_id=subject.id, teacher_id=user.id, title="Prueba")
    db.add(evaluation)
    db.flush()
    for idx, score in enumerate(scores, start=1):
        student = Student(ci=str(1000 + idx), full_name=f"Estudiante {idx}", section_id=section.id)
        db.add(student)
        db.flush()
        db.add(Grade(evaluation_id=evaluation.id, student_id=student.id, score=score, updated_by_id=user.id))
    db.commit()
    db.refresh(evaluation)
    return evaluation


def test_exactly_30_percent_triggers_article112():
    db = make_db()
    evaluation = seed_evaluation(db, [5, 7, 9, 10, 11, 12, 13, 14, 15, 16])
    result = calculate_article112(evaluation, db)
    assert result["failed"] == 3
    assert result["percentage"] == 0.30
    assert result["triggered"] is True


def test_20_percent_does_not_trigger():
    db = make_db()
    evaluation = seed_evaluation(db, [5, 9, 10, 11, 12, 13, 14, 15, 16, 17])
    result = calculate_article112(evaluation, db)
    assert result["failed"] == 2
    assert result["triggered"] is False


def test_three_business_days_skip_weekend():
    assert add_business_days(date(2026, 7, 24), 3) == date(2026, 7, 29)  # viernes -> miércoles
