<?php
/********************************************************************************
 * (c)1337 aheadware.com - All rights reserved
 ********************************************************************************/


class TB_Server_Control_Team {

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     */
    public static function load( TB_Server_Core_RequestData $params ) {
        $resp = new TB_Server_Core_Response();

        $profile = TB_Server_Core_Session::get()->getProfile();
        if ( is_null( $profile ) ) {
            $resp->setCode( TB_Server_Core_Response::CODE_INVALID_DATA );
        } else {


            // Team
            $team = TB_Shared_Ent_TeamData_Team::get( $profile->team_id );
            $resp->addData( 'team', $team );

            // Invitations
            $is = TB_Shared_Ent_Core_Invitation::getByTeamId( $profile->team_id );
            $invitations = array();
            /** @var TB_Shared_Ent_Core_Invitation $i */
            foreach( $is as $i ) {
                array_push( $invitations, $i->asArray() );
            }
            $resp->addData( 'invitation', $invitations );

            // Profile
            $resp->addData( 'profile', $profile->asArray() );

            // Profiles
            $ps = TB_Shared_Ent_TeamData_Profile::getProfilesByTeamId( $profile->team_id );
            /** @var TB_Shared_Ent_TeamData_Profile $p */
            $profiles = array();
            foreach( $ps as $p ) {
                array_push( $profiles, $p->asArray() );
            }
            $resp->addData( 'profiles', $profiles );

        }

        return $resp;
    }

    public static function getTeamsForAppointmentCreation( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teams = array();

        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        foreach( $sessionProfile->teams_js as $teamData )
        {
            if ( true === $sessionProfile->isAdminOfTeam( $teamData[ 'team_id' ] ) )
            {
                array_push( $teams, TB_Shared_Ent_TeamData_Team::get( $teamData[ 'team_id' ] ) );
                $resp->addData( 'members_' . $teamData[ 'team_id' ], TB_Shared_Ent_TeamData_Profile::getProfilesByTeamId( $teamData[ 'team_id' ] ) );
            }
        }

        $resp->addData( 'teams', $teams );

        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function getDetails( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'teamId' );
        $includeEmail = $params->get( 'includeEmails' );
        $members = array();

        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isInTeam( $teamId ) )
        {
            throw new \Exception( 'Cannot access team with id: ' . $teamId );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );

        if ( !($team instanceof TB_Shared_Ent_TeamData_Team ) )
        {
            $resp->setCode( TB_Server_Core_Response::CODE_NOT_FOUND );
            return $resp;
        }

        $members = TB_Shared_Ent_TeamData_Profile::getProfilesByTeamId( $team->id );

        $resp->addData( 'team', $team );
        $resp->addData( 'members', $members );

        if ( $includeEmail )
        {
            $accountIds = array();
            /** @var TB_Shared_Ent_TeamData_Profile $member */
            foreach ( $members as $member )
            {
                array_push( $accountIds, $member->account_id );
            }

            $emails = TB_Shared_Ent_Core_Account::getEmailsForAccountIds( $accountIds );
            $resp->addData( 'emails', $emails );
        }

