from sqlalchemy.orm import Session
from fastapi import HTTPException, status
from typing import List
from . import repository
from .schema import SubmissionCreate, SubmissionUpdate, SubmissionResponse


def create_submission(db: Session, data: SubmissionCreate) -> SubmissionResponse:
    try:
        submission_dict = data.model_dump()
        submission = repository.create(db, submission_dict)
        db.commit()
        db.refresh(submission)
        return SubmissionResponse.model_validate(submission)
    except Exception:
        db.rollback()
        raise


def list_submissions(db: Session, limit: int = 20, offset: int = 0) -> List[SubmissionResponse]:
    submissions = repository.list_all(db, limit=limit, offset=offset)
    return [SubmissionResponse.model_validate(s) for s in submissions]


def get_submission(db: Session, submission_id: str) -> SubmissionResponse:
    submission = repository.get_by_id(db, submission_id)
    if not submission:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Submission with id {submission_id} not found"
        )
    return SubmissionResponse.model_validate(submission)


def update_submission(db: Session, submission_id: str, data: SubmissionUpdate) -> SubmissionResponse:
    try:
        update_dict = data.model_dump(exclude_unset=True)
        if not update_dict:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="No fields provided for update"
            )
        submission = repository.update(db, submission_id, update_dict)
        if not submission:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Submission with id {submission_id} not found"
            )
        db.commit()
        db.refresh(submission)
        return SubmissionResponse.model_validate(submission)
    except HTTPException:
        db.rollback()
        raise
    except Exception:
        db.rollback()
        raise


def delete_submission(db: Session, submission_id: str) -> None:
    try:
        success = repository.delete(db, submission_id)
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"Submission with id {submission_id} not found"
            )
        db.commit()
    except HTTPException:
        db.rollback()
        raise
    except Exception:
        db.rollback()
        raise