from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import select, func
from typing import Optional

from app.core.deps import DB, CurrentUser, require_parent
from app.models.user import User, StudentProfile, ParentProfile, ParentStudentLink
from app.models.progress import PlayerProgress, AcademicProgressSummary, PlayerAward, Award
from app.models.school import School, SchoolStudentEnrollment
from app.schemas.user import LinkStudentRequest

router = APIRouter(
    prefix="/parents", tags=["Parents"], dependencies=[Depends(require_parent)]
)


@router.get("/profile", summary="Get Parent Profile")
async def get_parent_profile(current_user: CurrentUser, db: DB):
    result = await db.execute(
        select(ParentProfile).where(ParentProfile.user_id == current_user.id)
    )
    profile = result.scalar_one_or_none()
    return {"user": current_user, "profile": profile}


@router.post("/link-student", summary="Link a Student by STEM ID")
async def link_student(data: LinkStudentRequest, current_user: CurrentUser, db: DB):
    """
    Link a student to this parent account using the student's portable STEM ID.
    Relationship type: mother/father/guardian/other
    """
    student = await db.execute(
        select(User).where(User.stem_id == data.student_stem_id, User.role == "student")
    )
    student_user = student.scalar_one_or_none()
    if not student_user:
        raise HTTPException(status_code=404, detail="Student with that STEM ID not found")

    # Check not already linked
    existing = await db.execute(
        select(ParentStudentLink).where(
            ParentStudentLink.parent_user_id == current_user.id,
            ParentStudentLink.student_user_id == student_user.id,
        )
    )
    if existing.scalar_one_or_none():
        raise HTTPException(status_code=400, detail="Already linked to this student")

    link = ParentStudentLink(
        parent_user_id=current_user.id,
        student_user_id=student_user.id,
        relationship_type=data.relationship_type,
        is_primary_guardian=data.is_primary_guardian,
    )
    db.add(link)
    await db.commit()
    return {
        "message": f"Successfully linked to student {student_user.full_name}",
        "student_stem_id": student_user.stem_id,
    }


@router.delete("/unlink-student/{student_stem_id}", summary="Unlink a Student")
async def unlink_student(student_stem_id: str, current_user: CurrentUser, db: DB):
    student = await db.execute(select(User).where(User.stem_id == student_stem_id))
    student_user = student.scalar_one_or_none()
    if not student_user:
        raise HTTPException(status_code=404, detail="Student not found")

    result = await db.execute(
        select(ParentStudentLink).where(
            ParentStudentLink.parent_user_id == current_user.id,
            ParentStudentLink.student_user_id == student_user.id,
        )
    )
    link = result.scalar_one_or_none()
    if not link:
        raise HTTPException(status_code=404, detail="Link not found")

    await db.delete(link)
    await db.commit()
    return {"message": "Student unlinked"}


@router.get("/children", summary="Get My Linked Children")
async def get_children(current_user: CurrentUser, db: DB):
    """Get all students linked to this parent."""
    result = await db.execute(
        select(User, StudentProfile, ParentStudentLink)
        .join(ParentStudentLink, User.id == ParentStudentLink.student_user_id)
        .outerjoin(StudentProfile, User.id == StudentProfile.user_id)
        .where(ParentStudentLink.parent_user_id == current_user.id)
    )
    rows = result.all()
    return [
        {
            "stem_id": row.User.stem_id,
            "full_name": row.User.full_name,
            "relationship": row.ParentStudentLink.relationship_type,
            "is_primary_guardian": row.ParentStudentLink.is_primary_guardian,
            "total_xp": row.StudentProfile.total_xp if row.StudentProfile else 0,
            "level_rank": row.StudentProfile.level_rank if row.StudentProfile else 1,
            "streak_days": row.StudentProfile.streak_days if row.StudentProfile else 0,
        }
        for row in rows
    ]


@router.get("/children/{student_stem_id}/progress", summary="Get Child Progress")
async def get_child_progress(student_stem_id: str, current_user: CurrentUser, db: DB):
    """Get detailed learning progress for a linked child."""
    # Verify parent-child relationship
    student = await db.execute(select(User).where(User.stem_id == student_stem_id))
    student_user = student.scalar_one_or_none()
    if not student_user:
        raise HTTPException(status_code=404, detail="Student not found")

    link = await db.execute(
        select(ParentStudentLink).where(
            ParentStudentLink.parent_user_id == current_user.id,
            ParentStudentLink.student_user_id == student_user.id,
        )
    )
    if not link.scalar_one_or_none():
        raise HTTPException(status_code=403, detail="Not linked to this student")

    progress = await db.execute(
        select(AcademicProgressSummary).where(
            AcademicProgressSummary.student_user_id == student_user.id
        )
    )
    awards = await db.execute(
        select(PlayerAward, Award)
        .join(Award)
        .where(PlayerAward.student_user_id == student_user.id)
        .order_by(PlayerAward.earned_at.desc())
        .limit(10)
    )

    return {
        "student": {
            "stem_id": student_user.stem_id,
            "full_name": student_user.full_name,
        },
        "academic_summary": progress.scalars().all(),
        "recent_awards": [
            {"award": r.Award, "earned_at": r.PlayerAward.earned_at}
            for r in awards.all()
        ],
    }


@router.get("/children/{student_stem_id}/school", summary="Get Child's School")
async def get_child_school(student_stem_id: str, current_user: CurrentUser, db: DB):
    student = await db.execute(select(User).where(User.stem_id == student_stem_id))
    student_user = student.scalar_one_or_none()
    if not student_user:
        raise HTTPException(status_code=404, detail="Student not found")

    link = await db.execute(
        select(ParentStudentLink).where(
            ParentStudentLink.parent_user_id == current_user.id,
            ParentStudentLink.student_user_id == student_user.id,
        )
    )
    if not link.scalar_one_or_none():
        raise HTTPException(status_code=403, detail="Not linked to this student")

    result = await db.execute(
        select(SchoolStudentEnrollment, School)
        .join(School)
        .where(
            SchoolStudentEnrollment.student_user_id == student_user.id,
            SchoolStudentEnrollment.is_active == True,
        )
    )
    row = result.first()
    if not row:
        return {"enrolled": False}
    return {
        "enrolled": True,
        "school_name": row.School.school_name,
        "city": row.School.city,
        "enrollment_date": row.SchoolStudentEnrollment.enrollment_date,
    }


@router.get("/subscription", summary="My Subscription Status")
async def get_subscription(current_user: CurrentUser, db: DB):
    from app.services.subscription_service import check_premium_access
    return await check_premium_access(db, current_user.id)