        return $resp;
    }

    public static function getCourseTemplates( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'teamId' );
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isInTeam( $teamId ) )
        {
            throw new \Exception( 'Cannot access team with id: ' . $teamId );
        }

        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function getMembers( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'teamId' );

        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isInTeam( $teamId ) )
        {
            throw new \Exception( 'Cannot access team with id: ' . $teamId );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );

        if ( !($team instanceof TB_Shared_Ent_TeamData_Team ) )
        {
            $resp->setCode( TB_Server_Core_Response::CODE_NOT_FOUND );
            return $resp;
        }

        $resp->addData( 'members', TB_Shared_Ent_TeamData_Profile::getProfilesByTeamId( $team->id ) );

        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function changeMemberRole( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'groupId' );
        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );
        $newRole = $params->get( 'newRole' );

        if ( $newRole !== TB_Shared_Ent_TeamData_Profile::ROLE_PLAYER &&
             $newRole !== TB_Shared_Ent_TeamData_Profile::ROLE_COTRAINER )
        {
            throw new \Exception( 'Invalid new role: ' . $newRole );
        }

        if ( is_null( $team ) )
        {
            throw new \Exception( 'Invalid group id for update member.' );
        }


        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isAdminOfTeam( $teamId ) )
        {
            throw new \Exception( 'Not allowed to update member' );
        }

        $memberId = $params->get( 'memberId' );
        $memberToUpdate = TB_Shared_Ent_TeamData_Profile::get( $params->get( 'memberId' ) );
        if ( is_null( $memberToUpdate ) )
        {
            throw new \Exception( 'cannot find member to update with id', $memberId );
        }

        if ( false === $memberToUpdate->isInTeam(  $teamId ) )
        {
            throw new \Exception( 'profile to update is not a member of current team.' );
        }

        if ( $memberToUpdate->isOwnerOfTeam( $teamId ) )
        {
            throw new \Exception( 'Trainer cannot be updated within this function' );
        }

        $memberToUpdate->setRoleInTeam( $teamId, $newRole );
        $memberToUpdate->save();

        TB_Server_Core_Notification::notifyNewRole( $memberToUpdate, $team, $newRole );

        return $resp;
    }

    public static function changeMemberContract( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'groupId' );
        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );
        $contract = $params->get( 'contract' );
        $contractDt = NULL;
        $contractUnix = (int)$params->get( 'contractDate' );
        if ( $contractUnix > 0 )
        {
            $contractDt = DateTime::createFromFormat( 'U', (int)$params->get( 'contractDate' ) );
        }

        if ( is_null( $team ) )
        {
            throw new \Exception( 'Invalid group id for update member.' );
        }

        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isAdminOfTeam( $teamId ) )
        {
            throw new \Exception( 'Not allowed to update member' );
        }

        $memberId = $params->get( 'memberId' );
        $memberToUpdate = TB_Shared_Ent_TeamData_Profile::get( $params->get( 'memberId' ) );
        if ( is_null( $memberToUpdate ) )
        {
            throw new \Exception( 'cannot find member to update with id', $memberId );
        }

        if ( false === $memberToUpdate->isInTeam(  $teamId ) )
        {
            throw new \Exception( 'profile to update is not a member of current team.' );
        }

        $memberToUpdate->setContractInTeam( $teamId, $contract, $contractDt );
        $memberToUpdate->save();

        $resp->addData( 'updated_member', $memberToUpdate );

        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function updateMember( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        throw new \Exception( 'Should never been called anymore.' );

        $teamId = $params->get( 'groupId' );
        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );
        $action = $params->get( 'action' );

        if ( is_null( $team ) )
        {
            throw new \Exception( 'Invalid group id for update member.' );
        }


        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isAdminOfTeam( $teamId ) )
        {
            throw new \Exception( 'Not allowed to update member' );
        }

        $memberId = $params->get( 'memberId' );
        $memberToUpdate = TB_Shared_Ent_TeamData_Profile::get( $params->get( 'memberId' ) );
        if ( is_null( $memberToUpdate ) )
        {
            throw new \Exception( 'cannot find member to update with id', $memberId );
        }

        if ( false === $memberToUpdate->isInTeam(  $teamId ) )
        {
            throw new \Exception( 'profile to update is not a member of current team.' );
        }

        if ( $memberToUpdate->isOwnerOfTeam( $teamId ) )
        {
            throw new \Exception( 'Trainer cannot be updated within this function' );
        }

        switch( $action )
        {
            case 'change-role-to-member':
                $memberToUpdate->setRoleInTeam( $teamId, TB_Shared_Ent_TeamData_Profile::ROLE_PLAYER );
                $memberToUpdate->save();
            break;

            case 'change-role-to-admin':
                $memberToUpdate->setRoleInTeam( $teamId, TB_Shared_Ent_TeamData_Profile::ROLE_COTRAINER );
                $memberToUpdate->save();
            break;

            case 'delete':
                // @todo
            break;
        }

        return $resp;
    }

    public static function addCourseCategory( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'groupId' );
        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );

        if ( is_null( $team ) )
        {
            throw new \Exception( 'Team not found to create new course for' );
        }

        // Rights
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isOwnerOfTeam( $teamId ) )
        {
            throw new \Exception( 'Only owners can add new course categories.' );
        }

        $courseName = $params->get( 'name' );
        if ( mb_strlen( $courseName ) <= 0 )
        {
            throw new \Exception( 'Invalid course name' );
        }

        $team->addCourseCategory( array( 'name' => $courseName) );
        $team->save();

        return $resp;
    }

    public static function removeCourseCategory( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'groupId' );
        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );

        if ( is_null( $team ) )
        {
            throw new \Exception( 'Team not found to remove course for' );
        }

        // Rights
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isOwnerOfTeam( $teamId ) )
        {
            throw new \Exception( 'Only owners may delete course categories.' );
        }

        $categoryId = $params->get( 'categoryId' );

        if ( $categoryId === $team->getDefaultCategoryId() )
        {
            throw new \Exception( 'Cannot delete default category.' );
        }

        $cd = $team->getCourseCategoryDataById( $categoryId );
        if ( !is_null( $cd ) )
        {

            // Remove course category from profiles
            $affectedProfiles = TB_Shared_Ent_TeamData_Profile::getByCourseCategoryId( $categoryId );
            /** @var TB_Shared_Ent_TeamData_Profile $ap */
            foreach( $affectedProfiles as $ap )
            {
                if ( $ap->removeCategoryId( $categoryId ) )
                {
                    $ap->save();
                }
            }

            // Remove course category from appointments
            $affectedAppointments = TB_Shared_Ent_TeamData_Appointment::getByCourseCategoryId( $categoryId );
            /** @var TB_Shared_Ent_TeamData_Appointment $aapp */
            foreach( $affectedAppointments as $aapp )
            {
                $newCatgoryIds = array_diff( $aapp->category_ids_js, array( $categoryId ) );
                if ( 0 === count( $newCatgoryIds ) )
                {
                    array_push( $newCatgoryIds, $team->getDefaultCategoryId() );
                }
                $aapp->category_ids_js = $newCatgoryIds;
                $aapp->save();
            }

            // Remove course category from team
            $team->removeCourseCategoryById( $categoryId );
            $team->save();
        }


        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function updateCourseCategory( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'groupId' );
        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );

        if ( is_null( $team ) )
        {
            throw new \Exception( 'Team not found to remove course for' );
        }

        // Rights
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isOwnerOfTeam( $teamId ) )
        {
            throw new \Exception( 'Only owners can update course categories.' );
        }

        $categoryId = $params->get( 'categoryId' );

        $cd = $team->getCourseCategoryDataById( $categoryId );
        if ( is_null( $cd ) )
        {
            throw new \Exception( 'Course category with given id not found: ' . $categoryId );
        }

        $courseName = $params->get( 'name' );
        if ( mb_strlen( $courseName ) <= 0 )
        {
            throw new \Exception( 'Invalid course name' );
        }

        $team->updateCourseCategoryById( $categoryId, array( 'name' => $courseName ) );
        $team->save();

        return $resp;
    }

    public static function setCategoryIdsToProfileIds( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'groupId' );
        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );

        if ( is_null( $team ) )
        {
            throw new \Exception( 'Team not found' );
        }

        // Rights
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isAdminOfTeam( $teamId ) )
        {
            throw new \Exception( 'Not allowed to call ::addProfileIdsToCourseCategory' );
        }

        $categoryId  = $params->get( 'categoryId' );
        if ( is_null( $team->getCourseCategoryDataById( $categoryId ) ) )
        {
            throw new \Exception( 'Invalid category id' );
        }

        $profileIds = $params->get( 'profileIds' );
        if ( !is_array( $profileIds ) )
        {
            throw new \Exception( 'Invalid profile Ids to add' );
        }

        $teamProfiles = TB_Shared_Ent_TeamData_Profile::getProfilesByTeamId( $teamId );
        /** @var TB_Shared_Ent_TeamData_Profile $tp */
        foreach ( $teamProfiles as $tp )
        {
            if ( in_array( $tp->id, $profileIds ) )
            {
                if ( $tp->addToCategoryId( $categoryId ) )
                {
                    $tp->save();
                }
            }
            else
            {
                if ( $tp->removeCategoryId( $categoryId ) )
                {
                    $tp->save();
                }
            }
        }

        return $resp;
    }

    /**
     * Get team
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     */
    public static function getCurrent( TB_Server_Core_RequestData $params ) {
        $resp = new TB_Server_Core_Response();

        $profile = TB_Server_Core_Session::get()->getProfile();
        if ( is_null( $profile ) ) {
            $resp->setCode( TB_Server_Core_Response::CODE_INVALID_DATA );
        } else {

            // Team
            $team = TB_Shared_Ent_TeamData_Team::get( $profile->team_id );
            $resp->addData( 'team', $team );

        }

        return $resp;
    }

    /**
     * Update current team
     *
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function update( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $teamId = $params->get( 'groupId' );
        $team = TB_Shared_Ent_TeamData_Team::get( $teamId );

        if ( is_null( $team ) )
        {
            throw new \Exception( 'Team not found to update.' );
        }

        // Rights
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();
        if ( false === $sessionProfile->isAdminOfTeam( $teamId ) )
        {
            throw new \Exception( 'Not allowed to update team.' );
        }

        $displayName = $params->get( 'groupName', $team->display_name );
        $category = $params->get( 'industry', $team->category );
        $team->display_name = _xss( $displayName );
        $team->category = _xss( $category );
        $team->description = _xss( $params->get( 'description' ) );
        $team->contact_information = _xss( $params->get( 'contactInformation' ) );
        $team->save();

        return $resp;
    }

    /**
     * Update current team emblem
     *
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function updateEmblem( TB_Server_Core_RequestData $params ) {

        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $params->get( 'teamId' ) );
        if ( !isset( $team ) )
        {
            throw new \Exception( 'Invalid team to update emblem of' );
        }

        if ( false === $sessionProfile->isAdminOfTeam( $team->id ) )
        {
            throw new \Exception( 'No right to update team emblem' );
        }

        $rawImgData = $params->get( 'imageData' );

        // Upload to cloud
        $cloudinary = TB_Server_Utils_Cloudinary::get();

        if ( is_null( $rawImgData ) )
        {

            // Delete emblem
            if ( !is_null( $team->emblem_cloud_id ) )
            {
                $res = $cloudinary->delete( $team->emblem_cloud_id );
            }
            $team->emblem_url = NULL;
            $team->emblem_cloud_id = NULL;
            $team->save();

        }
        else
        {

            // Store old cloud id
            $oldEmblemCloudId = $team->emblem_cloud_id;

            // Set new emblem
            $res = $cloudinary->upload( $rawImgData, array( 'emblem', $team->id ) );
            if ( !is_array( $res ) || !isset( $res[ 'secure_url' ] ) || !isset( $res[ 'public_id' ] ) ) {
                throw new Exception( 'Invalid response from Cloudinary.' );
            }
            // Update team
            $team->emblem_url = $res[ 'secure_url' ];
            $team->emblem_cloud_id = $res[ 'public_id' ];
            $team->save();

            // If new img is saved - remove old from the cloud
            if ( !is_null( $oldEmblemCloudId ) )
            {
                $res = $cloudinary->delete( $oldEmblemCloudId );
                if ( !is_array( $res ) || !isset( $res[ 'result' ] ) || "ok" != $res[ 'result' ] ) {
                    TB_Server_Utils_Log::get()->log( "Could not delete old team emblem: " . $oldEmblemCloudId . ' - ' . @json_encode( $res ) );
                }
            }
        }

        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function removeMember( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $params->get( 'groupId' ) );
        if ( !isset( $team ) )
        {
            throw new \Exception( 'Group not found.' );
        }

        $profileToRemove = TB_Shared_Ent_TeamData_Profile::get( $params->get( 'profileId' ) );
        if ( !isset( $profileToRemove ) )
        {
            throw new \Exception( 'Profile to remove does not exists.' );
        }

        if ( !$sessionProfile->isAdminOfTeam( $team->id ) )
        {
            throw new \Exception( 'User is not admin of team.' );
        }

        if ( $profileToRemove->isOwnerOfTeam( $team->id ) )
        {
            throw new \Exception( 'Cannot remove owner of team.' );
        }

        $dbh = TB_Shared_Db_TeamData::get();
        try
        {
            $dbh->beginTransaction();


            $appointments = TB_Shared_Ent_TeamData_Appointment::getForTeamIdWithProfileAttendanceInteraction( $team->id, $profileToRemove->id, true );
            /** @var TB_Shared_Ent_TeamData_Appointment $appointment */
            foreach ( $appointments as $appointment )
            {
                // Only delete upcoming appointments
                if ( false === $appointment->isOver() && false === $appointment->hasStarted() )
                {
                    TB_Shared_Ent_TeamData_Attendee::deleteByAppointmentIdAndProfileId( $appointment->id, $profileToRemove->id );
                    TB_Server_Control_Appointment::processWaitingList( $appointment );
                }
                // Delete all chat entries
                TB_Shared_Ent_TeamData_Chat::deleteAllFromCreatorForAppointment( $appointment->id, $profileToRemove->id );
            }

            $profileToRemove->leaveTeam( $team->id );
            $profileToRemove->save();

            $dbh->commit();
        }
        catch ( \Exception $e )
        {
            $dbh->rollBack();
        }

        TB_Server_Core_Notification::notifyTeamLeave( $profileToRemove, $team );

        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function leave( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $params->get( 'groupId' ) );
        if ( !isset( $team ) )
        {
            throw new \Exception( 'Group not found.' );
        }

        $dbh = TB_Shared_Db_TeamData::get();
        try
        {
            $dbh->beginTransaction();

            $appointments = TB_Shared_Ent_TeamData_Appointment::getForTeamIdWithProfileAttendanceInteraction( $team->id, $sessionProfile->id, true );
            /** @var TB_Shared_Ent_TeamData_Appointment $appointment */
            foreach ( $appointments as $appointment )
            {
                // Only delete upcoming appointments
                if ( false === $appointment->isOver() && false === $appointment->hasStarted() )
                {
                    TB_Shared_Ent_TeamData_Attendee::deleteByAppointmentIdAndProfileId( $appointment->id, $sessionProfile->id );
                    TB_Server_Control_Appointment::processWaitingList( $appointment );
                }
                // Delete all chat entries
                TB_Shared_Ent_TeamData_Chat::deleteAllFromCreatorForAppointment( $appointment->id, $sessionProfile->id );
            }

            $sessionProfile->leaveTeam( $team->id );
            $sessionProfile->save();

            $dbh->commit();
        }
        catch ( \Exception $e )
        {
            $dbh->rollBack();
        }


        return $resp;
    }

    public static function getProfileAppointmentLog( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $params->get( 'groupId' ) );
        if ( !isset( $team ) )
        {
            throw new \Exception( 'Group not found.' );
        }

        $logProfile = TB_Shared_Ent_TeamData_Profile::get( $params->get( 'profileId' ) );
        if ( !isset( $logProfile ) )
        {
            throw new \Exception( 'Profile to get appointment log from does not exists.' );
        }

        if ( !$logProfile->isInTeam( $team->id ) )
        {
            throw new \Exception( 'Profile is not in team.' );
        }


        if ( !$logProfile->isOwnProfile( $sessionProfile ) && !$sessionProfile->isAdminOfTeam( $team->id ) )
        {
            throw new \Exception( 'Not allowed to retrieve appointment log' );
        }


        $res = TB_Shared_Ent_TeamData_Appointment::getLogByGroupAndProfileId(
            $team->id,
            $logProfile->id,
            $params->get( 'startDt' ),
            $params->get( 'endDt' )
        );
        $resp->addData( 'appointmentLog', $res );

        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function getAdminNote( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        $adminNoteText = '';

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $params->get( 'groupId' ) );
        if ( !isset( $team ) )
        {
            throw new \Exception( 'Group not found.' );
        }

        $noteProfile = TB_Shared_Ent_TeamData_Profile::get( $params->get( 'profileId' ) );
        if ( !isset( $noteProfile ) )
        {
            throw new \Exception( 'Profile to get note from does not exists.' );
        }

        if ( !$noteProfile->isInTeam( $team->id ) )
        {
            throw new \Exception( 'Profile is not in team.' );
        }

        if ( !$sessionProfile->isAdminOfTeam( $team->id ) )
        {
            throw new \Exception( 'Not allowed to retrieve notes' );
        }

        $adminNote = TB_Shared_Ent_TeamData_AdminNote::getByGroupIdAndProfileId( $team->id, $noteProfile->id );
        if ( $adminNote )
        {
            $adminNoteText = $adminNote->note;
        }

        $resp->addData( 'adminNote', $adminNoteText );
        return $resp;
    }

    public static function setContracteeData( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $params->get( 'groupId' ) );
        if ( !isset( $team ) )
        {
            throw new \Exception( 'Group not found.' );
        }

        if ( !$sessionProfile->isAdminOfTeam( $team->id ) )
        {
            throw new \Exception( 'Not allowed to update contractee data' );
        }

        $cName = $params->get( 'name' );
        $cStreet = $params->get( 'street' );
        $cZipCode = $params->get( 'zip_code' );
        $cCity = $params->get( 'city' );
        $cCountry = $params->get( 'country' );

        if ( !$cName || !$cStreet || !$cZipCode || !$cCity || !$cCountry )
        {
            throw new \Exception( 'Invalid contractee data.' );
        }

        $team->contractee_master_data_js = array(
            'name' => $cName,
            'street' => $cStreet,
            'zip_code' => $cZipCode,
            'city' => $cCity,
            'country' => $cCountry
        );
        $team->save();

        return $resp;
    }

    /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function updateAdminNote( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $params->get( 'groupId' ) );
        if ( !isset( $team ) )
        {
            throw new \Exception( 'Group not found.' );
        }

        $noteProfile = TB_Shared_Ent_TeamData_Profile::get( $params->get( 'profileId' ) );
        if ( !isset( $noteProfile ) )
        {
            throw new \Exception( 'Profile to get note from does not exists.' );
        }

        if ( !$noteProfile->isInTeam( $team->id ) )
        {
            throw new \Exception( 'Profile is not in team.' );
        }

        if ( !$sessionProfile->isAdminOfTeam( $team->id ) )
        {
            throw new \Exception( 'Not allowed to retrieve notes' );
        }

        $adminNoteContent = $params->get( 'adminNote');
        if ( !$adminNoteContent )
        {
            throw new \Exception( 'No admin note content found.' );
        }

        $adminNote = TB_Shared_Ent_TeamData_AdminNote::getByGroupIdAndProfileId( $team->id, $noteProfile->id );
        if ( !$adminNote )
        {
            $adminNote = new TB_Shared_Ent_TeamData_AdminNote();
            $adminNote->group_id = $team->id;
            $adminNote->profile_id = $noteProfile->id;
            $adminNote->creator_profile_id = $sessionProfile->id;
        }

        $adminNote->note = $adminNoteContent;
        $adminNote->save();

        return $resp;
    }

        /**
     * @param TB_Server_Core_RequestData $params
     * @return TB_Server_Core_Response
     * @throws Exception
     */
    public static function join( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $team = TB_Shared_Ent_TeamData_Team::get( $params->get( 'groupId' ) );
        if ( !isset( $team ) )
        {
            throw new \Exception( 'Group not found.' );
        }

        $sessionProfile->joinTeam( $team->id );
        $sessionProfile->save();

        $resp->addData( 'profile',  $sessionProfile );
        $resp->addData( 'profile_teams', TB_Shared_Ent_TeamData_Team::getByProfile( $sessionProfile ) );

        return $resp;
    }

    public static function getAll( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $groups = TB_Shared_Ent_TeamData_Team::getAllForJoin();

        $resp->addData( 'groups', $groups );

        return $resp;
    }

    // NOT USED AT THE MOMENT
    public static function delete( TB_Server_Core_RequestData $params )
    {
        $resp = new TB_Server_Core_Response();

        /** @var TB_Shared_Ent_TeamData_Profile $sessionProfile */
        $sessionProfile = TB_Server_Core_Session::get()->getProfile();

        if ( !isset( $sessionProfile ) )
        {
            throw new \Exception( 'Invalid profile' );
        }

        $teamIdToDelete = $params->get( 'teamId' );
        if ( 'trainer' !== $sessionProfile->getRoleInTeam( $teamIdToDelete ) )
        {
            throw new \Exception( 'Only trainers can delete their teams.' );
        }

        $entTeam = TB_Shared_Ent_TeamData_Team::get( $teamIdToDelete );
        if ( !$entTeam )
        {
            throw new \Exception( 'Team to delete not found.' );
        }

        // @todo Check if team has a running valid and payed zContract

        $dbh = TB_Shared_Db_TeamData::get();
        try
        {
            $dbh->beginTransaction();

            $profilesToRemove = TB_Shared_Ent_TeamData_Profile::getProfilesByTeamId( $entTeam->id );

            /** @var TB_Shared_Ent_TeamData_Profile $profileToRemove */
            foreach( $profilesToRemove as $profileToRemove )
            {
                $profileToRemove->leaveTeam( $entTeam->id );
                $profileToRemove->save();
            }
            $entTeam->delete();

            $dbh->commit();
        }
        catch ( \Exception $e )
        {
            $dbh->rollBack();
        }

        return $resp;

    }

}