from datetime import date
from typing import Optional

from fastapi import Depends, APIRouter, Query
from pydantic import BaseModel

from core.config import get_db
from core.security.authentication import get_user
from models import Attendance, CourseAllocation, Payment, Course, Participant, PaymentDetails
from schema import GenericResponse
from schema.attendance import AttendanceCreateSchema, AttendanceFilterSchema
from services.attendance import AttendanceService
from services.report import ReportService

attendance_router = APIRouter(prefix="/attendance")

#TODO: FIXED add has_attendance_management
#TODO : FIXED attendance upsert API
# TODO :  Change timezone in server UK
#TODO: FIXED : view attendance in staff
"""
course_id , staff_id,attendance_date => participant name, status
"""

#TODO :FIXED  view attendance in parent & 18 above:
"""

filter: participant id,academic_year id, term _id, course id

"""
#TODO:Fixed view attendance in admin
"""
academic_year_id,term_id,attendance_date(mandatory) , course_category_id,course_id
"""

#TODO : Fixed admin can edit attendance data
#TODO : FIXED add field modified by admin -yes/no attendance date,
#TODO: Export
"""
FIXED
*Attendance history
    filter : academic_year_id:M,term_id:M ,from_date, end_date, course_id, course_category_id
    response: first_name,last_name, course_name,age_group,at_date,tutor_name, attandance status
    report: first_name,last_name,reg_id,parent_name,parent_last_last_name,term,course,age_group of course,attendance mark_date, class_start_time,tutor_name,attendance_status (P:B)

FIXED
*Student data registered data (view report api, data download api)
    
    filter  : gender,age,consents,fields=[first_name,]
    
    response: participant_name,parent_name, parent_email, parent_mobile_number , participant age
    report_data=fields[]+mandatory fields


*student  enrolled data:
     filter : academic year_id, term_id : NM,age_group_id, course_category_id, course_id
     response : participant_name,participant age ,parent_name,parent email,id parent mbile number,particpant, email, gender,
     report : same as response

"""

#TODO: FIXED --  payment history = transaction_date,total_amount,batch_id, parent_email,parent_mobile,payment status
#TODO: FIXED -- payment history details = participnat_name, course_id,amount,bursary,wallet_used,orginal ,amount
#TODO : FIXED SKU unique
#TODO: FIXED Wallet credit & debit also

@attendance_router.get("/allocated_course/{staff_id}", response_model=GenericResponse)
async def get_allocated_course_list_by_staff(staff_id: int, academic_year_id: str = Query(None),
                                             term_id: str = Query(None), course_name: str = Query(None),
                                             user=Depends(get_user), service=Depends(AttendanceService)):


    with get_db() as db:
        query = db.query(CourseAllocation).join(Course, Course.id == CourseAllocation.course_id).filter(
            CourseAllocation.staff_id == staff_id)
        if academic_year_id:
            query = query.filter(Course.academic_year_id == academic_year_id)

        if term_id:
            query = query.filter(Course.term_id == term_id)
        if course_name:
            query = query.filter(Course.name.icontains(course_name))

        data = []
        for row in query.all():
            data.append({
                "course_id": row.course_id,
                "course_name": row.course.name,
                "age": row.course.age_group.label,
                "term": row.course.term.name,
                "course_start_date": row.course.start_date,
                "course_end_date": row.course.end_date,
                "course_start_time": row.course.start_time,
                "course_end_time": row.course.end_time,
                "role_id": row.role_id,
                "role": row.role.label,
                "has_attendance_management":row.role.has_attendance_management
            })

    return {"message": "course populated successfully.", "data": data}


@attendance_router.get("/list_participant/{course_id}", response_model=GenericResponse)
async def list_participant_under_course(course_id: int, user=Depends(get_user), service=Depends(AttendanceService)):
    with get_db() as db:
        query = (
            db.query(PaymentDetails)
            .join(PaymentDetails.payment)  # join Payment table via relationship
            .filter(
                PaymentDetails.course_id == course_id,
                Payment.is_payment_completed == True
            )
            .all()
        )

        data = []
        for row in query:
            data.append({
                "participant_id": row.purchased_for_id,
                "participant_first_name": row.purchased_participant.first_name,
                "participant_last_name": row.purchased_participant.last_name,
                "course_id": row.course_id
            })

    return {"message": "participant populated successfully.", "data": data}


