/**
 * (c) by aheadware.com
 */
"use strict";

var app = app || {};
app.model = app.model || {};

/**
 * Appointment
 */
app.model.Appointment = function( appData, attendees, attendeeProfiles )
{
    var data = appData,
        attendees = attendees || [],
        attendeeProfiles = attendeeProfiles || [],
        id = data.id,
        category = data.category || null,
        categoryIds = typeof( data.category_ids_js ) === 'string' ? JSON.parse( data.category_ids_js ) : data.category_ids_js,
        visibility = data.visibility,
        subject = data.subject,
        teamId = data.team_id,
        serialId = data.serial_id || null,
        hasAttended = data.has_attended,
        comment = data.comment,
        state = data.state,
        location = data.location,
        minAttendees = data.min_attendees ? data.min_attendees : 0,
        maxAttendees = data.max_attendees ? data.max_attendees : 0,
        priceFactor  = (+data.price_factor),
        mStart = app.util.Helper.getMomentFromUTCTime( data.start_dt ),
        mEnd = app.util.Helper.getMomentFromUTCTime( data.end_dt ),
        mDeadline = app.util.Helper.getMomentFromUTCTime( data.deadline_dt ),
        mDeadlineReject = app.util.Helper.getMomentFromUTCTime( data.deadline_reject_dt );

    // Process attendee data in order to fix correct status date
    for ( var ai = 0; ai < attendees.length; ai++ )
    {
        attendees[ ai ].momentLastUpdate = app.util.Helper.getMomentFromUTCTime( attendees[ ai ].last_update_dt );
    }

    this.getId = function()
    {
        return id;
    };

    this.getCategory = function()
    {
        return category;
    };

    this.getVisibility = function()
    {
        return visibility;
    };

    this.isVisible = function()
    {
        return ( visibility === app.model.Appointment.ENUM_VISIBLE_FOR_ALL );
    };

    this.getTeamId = function()
    {
        return teamId;
    };

    this.getSubject = function()
    {
        return subject;
    };
    this.getLocation = function()
    {
        return location;
    };
    this.getMinAttendees = function()
    {
        return minAttendees;
    };

    this.getPriceFactor = function()
    {
        return priceFactor / 100;
    };

    this.isCancelled = function()
    {
        return ( state === "cancelled" );
    };

    this.getComment = function()
    {
        return comment;
    };

    this.getMaxAttendees = function()
    {
        return maxAttendees;
    };

    this.getMomentStart = function()
    {
        return mStart;
    };

    this.getMomentEnd = function()
    {
        return mEnd;
    };

    this.getMomentDeadline = function()
    {
        return mDeadline;
    };

    this.getMomentDeadlineReject = function()
    {
        return mDeadlineReject;
    };

    this.getState = function()
    {
        return state;
    };

    this.isDraft = function()
    {
        return ( state === 'draft' );
    };

    /**
     *
     * @returns {boolean}
     */
    this.isDeadlineOver = function()
    {
        return ( moment() > mDeadline );
    };

    this.isDeadlineRejectOver = function()
    {
        return ( moment() > mDeadlineReject );
    };

    this.isOver = function()
    {
        return ( moment() > mEnd );
    };

    this.hasStarted = function()
    {
        return ( moment() > mStart );
    };

    this.hasWaitingList = function()
    {
        return ( 0 < this.getMaxAttendees() );
    };

    this.isMaxAttendeesExceeded = function()
    {
        if ( 0 == maxAttendees )
        {
            return false;
        }

        return ( maxAttendees <= this.getNumAttendeesAccepted() );
    };

    this.isSerial = function()
    {
        return ( 0 < +serialId );
    };

    /**
     *
     * @param profileId
     * @returns {*}
     */
    this.getProfileById = function( profileId )
    {
        var p = null;
        for ( var pi = 0; pi < attendeeProfiles.length; pi++ )
        {
            if ( attendeeProfiles[ pi ].id == profileId )
            {
                p = new app.model.Profile( attendeeProfiles[ pi ] );
                break;
            }
        }
        return p;
    };

    /**
     *
     * @returns {number}
     */
    this.getNumAttendeesAccepted = function()
    {
        var numAccepted = 0;

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "accepted" )
            {
                numAccepted++;
            }
        }

        return numAccepted;
    };

    this.getNumHasAttended = function()
    {
        var numAttended = 0;

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].has_attended == "accepted" )
            {
                numAttended++;
            }
        }

        return numAttended;
    };

    this.getNumHasNotAttended = function()
    {
        var numNotAttended = 0;

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].has_attended == "declined" )
            {
                numNotAttended++;
            }
        }

        return numNotAttended;
    };

    /**
     *
     * @returns {number}
     */
    this.getNumAttendeesDeclined = function()
    {
        var numDeclined= 0;

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "declined" )
            {
                numDeclined++;
            }
        }

        return numDeclined;
    };

    this.isDeletable = function()
    {
        return ( 0 === this.getNumAttendeesAccepted() && 0 === this.getNumAttendeesDeclined() &&
                 0 === this.getNumHasAttended() && 0 === this.getNumHasNotAttended() );
    };

    /**
     *
     * @param profileId
     * @returns {boolean}
     */
    this.hasProfileIdAccepted = function( profileId )
    {
        return ( "accepted" === this.getAttendeeStatusForProfileId( profileId ) );
    };

    this.hasProfileIdAttended = function( profileId )
    {
        return ( "attended" === this.getAttendeeHasAttendedValueForProfileId( profileId ) );
    };

    /**
     *
     * @param profileId
     * @returns {*}
     */
    this.getAttendeeByProfileId = function( profileId )
    {
        var attendee = null;

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].profile_id == profileId && attendees[ ai ].status.length > 0 )
            {
                attendee = this.getProfileById( profileId );
                break;
            }
        }

        return attendee;
    };

    this.hasContractAttendances = function()
    {
        var r = false;

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].contract_id !== null && attendees[ ai ].contract_id > 0 )
            {
                r = true;
                break;
            }
        }

        return r;
    };

    this.getAttendeeData = function()
    {
        return attendees;
    };

    this.getAttendeesAccepted = function()
    {
        var attendeesAccepted = [];

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "accepted" )
            {
                attendeesAccepted.push( this.getProfileById( attendees[ ai ].profile_id ) );
            }
        }

        return attendeesAccepted;
    };

    this.getProfileIdsAccepted = function()
    {
        var profileIdsAccepted = [];

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "accepted" )
            {
                profileIdsAccepted.push(attendees[ ai ].profile_id );
            }
        }

        return profileIdsAccepted;
    };

    this.getAttendeesDeclined = function()
    {
        var attendeesDeclined = [];

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "declined" )
            {
                attendeesDeclined.push( this.getProfileById( attendees[ ai ].profile_id ) );
            }
        }

        return attendeesDeclined;
    };

    this.getProfileIdsDeclined = function()
    {
        var profileIdsDeclined = [];

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "declined" )
            {
                profileIdsDeclined.push(attendees[ ai ].profile_id );
            }
        }

        return profileIdsDeclined;
    };

    this.getAttendeesWaiting = function()
    {
        var attendeesWaiting = [];

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "waiting" )
            {
                attendeesWaiting.push( this.getProfileById( attendees[ ai ].profile_id ) );
            }
        }

        return attendeesWaiting;
    };

    this.getProfileIdsWaiting = function()
    {
        var profileIdsWaiting = [];

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "waiting" )
            {
                profileIdsWaiting.push(attendees[ ai ].profile_id );
            }
        }

        return profileIdsWaiting;
    };

    /**
     *
     * @returns {number}
     */
    this.getNumAttendeesWaiting = function()
    {
        return this.getAttendeesWaiting().length;
    };

    this.getAttendeesAttended = function()
    {
        var attendeesAttended = [];

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].has_attended == "attended" )
            {
                attendeesAttended.push( this.getProfileById( attendees[ ai ].profile_id ) );
            }
        }

        return attendeesAttended;
    };

    this.getAttendeesNotAttended = function()
    {
        var attendeesNotAttended = [];

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].status == "accepted" &&
                 attendees[ ai ].has_attended == "declined" )
            {
                attendeesNotAttended.push( this.getProfileById( attendees[ ai ].profile_id ) );
            }
        }

        return attendeesNotAttended;
    };


    /**
     *
     * @param profileId
     * @returns {boolean}
     */
    this.hasProfileIdDeclined = function( profileId )
    {
        return ( "declined" === this.getAttendeeStatusForProfileId( profileId ) );
    };

    this.isProfileIdWaiting = function( profileId )
    {
        return ( "waiting" === this.getAttendeeStatusForProfileId( profileId ) );
    };

    this.getWaitingList = function()
    {
        var waitingList = [];
        var waitingPos = 0,
            posCounter = 0;

        function compareLastUpdateDt( a,b )
        {
            if ( a.momentLastUpdate < b.momentLastUpdate )
            {
                return -1;
            }
            else if ( a.momentLastUpdate > b.momentLastUpdate )
            {
                return 1;
            }
            return 0;
        }

        attendees.sort( compareLastUpdateDt );

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( "waiting" === attendees[ ai ].status )
            {
                waitingList.push( this.getAttendeeByProfileId( attendees[ ai ].profile_id ));
            }
        }

        return waitingList;
    };

    this.getWaitingPositionForProfileId = function( profileId )
    {
        var waitingPos = 0,
            posCounter = 0;

        function compareLastUpdateDt( a,b )
        {
            if ( a.momentLastUpdate < b.momentLastUpdate )
            {
                return -1;
            }
            else if ( a.momentLastUpdate > b.momentLastUpdate )
            {
                return 1;
            }
            return 0;
        }

        attendees.sort( compareLastUpdateDt );

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( "waiting" === attendees[ ai ].status )
            {
                posCounter++;
            }

            if ( attendees[ ai ].profile_id == profileId )
            {
                if ( "waiting" === attendees[ ai ].status )
                {
                    waitingPos = posCounter;
                }
                break;
            }
        }

        return waitingPos;
    };

    /**
     *
     * @param profileId
     * @returns {*}
     */
    this.getAttendeeHasAttendedValueForProfileId = function( profileId )
    {
        var ha = null;

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].profile_id == profileId )
            {
                ha = attendees[ ai ].has_attended;
                break;
            }
        }

        return ha;
    };

    /**
     *
     * @param profileId
     * @returns {*}
     */
    this.getAttendeeStatusForProfileId = function( profileId )
    {
        var status = null;

        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].profile_id == profileId )
            {
                status = attendees[ ai ].status;
                break;
            }
        }

        return status;
    };

    this.setAttendeeStatusForProfileId = function( profileId, status )
    {
        for ( var ai = 0; ai < attendees.length; ai++ )
        {
            if ( attendees[ ai ].profile_id == profileId )
            {
                attendees[ ai ].status = status;
                break;
            }
        }
    };

    this.getCategoryIds = function()
    {
        return categoryIds;
    };

    this.getCategoryName = function()
    {
        var g = app.model.SessionUser.getGroupById( this.getTeamId() ),
            cg = null,
            cName = null;

        if ( g )
        {
            cg = g.getCourseCategoryById( this.getCategoryId() );
            if ( cg )
            {
                cName = cg.name;
            }
        }

        return cName;
    };

    this.getCategoryNames = function()
    {
        var g = app.model.SessionUser.getGroupById( this.getTeamId() ),
            cgIds = this.getCategoryIds(),
            cName = '';

        if ( g )
        {
            for ( var ci = 0; ci < cgIds.length; ci++ )
            {
                if ( ci > 0 )
                {
                    cName += ' - ';
                }

                cName += g.getCourseCategoryNameById( cgIds[ ci ] );
            }
        }

        return cName;
    };

};

app.model.Appointment.ENUM_VISIBLE_FOR_ALL = 'ALL';
app.model.Appointment.ENUM_VISIBLE_FOR_CATEGORIES = 'CATEGORIES';