﻿"use strict";

// submissionDetails controller
app.controller("submissionDetailsController", [
    "$rootScope",
    "$scope",
    "$routeParams",
    "submissionDataService",
    "judgeRulesService",
    "votingService",
    "categorySubmissionDataService",
    "categoryDataService",
    "authService",
    "streamingDataService",
    "$location",
    "$interval",
    function (
        $rootScope,
        $scope,
        $routeParams,
        submissionDataService,
        judgeRulesService,
        votingService,
        categorySubmissionDataService,
        categoryDataService,
        authService,
        streamingDataService,
        $location,
        $interval) {

        $scope.votingService = votingService; // Make voting service methods available to views
        $scope.judgeRulesService = judgeRulesService;
        $scope.submissionId = $routeParams.subId;
        $scope.submission = {};
        $scope.submissionDetailsTemplateBaseUri = window.location.pathname + "/spa-app/views/submission/html/";
        $scope.categoryId = 0;
        $scope.categories = [];
        $scope.currentCategory = { id: 0 };
        $scope.ballotId = 0;

        $scope.voteTypeId = 0;
        $scope.voteTypeConfig = {};
        $scope.votes = [];

        $scope.voted = false;
        $scope.enableVote = true;

        // video related
        $scope.startingTime = 0; // default is at beginning
        $scope.passRequiredViewingTime = true;
        $scope.requiredMinimumPlaytime = 0;

        $scope.roundId = 0;
        $scope.contactId = 0;
        $scope.fullname = "";
        $scope.emailAddress = "";
        $scope.randomNumber = Math.random();

        $scope.finishLoading = false;

        $scope.showOnAirDetails = false;
        $scope.showMarketDetails = false;
        $scope.showSubmitterContactDetails = false;
        $scope.showRadioStationDetails = false;

        $scope.streamData = {};

        // ----- Event listeners
        $scope.$on("refreshVotesRequired", function (event, data) {
            $scope.getSubmission();
        });
        $scope.$on("submitVote", function (event, data) {
            $scope.getSubmission();
        });
        $scope.$on("swapVote", function (event, data) {
            $scope.votes = votingService.getVotes();
        });
        // ----- Helpers

        $scope.getUserInfo = function () {
            authService.getUserInfo().then(function (results) {
                $scope.fullname = results.data.fullname;
                $scope.emailAddress = results.data.emailAddress;
                $scope.contactId = results.data.id;
            },
                function (error) {
                    console.error('error on getUserInfo');
                });
        };

        $scope.init = function () {
            $scope.getUserInfo();
            // Used for nav
            $rootScope.isDetailsView = true;
            $rootScope.showMenuHint = false;
            $scope.getCategories();

            // Init
            $scope.getSubmission();
        };

        $scope.isActive = function (catId) {
            return ($scope.currentCategory.id === catId);
        };
        $scope.getCategories = function () {
            categoryDataService.getCategories().then(function (results) {
                $scope.categories = results.data;
            });
        };
        $scope.getCategory = function () {
            categoryDataService.getCategory($scope.categoryId).then(function (results) {
                // check if user are allowed to see the submission details
                var allowToSeeDetails = judgeRulesService.showDetails(results.data, results.data.roundSortOrder);

                if (!allowToSeeDetails) {
                    $location.path("/dashboard/" + $scope.ballotId);
                }
                else {
                    results.data.categoryName = judgeRulesService.getCategoryName(results.data);
                    $rootScope.detailsCategory = $scope.currentCategory = results.data;
                    $scope.ballotId = $scope.currentCategory.ballotId;
                    $scope.showDocumentDownload = ["11", "12", "13", "15", "14", "25", "16", "17", "18", "19", "46", "47", "48", "23"].indexOf(results.data.categoryNumber) < 0;
                    $scope.showOnAirDetails = ["1", "2", "3", "4"].indexOf(results.data.categoryNumber) >= 0;
                    $scope.showMarketDetails = ["6", "7", "8", "9"].indexOf(results.data.categoryNumber) >= 0;
                    $scope.showSubmitterContactDetails = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "30", "50"].indexOf(results.data.categoryNumber) < 0;
                    $scope.showRadioStationDetails = ["30", "50"].indexOf(results.data.categoryNumber) < 0;
                }

                $scope.roundId = results.data.roundId;

                // Init the voting service and grab the current votes
                $scope.votingService.init($scope.voteTypeId, $scope.voteTypeConfig, $scope.currentCategory).then(function (results) {
                    $scope.votes = $scope.votingService.getVotes();
                    $scope.setVoted();

                    // Check if voting is criteria, if it is we have to init it
                    if ($scope.votingService.isCriteriaVoting()) {
                        if (["1", "2", "3", "4", "30", "50", "6", "7", "8", "9"].indexOf($scope.currentCategory.categoryNumber) >= 0) {
                            var nomineeName = [$scope.submission.nomineeName, $scope.submission.nomineeSecondaryName].join("<br/>");

                        } else {
                            var nomineeName = [$scope.submission.nomineeName, $scope.submission.nomineeSecondaryName, $scope.submission.submissionRunningTime].join("<br/>");
                        }

                        $scope.votingService.showCriteriaVoteDetails($scope.submission.voteId, $scope.submission.submissionId, nomineeName, $scope.submission.voteSubmitted, null, $scope.ballotId);
                    }
                }).finally(function () { $scope.finishLoading = true; });

                $scope.setCanVote();
            },
                function (error) {
                    console.error('error on getCategory');
                });
        };
        $scope.getSubmission = function () {
            submissionDataService.getSubmission($scope.submissionId).then(function (results) {
                $scope.submission = results.data.submission;
                $scope.submission.packageMedia = results.data.submission.packageMedia || [];
                $scope.renderSubmissionTemplate($scope.submission.category.categoryNumber);
                $scope.categoryId = $scope.submission.category.id;
                $scope.voteTypeId = results.data.voteTypeId;
                $scope.voteTypeConfig = results.data.voteTypeConfig;
                $scope.requiredMinimumPlaytime = $scope.getMinimumPlaytime("null", $scope.voteTypeId, $scope.voteTypeConfig);
                $scope.getCategory();
                var playableMedia = [];
                playableMedia = playableMedia.concat($scope.submission.packageMedia.filter(function (pm) {
                    return pm.media.fileTypeId == 1 || pm.media.fileTypeId == 2;
                }));
                playableMedia = playableMedia.concat($scope.submission.videos);
                if (playableMedia && playableMedia.length > 0) {
                    $scope.setupPlayers();
                }
            });
        };

        $scope.setUpVideoPlayer = function (mediaId, fileTypeId, playerContainerId) {
            $scope.streamData[mediaId] = {};
            streamingDataService.getStreamingLink(mediaId).then(function (url) {
                var w = 640;
                var h = fileTypeId == 1 ? 40 : 360;

                var onPlay = function () {
                    if ($scope.startingTime > 0) {
                        console.log('seeking to: ' + $scope.startingTime);
                        jwplayer(playerContainerId).seek($scope.startingTime);
                    }
                };

                var onTime = function (event) {
                    var lastPosition = $scope.streamData[mediaId].lastPosition ? Math.floor($scope.streamData[mediaId].lastPosition) : 0;
                    var currPosition = Math.floor(event.position);
                    if (currPosition > lastPosition) {
                        $scope.streamData[mediaId].lastPosition = currPosition;
                    }
                };

                var onSeek = function (event) {

                    if (event.offset <= event.position) {
                        // Ok to scrub back
                        return;
                    }

                    var furthestWatchedPosition = Math.max($scope.startingTime, $scope.streamData[mediaId].lastPosition ? $scope.streamData[mediaId].lastPosition : 0);
                    if (event.offset <= furthestWatchedPosition) {
                        // Ok to scrub to already watched point
                        return;
                    }

                    // It's not possible to natively prevent seeking in jwPlayer,
                    // so we seek back after 100ms. As the onTime event may be called meanwhile,
                    // we have to prevent usage being registered with a higher value
                    // for HLS sources you have to use setTimout
                    setTimeout(function () {
                        jwplayer(playerContainerId).seek(furthestWatchedPosition);
                    }, 100);
                };

                var onComplete = function (event) {
                    console.log('onComplete reached');
                };

                jwplayer(playerContainerId).setup({
                    width: w,
                    height: h,
                    playlist: [{
                        sources: [{
                            file: url,
                            type: "hls",
                            // file: "https://yangarommd-28-mmd-cust.lldns.net/s/EMMYNEWS/QA/11982.mp4/manifest.m3u8?p=65&cf=1522734107&h=dc6539eef57d760fa14489a807882543?ttl=1522701758.267&token=d735f76c83ed243a040363c380fa9608",
                            // file: "https://www.w3schools.com/html/mov_bbb.mp4",
                        }],
                        withCredentials: false,
                    }],
                }).on('play', onPlay)
                    .on('time', onTime)
                    .on('seek', onSeek)
                    .on('complete', onComplete);
            });
        };
        $scope.setupPlayers = function () {
            var setupPlayer = function (jwPlayerContainer) {
                var mediaId = jwPlayerContainer.data('media-id');
                var fileTypeId = jwPlayerContainer.data('file-type-id');
                var elementId = jwPlayerContainer.attr('id');

                $scope.setUpVideoPlayer(mediaId, fileTypeId, elementId, $scope.setCanVote);
            };

            $scope.jwPlayerWatch = $interval(function () {
                // Waits for jwPlayer script to be loaded and jwPlayerContainer to be rendered
                if (jwplayer && $('.jwPlayerContainer').length) {
                    $interval.cancel($scope.jwPlayerWatch);
                    $('.jwPlayerContainer').each(function () {
                        setupPlayer($(this));
                    });
                }
            }, 500);
        };
        $scope.setVoted = function () {
            $scope.voted = false;
            if ($scope.votes.length > 0) {
                $.each($scope.votes, function (index, vote) {
                    if (vote.submissionId == $scope.submissionId) {
                        $scope.voted = true;
                        return false;
                    }
                });
            }
        };

        $scope.checkEmptyNull = function (text) {
            return (!$.awards.is.nullOrEmpty(text));
        };
        $scope.renderSubmissionTemplate = function (catNum) {

            switch (catNum) {
                case "10":
                    $scope.submissionDetailsTemplate = $scope.submissionDetailsTemplateBaseUri + "cat" + catNum + "-submissionDetails";
                    break;
                case "1":
                case "2":
                case "3":
                case "4":
                case "30":
                case "50":
                case "6":
                case "7":
                case "8":
                case "9":
                    $scope.submissionDetailsTemplate = $scope.submissionDetailsTemplateBaseUri + "cat33-41-submissionDetails";
                    break;
                default:
                    $scope.submissionDetailsTemplate = $scope.submissionDetailsTemplateBaseUri + "base-submissionDetails";
                    break;
            } // switch
        };

        $scope.getRequireMinimumPlaytime = function (voteTypeId, voteTypeConfig) {
            var result = false;
            if (typeof voteTypeConfig !== "undefined" && voteTypeConfig != null) {
                if (voteTypeId == 1) {
                    result = voteTypeConfig["orderedList"].requireMinimumPlaytime;
                }
                else if (voteTypeId == 2) {
                    result = voteTypeConfig["unorderedList"].requireMinimumPlaytime;
                }
                else {
                    result = voteTypeConfig["criteria"].requireMinimumPlaytime;
                }
            }
            return result;
        };

        $scope.getMinimumPlaytime = function (data, voteTypeId, voteTypeConfig) {
            var result = 0;
            var usageTypeId = 3;
            if (data !== "null") {
                usageTypeId = data.usageTypeId;
            }
            // usageTypeId = 3 (streaming)
            // usageTypeId = 5 (passed required viewing time. thus no minimum playing time)
            if (usageTypeId == 3) {
                if (typeof voteTypeConfig !== "undefined" && voteTypeConfig != null) {
                    if (voteTypeId == 1) {
                        result = voteTypeConfig["orderedList"].minimumPlaytime;
                    }
                    else if (voteTypeId == 2) {
                        result = voteTypeConfig["unorderedList"].minimumPlaytime;
                    }
                    else {
                        result = voteTypeConfig["criteria"].minimumPlaytime;
                    }
                }
            }
            return result;
        };

        $scope.setStartingTime = function (result) {
            $scope.startingTime = 0;
            if (typeof result !== "undefined" &&
                typeof result.data !== "undefined" &&
                typeof result.data.streamTimeInSecs !== "undefined") {
                $scope.startingTime = result.data.streamTimeInSecs;
            }
        };

        // submission details specific vote methods
        $scope.toggleVote = function () {
            var subId = $scope.submissionId;
            if ($scope.voted) {
                $scope.votingService.deleteVoteBySubmissionId(subId);
                $scope.voted = false;
            }
            else {
                $scope.votingService.setVote(subId, $scope.ballotId);
                $scope.voted = true;
            }
        };

        $scope.setCanVote = function () {
            if ($scope.votingService.isCriteriaVoting())
                $scope.enableVote = $scope.passRequiredViewingTime && ($scope.submission.voteSubmitted == 0 || $scope.votingService.inVotesBySubmissionId($scope.submissionId));
            else
                $scope.enableVote = $scope.passRequiredViewingTime && ($scope.votingService.canVoteBySubmissionId() || $scope.votingService.inVotesBySubmissionId($scope.submissionId));
        };
        $scope.starRatingHover = function (value, key, max) {
            $scope.votingService.criteriaVotesUIInfo[key].overStar = value;
            $scope.votingService.criteriaVotesUIInfo[key].percent = 100 * (value / max);
            $scope.votingService.criteriaVotesUIInfo[key].starRatingHoverLabel = judgeRulesService.getStarRatingLabel(value);
        };

        $scope.markConflictOfInterest = function () {
            var roundId = $scope.roundId,
                submissionId = parseInt($scope.submissionId, 10),
                contactId = $scope.contactId;

            votingService.setConflictOfInterest(roundId, submissionId, contactId).then(function (results) {
                $location.path("/categorySubmissions/" + $scope.categoryId);
            });;
        };

        $scope.showConflictOfInterest = function () {
            $.awards.confirm({
                title: "Conflict of Interest?",
                message: "<p>Would you like to declare a conflict of interest for this submission? If so click YES. The submission will be removed from your ballot, and you will no longer be required to score it. Click NO if you do not wish to declare a conflict.</p>" + "<p>Judges may not vote for an entry in which they were directly involved. Though every effort is made to screen out potential conflicts of interest, they may occur. In such cases, the judge must declare a conflict of interest. Follow the instructions above to declare a conflict of interest. Note: It is not considered a conflict of interest to vote on an entry submitted by a network or production company where a judge is currently employed. However, it is a conflict if a judge was directly involved in the production of an entry, or has a special relationship with someone directly involved with an entry (a spouse or significant other, for example). If you feel that you may have a conflict, please contact [placeholder]  at [placeholder]  / [placeholder]  or [placeholder]  at [placeholder]  / [placeholder] to discuss whether or not you should vote on the submission.</p>",
                okText: "Yes",
                cancelText: "No",
                okFunction: function () {
                    $.awards.confirm({
                        title: "Conflict of Interest?",
                        message: "Are you sure you want to declare a conflict of interest for this submission? Clicking YES will remove the submission from your ballot, and you will no longer be required to vote for it.",
                        okText: "Yes",
                        cancelText: "No",
                        okFunction: function () { vm.markConflictOfInterest(); }
                    });
                }
            });
        };

        $scope.init();
    }]);