@attendance_router.post("/marking", response_model=GenericResponse)
async def create_attendance(request: AttendanceCreateSchema, user=Depends(get_user),
                            service=Depends(AttendanceService)):
    service.save(request)
    return {"message": "Attendance updated successfully."}


@attendance_router.get("/marking/{staff_id}/{course_id}", response_model=GenericResponse)
async def list_attendance_by_staff_id(staff_id: int,course_id:int, user=Depends(get_user), service=Depends(AttendanceService)):
    with get_db() as db:
        query = db.query(Attendance).filter(Attendance.staff_id == staff_id,Attendance.course_id==course_id).all()
        data = []
        for row in query:
            data.append({
                "staff_id": row.staff_id,
                "course_id": row.course_id,
                "participant_id": row.participant_id,
                "attendance_status": row.attendance_status,
                "attendance_date": row.attendance_date,
                "remarks": row.remarks,
                "course": dict(name=row.course.name, id=row.course.id),
                "participant": dict(first_name=row.participant.first_name, id=row.participant.id,
                                    last_name=row.participant.last_name)
            })
    return {"message": "Attendance populated successfully.", "data": data}


@attendance_router.post("/filter", response_model=GenericResponse)
async def attendance_filter(request: AttendanceFilterSchema, user=Depends(get_user),
                            service=Depends(AttendanceService)):
    with get_db() as db:
        query = db.query(Attendance).filter(Attendance.participant_id == request.participant_id)
        if request.course_id:
            query = query.filter(Attendance.course_id == request.course_id)
        if request.participant_name:
            query = query.join(Participant, Attendance.participant_id == Participant.id).filter(
                Participant.first_name.icontains(request.particippant_name))
        data = []
        for row in query.all():
            data.append({
                "staff_id": row.staff_id,
                "course_id": row.course_id,
                "participant_id": row.participant_id,
                "attendance_status": row.attendance_status,
                "attendance_date": row.attendance_date,
                "remarks": row.remarks,
                "course": dict(name=row.course.name, id=row.course.id),
                "participant": dict(first_name=row.participant.first_name, id=row.participant.id,
                                    last_name=row.participant.last_name)
            })
    return {"message": "Attendance populated successfully.", "data": data}


# New APIS
#course_id , staff_id,attendance_date => participant name, status

class AttendanceViewByStaff(BaseModel):
    course_id:int=None
    staff_id:int=None
    attendance_date:Optional[date]=None

@attendance_router.post("/staff")
async def staff_attendance_view( request:AttendanceViewByStaff,user=Depends(get_user),
                            service=Depends(AttendanceService)):
    data=service.view_attendance_from_staff(request,user)
    return {"message": "Attendance populated successfully.", "data": data}

class AttendanceViewByParent(BaseModel):
    participant_id:int
    academic_year_id:Optional[int]=None
    term_id: Optional[int] = None
    course_id:Optional[int]=None
    attendance_date:Optional[date]=None

@attendance_router.post("/parent")
async def parent_attendance_view( request:AttendanceViewByParent,user=Depends(get_user),
                            service=Depends(AttendanceService)):
    data=service.view_attendance_from_parent(request,user)
    return {"message": "Attendance populated successfully.", "data": data}

class AttendanceViewByAdmin(BaseModel):
    academic_year_id:int
    term_id: int
    attendance_date: date
    course_category_id: Optional[int]=None
    course_id:Optional[int]=None


@attendance_router.post("/admin")
async def admin_attendance_view( request:AttendanceViewByAdmin,user=Depends(get_user),
                            service=Depends(AttendanceService)):
    data=service.view_attendance_from_admin(request,user)
    return {"message": "Attendance populated successfully.", "data": data}

class AttendanceUpdateByAdmin(BaseModel):
    participant_id: int
    course_id: int
    staff_id: int
    attendance_status: str
    remarks: Optional[str] = None
    attendance_date: date
    attendance_id:int


@attendance_router.post("/admin/update")
async def admin_attendance_update( request:AttendanceUpdateByAdmin,user=Depends(get_user),
                            service=Depends(AttendanceService)):
    data=service.update_attendance_from_admin(request,user)
    return {"message": "Attendance updated successfully.", "data": data}

