define([
    'backbone',
    'underscore',
    'teams/js/collections/team',
    'teams/js/collections/team_membership',
    'teams/js/collections/topic',
    'teams/js/models/topic'
], function (Backbone, _, TeamCollection, TeamMembershipCollection, TopicCollection, TopicModel) {
    'use strict';
    var createMockPostResponse, createMockDiscussionResponse, createAnnotatedContentInfo, createMockThreadResponse,
        createMockTopicData, createMockTopicCollection, createMockTopic,
        testCourseID = 'course/1',
        testUser = 'testUser',
        testTopicID = 'test-topic-1',
        testTeamDiscussionID = "12345",
        teamEvents = _.clone(Backbone.Events),
        testCountries = [
            ['', ''],
            ['US', 'United States'],
            ['CA', 'Canada'],
            ['MX', 'Mexico']
        ],
        testLanguages = [
            ['', ''],
            ['en', 'English'],
            ['es', 'Spanish'],
            ['fr', 'French']
        ];

    var createMockTeamData = function (startIndex, stopIndex) {
        return _.map(_.range(startIndex, stopIndex + 1), function (i) {
            var id = "id" + i;
            return {
                name: "team " + i,
                id: id,
                language: testLanguages[i%4][0],
                country: testCountries[i%4][0],
                membership: [],
                last_activity_at: '',
                topic_id: 'topic_id' + i,
                url: 'api/team/v0/teams/' + id
            };
        });
    };

    var createMockTeamsResponse = function(options) {
        return _.extend(
            {
                count: 6,
                num_pages: 2,
                current_page: 1,
                start: 0,
                results: createMockTeamData(1, 5)
            },
            options
        );
    };

    var createMockTeams = function(responseOptions, options, collectionType) {
        if(_.isUndefined(collectionType)) {
            collectionType = TeamCollection;
        }
        return new collectionType(
            createMockTeamsResponse(responseOptions),
            _.extend({
                teamEvents: teamEvents,
                course_id: testCourseID,
                per_page: 2,
                parse: true
            }, options)
        );
    };

    var createMockTeamMembershipsData = function(startIndex, stopIndex) {
        var teams = createMockTeamData(startIndex, stopIndex);
        return _.map(_.range(startIndex, stopIndex + 1), function (i) {
            return {
                user: {
                    username: testUser,
                    url: 'https://openedx.example.com/api/user/v1/accounts/' + testUser,
                    profile_image: {
                        image_url_small: 'test_profile_image'
                    }
                },
                team: teams[i-1]
            };
        });
    };

    var createMockUserInfo = function(options) {
        return _.extend(
            {
                username: testUser,
                privileged: false,
                staff: false,
                team_memberships_data: createMockTeamMembershipsData(1, 5)
            },
            options
        );
    };

    var verifyCards = function(view, teams) {
        var teamCards = view.$('.team-card');
        _.each(teams, function (team, index) {
            var currentCard = teamCards.eq(index);
            expect(currentCard.text()).toMatch(team.name);
            expect(currentCard.text()).toMatch(_.object(testLanguages)[team.language]);
            expect(currentCard.text()).toMatch(_.object(testCountries)[team.country]);
        });
    };

    var triggerTeamEvent = function (action) {
        teamEvents.trigger('teams:update', {action: action});
    };

    createMockPostResponse = function(options) {
        return _.extend(
            {
                username: testUser,
                course_id: testCourseID,
                commentable_id: testTeamDiscussionID,
                type: 'thread',
                body: "",
                anonymous_to_peers: false,
                unread_comments_count: 0,
                updated_at: '2015-07-29T18:44:56Z',
                group_name: 'Default Group',
                pinned: false,
                votes: {count: 0, down_count: 0, point: 0, up_count: 0},
                user_id: "9",
                abuse_flaggers: [],
                closed: false,
                at_position_list: [],
                read: false,
                anonymous: false,
                created_at: "2015-07-29T18:44:56Z",
                thread_type: 'discussion',
                comments_count: 0,
                group_id: 1,
                endorsed: false
            },
            options
        );
    };

    createMockDiscussionResponse = function(threads) {
        if (_.isUndefined(threads)) {
            threads = [
                createMockPostResponse({ id: "1", title: "First Post"}),
                createMockPostResponse({ id: "2", title: "Second Post"}),
                createMockPostResponse({ id: "3", title: "Third Post"})
            ];
        }
        return {
            "num_pages": 1,
            "page": 1,
            "discussion_data": threads,
            "user_info": {
                "username": testUser,
                "follower_ids": [],
                "default_sort_key": "date",
                "downvoted_ids": [],
                "subscribed_thread_ids": [],
                "upvoted_ids": [],
                "external_id": "9",
                "id": "9",
                "subscribed_user_ids": [],
                "subscribed_commentable_ids": []
            },
            "annotated_content_info": {
            },
            "roles": {"Moderator": [], "Administrator": [], "Community TA": []},
            "course_settings": {
                "is_cohorted": false,
                "allow_anonymous_to_peers": false,
                "allow_anonymous": true,
                "category_map": {"subcategories": {}, "children": [], "entries": {}},
                "cohorts": []
            }
        };
    };

    createAnnotatedContentInfo = function() {
        return {
            voted: '',
            subscribed: true,
            ability: {
                can_reply: true,
                editable: true,
                can_openclose: true,
                can_delete: true,
                can_vote: true
            }
        };
    };

    createMockThreadResponse = function(options) {
        return _.extend(
            {
                username: testUser,
                course_id: testCourseID,
                commentable_id: testTeamDiscussionID,
                children: [],
                comments_count: 0,
                anonymous_to_peers: false,
                unread_comments_count: 0,
                updated_at: "2015-08-04T21:44:28Z",
                resp_skip: 0,
                id: "55c1323c56c02ce921000001",
                pinned: false,
                votes: {"count": 0, "down_count": 0, "point": 0, "up_count": 0},
                resp_limit: 25,
                abuse_flaggers: [],
                closed: false,
                resp_total: 1,
                at_position_list: [],
                type: "thread",
                read: true,
                anonymous: false,
                user_id: "5",
                created_at: "2015-08-04T21:44:28Z",
                thread_type: "discussion",
                context: "standalone",
                endorsed: false
            },
            options
        );
    };

    createMockTopicData = function (startIndex, stopIndex) {
        return _.map(_.range(startIndex, stopIndex + 1), function (i) {
            return {
                "description": "Test description " + i,
                "name": "Test Topic " + i,
                "id": "test-topic-" + i,
                "team_count": 0
            };
        });
    };

    createMockTopic = function(options) {
        return new TopicModel(_.extend(
            {
                id: testTopicID,
                name: 'Test Topic 1',
                description: 'Test description 1'
            },
            options
        ));
    };

    var testContext = {
        courseID: testCourseID,
        topics: {
            count: 5,
            num_pages: 1,
            current_page: 1,
            start: 0,
            results: createMockTopicData(1, 5)
        },
        maxTeamSize: 6,
        languages: testLanguages,
        countries: testCountries,
        topicUrl: '/api/team/v0/topics/topic_id,' + testCourseID,
        teamsUrl: '/api/team/v0/teams/',
        teamsDetailUrl: '/api/team/v0/teams/team_id',
        teamMembershipsUrl: '/api/team/v0/team_memberships/',
        teamMembershipDetailUrl: '/api/team/v0/team_membership/team_id,' + testUser,
        myTeamsUrl: '/api/team/v0/teams/',
        userInfo: createMockUserInfo()
    };

    var createMockContext = function(options) {
        return _.extend({}, testContext, options);
    };

    createMockTopicCollection = function (topicData) {
        topicData = topicData !== undefined ? topicData : createMockTopicData(1, 5);

        return new TopicCollection(
            {
                count: topicData.length + 1,
                current_page: 1,
                num_pages: 2,
                start: 0,
                results: topicData,
                sort_order: 'name'
            },
            {
                teamEvents: teamEvents,
                course_id: testCourseID,
                parse: true,
                url: testContext.topicUrl
            }
        );
    };

    return {
        teamEvents: teamEvents,
        testCourseID: testCourseID,
        testUser: testUser,
        testTopicID: testTopicID,
        testCountries: testCountries,
        testLanguages: testLanguages,
        testTeamDiscussionID: testTeamDiscussionID,
        testContext: testContext,
        createMockTeamData: createMockTeamData,
        createMockTeamsResponse: createMockTeamsResponse,
        createMockTeams: createMockTeams,
        createMockUserInfo: createMockUserInfo,
        createMockContext: createMockContext,
        createMockTopic: createMockTopic,
        createMockPostResponse: createMockPostResponse,
        createMockDiscussionResponse: createMockDiscussionResponse,
        createAnnotatedContentInfo: createAnnotatedContentInfo,
        createMockThreadResponse: createMockThreadResponse,
        createMockTopicData: createMockTopicData,
        createMockTopicCollection: createMockTopicCollection,
        triggerTeamEvent: triggerTeamEvent,
        verifyCards: verifyCards
    };
});
