package world.respect.shared.domain.account.child

import org.koin.core.component.KoinComponent
import world.respect.datalayer.AuthenticatedUserPrincipalId
import world.respect.datalayer.DataLoadParams
import world.respect.datalayer.SchoolDataSource
import world.respect.datalayer.ext.dataOrNull
import world.respect.datalayer.school.model.Enrollment
import world.respect.datalayer.school.model.EnrollmentRoleEnum
import world.respect.datalayer.school.model.Person
import world.respect.datalayer.school.model.PersonRoleEnum
import world.respect.shared.domain.account.invite.RespectRedeemInviteRequest
import world.respect.shared.domain.school.SchoolPrimaryKeyGenerator
import world.respect.shared.util.toPerson

class AddChildAccountUseCaseDataSource(
    private val schoolPrimaryKeyGenerator: SchoolPrimaryKeyGenerator,
    private val authenticatedUser: AuthenticatedUserPrincipalId,
    private val schoolDataSource: SchoolDataSource,
) : AddChildAccountUseCase, KoinComponent {

    override suspend operator fun invoke(
        personInfo: RespectRedeemInviteRequest.PersonInfo,
        parentUsername: String,
        classUid: String?,
        inviteCode: String,
        familyPersonGuid: String?,
    ) {
        val parentPerson = schoolDataSource.personDataSource.findByGuid(
            loadParams = DataLoadParams(),
            guid = familyPersonGuid?:authenticatedUser.guid,
        ).dataOrNull() ?: throw IllegalStateException("Parent person not found: $authenticatedUser")

        val childUid = schoolPrimaryKeyGenerator.primaryKeyGenerator.nextId(
            Person.TABLE_ID
        ).toString()

        val parentWithRel = parentPerson.copy(
            relatedPersonUids = parentPerson.relatedPersonUids + childUid
        )

        val childPerson = personInfo.toPerson(
            role = PersonRoleEnum.STUDENT,
            guid = childUid
        ).copy(
            relatedPersonUids = listOf(authenticatedUser.guid)
        )

        schoolDataSource.personDataSource.store(
            listOf(parentWithRel, childPerson)
        )
        if (classUid!=null){
            val enrollment = Enrollment(
                uid = schoolPrimaryKeyGenerator.primaryKeyGenerator.nextId(Enrollment.TABLE_ID)
                    .toString(),
                classUid = classUid,
                personUid = childUid,
                role = EnrollmentRoleEnum.PENDING_STUDENT,
                inviteCode = inviteCode,
            )

            schoolDataSource.enrollmentDataSource.store(listOf(enrollment))
        }
    }
}