angular
        .module('carfriend')
        .controller('AccountCtrl', AccountCtrl);

function AccountCtrl(AuthService, $ionicPopup, $scope, $state, $filter, LoadingService, CarService, $cordovaCamera,
        geolocationService, ColorService, NotificationsService, $interval, UsersService, ionicMaterialInk,
        CleaningService, ParkingService, $q, $ionicModal, ionicDatePicker) {

    var vm = this;
    var interval;
    var ipObj1 = {
        callback: function (val) {
            vm.car.stk = new Date(val);
        },
        disabledDates: [],
        from: new Date(),
        to: new Date(2025, 10, 30),
        mondayFirst: true,
        disableWeekdays: [],
        closeOnSelect: false,
        templateType: 'popup'
    };
    /*functions*/
    vm.addNewCar = addNewCar;
    vm.resetForm = resetForm;
    vm.updateCarDetails = updateCarDetails;
    vm.uploadPhoto = uploadPhoto;
    vm.unsecureMe = unsecureMe;
    vm.insertStreetByGPS = insertStreetByGPS;
    vm.insertStreetManually = insertStreetManually;
    vm.showDistance = showDistance;
    vm.openModal = openModal;
    vm.hideModal = closeModal;
    vm.openCalendar = openCalendar;
    vm.stkDisplayChange = stkDisplayChange;
    vm.getHomeStreet = getHomeStreet;
    vm.deleteGPSError = deleteGPSError;
    vm.secureMe = secureMe;
    vm.goToProfile = goToProfile;
    vm.formatSituation = formatSituation;
    vm.getGPSGeocode = getGPSGeocode;
    vm.doRefresh = doRefresh;
    
    /*variables*/
    vm.currentUser = AuthService.getUser();
    vm.colorsOffer = ColorService.getColors();
    vm.car = CarService.getCar();
    vm.car.hex = ColorService.getColors()[vm.car.color];
    vm.isDriver;
   


    /*first load*/
    initialize();
    initNewCar();
    calculateDaysToStk();
    ionicMaterialInk.displayEffect();

    $scope.$watch('vm.newCar.evidenceNumber', function (val) {
        vm.newCar.evidenceNumber = $filter('uppercase')(val);
    });

    $scope.$on("$ionicView.beforeEnter", function (scopes, states) {
        vm.currentUser = AuthService.getUser();
        vm.car = CarService.getCar();
        if (vm.currentUser.details.userType === "driver") {
            vm.isDriver = true;
            loadRunningSecurity();
            setTimeout(function () {
                $scope.$apply(function () {
                    $scope.$broadcast('checkNewNotif');
                    $scope.$broadcast('getReceivedNotif', 5);
                });
            }, 200);
        } else
            vm.isDriver = false;
    });


    $scope.$on("$ionicView.beforeLeave", function (scopes, states) {
        $scope.$broadcast('clearNewNotif');
        vm.newNotif = false;
    });

    $scope.$on("$ionicView.loaded", function (scopes, states) {
        if (vm.currentUser.details.userType === "driver") {
            LoadingService.startLoad();
            lastParking();
        }

    });


    $scope.$on("newNotification", function (event, args) {
        vm.newNotif = true;
    });


    $ionicModal.fromTemplateUrl('templates/near-events.html', {
        scope: $scope,
        animation: 'slide-in-up'
    }).then(function (modal) {
        vm.modal = modal;
    });

    $scope.$on('refreshReceivedEnd', function (a, b) {
        $scope.$broadcast('scroll.refreshComplet');
    });


    ////////////////////////

    /* zakladne funkcie */
    function initialize() {
        vm.addYourCar = false;
        vm.homeStreetError = false;      
        vm.lastParkingHistory = {};
         clearSecurityValues();
    };
    
    function clearSecurityValues() {
        vm.streetCleaning = {};
        vm.noStreetcleaning = {};
        vm.streetResults = {};

        vm.parkingData = {
            location: {},
            coords: {},
            id: "",
            from: "",
            to: ""
        };
        vm.secureMeError = false;
    }
    ;
    function doRefresh() {
        if (vm.isDriver) {
            lastParking();
        };
        $scope.$broadcast('refreshReceivedNotif');
    };


    /* pridanie noveho vozidla*/
    function checkIfCarAlreadyExist() {
        return CarService.findCarByEvc(vm.newCar.evidenceNumber).then(function (data) {
            if (data && data.data && data.data.totalRows === 0)
                return false;
            else
                return true;
        });
    }
    ;
    function addNewCar() {
        vm.result = {};
        vm.addCarLoading = true;
        checkIfCarAlreadyExist().then(function (exist) {
            if (exist) {
                handleNewCarResult(1);
            } else {
                vm.newCar.user = vm.currentUser.details.id;
                CarService.create(vm.newCar).then(function () {
                    UsersService.update(vm.currentUser.details.id, {userType: "driver"}).then(function (res) {
                        handleNewCarResult(0);
                        AuthService.getCurrentUserInfo();
                        CarService.all(vm.currentUser.details.id);
                    }, function (err) {
                        handleNewCarResult(2, err);
                    }, function (err) {
                        handleNewCarResult(2, err);
                    });
                });
            }
        });
    }
    ;
    function handleNewCarResult(code, err) {
        vm.addCarLoading = false;
        var messages = [];
        messages.push("Vozidlo bolo úspešne pridané.");
        messages.push("Toto vozidlo je už zaregistrované v carfriend");
        messages.push("Nastala chyba pri pridávaní vozidla. Skúste to znova.");
        vm.result = {
            status: code,
            message: messages[code]
        };
    }
    ;
    function initNewCar() {
        vm.newCar = {};
        vm.result = {};
    }
    ;
    function resetForm() {
        vm.addYourCar = false;
        vm.addCarLoading = false;
        vm.addCarForm.$setPristine();
        vm.addCarForm.$setUntouched();
        initNewCar();
    }
    ;

    /* praca s vozidlom */
    function updateCarDetails() {
        CarService.update(vm.car.id, vm.car).then(function (success) {
            calculateDaysToStk();
        }, function (error) {
        });
    }
    ;
    function uploadPhoto() {
        var options = {
            quality: 80,
            destinationType: Camera.DestinationType.DATA_URL,
            sourceType: Camera.PictureSourceType.CAMERA,
            encodingType: Camera.EncodingType.JPEG,
            targetWidth: 300,
            targetHeight: 300,
            popoverOptions: CameraPopoverOptions,
            saveToPhotoAlbum: false,
            allowEdit: false,
            correctOrientation: true
        };
        $cordovaCamera.getPicture(options).then(function (imageData) {
            vm.car.photo = "data:image/jpeg;base64," + imageData;
        }, function (err) {
            $ionicPopup.alert({
                title: err,
                template: "Skúste znova alebo pokračujte bez fotky.",
                buttons: [{
                        text: '<b>OK</b>',
                        type: 'button-assertive'
                    }]
            });
        });
    }
    ;
    function getHomeStreet() {
        getCurrentGPSInfo(1).then(function (data) {
            if (!$filter('isEmpty')(data)) {
                vm.car.homeStreet = data.street;
            }
            ;
        });
    }
    ;
    function openCalendar() {
        ionicDatePicker.openDatePicker(ipObj1);
    }
    ;
    function stkDisplayChange() {
        if (vm.daysToStk) {
            if (vm.selection === "true")
                vm.selection = "false";
            else
                vm.selection = "true";
        }
    }
    ;
    function calculateDaysToStk() {
        if (vm.car.stk !== null) {
            var today = new Date();
            var stk = new Date(vm.car.stk);
            var oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds
            var dayz = Math.round(Math.abs((stk.getTime() - today.getTime()) / (oneDay)));
            vm.daysToStk = dayz;

            vm.stkAlert = dayz < 10 ? true : false;
        }
    }
    ;
    function lastParking() {
        var pom = {};
        ParkingService.lastParkingInfo(vm.car.id).then(function (history) {
            if (history && history.data && history.data.data && history.data.data.length === 1) {
                vm.lastParkingHistory.isData = true;
                pom = {
                    latitude: history.data.data[0].geo[0],
                    longitude: history.data.data[0].geo[1]
                };
                geolocationService.getCurrentLocation(pom).then(function (loc) {
                    var address_components = loc[0].address_components;
                    var location = {};
                    angular.forEach(address_components, function (value1, key1) {
                        angular.forEach(value1.types, function (value2, key2) {
                            location[value2] = value1.long_name;
                        });
                    });
                    vm.lastParkingHistory.from = history.data.data[0].from;
                    vm.lastParkingHistory.street = location["route"];

                }, function (locationErr) {
                    console.log(locationErr);
                });
            } else
                vm.lastParkingHistory.isData = false;
        });
    }
    ;
    
    /* zabezpecenie vozidla*/
    function getCurrentGPSInfo(errorType) {
        var position = {};
        var location = {};
        var street = "";
        return geolocationService.getCurrentPosition().then(function (pos) {
            position = pos.coords;
            return geolocationService.getCurrentLocation(position).then(function (loc) {
                var address_components = loc[0].address_components;
                angular.forEach(address_components, function (value1, key1) {
                    angular.forEach(value1.types, function (value2, key2) {
                        location[value2] = value1.long_name;
                    });
                });
                street = location["route"];

                var results = {
                    position: position,
                    location: location,
                    street: street
                };
                return  results;
            }, function (locationErr) {
                return handleGPSError(locationErr, errorType);
            });
        }, function (positionErr) {
            return handleGPSError(positionErr, errorType);
        });
    }
    ;

    function handleGPSError(err, errorType) {
        if (errorType === 1)
            vm.homeStreetError = true;
        else
            vm.secureMeError = true;
        return {};
    }
    ;

    function deleteGPSError(errorType) {
        if (errorType === 1)
            vm.homeStreetError = false;
        else
            vm.secureMeError = false;
    }
    ;

    function insertStreetByGPS() {
        vm.parkingData.location = {};
        getCurrentGPSInfo(2).then(function (data) {
            if (!$filter('isEmpty')(data)) {
                vm.parkingData.coords = {
                    latitude: data.position.latitude,
                    longitude: data.position.longitude
                }
                vm.parkingData.location = data.location;
                secureMe();
            }
            ;
        });
    }
    ;

    function insertStreetManually(street) {
        vm.streetResults = {};
        geolocationService.isStreetExist(street).then(function (res) {
            if (res.length === 0)
                vm.streetResults.error = true;
            else {
                vm.streetResults.error = false;
                vm.streetResults = res;
            }
        });
    }
    ;

    function getGPSGeocode(location) {
        var lat, lng;
        angular.forEach(location.address_components, function (value1, key1) {
            angular.forEach(value1.types, function (value2, key2) {
                vm.parkingData.location[value2] = value1.long_name;
            });
        });

        lat = location.geometry.location.lat();
        lng = location.geometry.location.lng();
       vm.parkingData.coords = {
            latitude: lat,
            longitude: lng
        };
        secureMe();
    }

    function secureMe() {
        vm.loadingSecureMeData = true;
        var promises = [];
        if(vm.parkingData.id === "")
            promises.push(saveCurrentLocation());
        
        promises.push(checkCleaning());
        promises.push(checkStreetHistory());
        $q.all(promises).then(function (nepotrebneData) {
            if (nepotrebneData.length === promises.length) {
                timeSetup();
                deleteGPSError(2);
                vm.startSecure = true;
                vm.loadingSecureMeData = false;
            }
        });
    }
    ;

    function saveCurrentLocation() {
        vm.parkingData.id = "";
        var d1 = new Date(),
                d2 = new Date(d1);
        d2.setMinutes(d1.getMinutes() + 60);
        vm.parkingData.from = $filter('date')(d1, 'yyyy-MM-dd HH:mm:ss');
        vm.parkingData.to = $filter('date')(d2, 'yyyy-MM-dd HH:mm:ss');
        var postData = {
            car: vm.car.id,
            geo: [vm.parkingData.coords.latitude, vm.parkingData.coords.longitude],
            security: true,
            from: vm.parkingData.from,
            to: vm.parkingData.to
        };
        return ParkingService.post(postData).then(function (parkingID) {
            vm.parkingData.id = parkingID.data.__metadata.id;
        });
    }
    ;

    function checkCleaning() {
        vm.streetCleaning = {};
        vm.noStreetcleaning = {};
        return CleaningService.checkLocality(vm.parkingData.location["locality"]).then(function (lokalita) {
            if (lokalita.data && lokalita.data.data && lokalita.data.data.length === 1)
                return CleaningService.checkCleaningToday(vm.parkingData.location["route"], vm.parkingData.location["locality"]).then(function (cistenie) {
                    if (cistenie.data && cistenie.data.data && cistenie.data.data.length === 1)
                        vm.streetCleaning = cistenie.data.data[0];
                    else
                        handleCleaningResults(true, 1, false);
                });
            else
                handleCleaningResults(false, 3, false);
            return true;
        });
    }
    ;
    function handleCleaningResults(localityInList, status, streetNotFound) {
        var info;
        switch (status) {
            case 1:
                info = "Dnes sa na tejto ulici nekoná čistenie.";
                break;
            case 2:
                info = "Na tejto ulici sa nikdy nekoná blokové čistenie.";
                break;
            case 3:
                info = "Mrzí nás to, ale nemáme informácie o blokových čisteniach v tejto lokalite.";
                break;
            case 4:
                info = "Zadaná ulica je neznáma, a preto nevieme určiť či prebieha blokové čistenie.";
                break;
        }
        ;

        vm.noStreetcleaning = {
            localityInList: localityInList,
            streetNotFound: streetNotFound,
            info: info
        };
    }
    ;
    
    function checkStreetHistory() {
        var vzdialenost = 800; //metrov
        vm.streetHistory = {};
        return NotificationsService.getHistoryOfCurrentPosition(vzdialenost, vm.parkingData.coords).then(function (his) {
            if (his.data && his.data.data && his.data.data.length > 0)
                vm.streetHistory = his.data.data;
            return true;
        });
    }
    ;

    function formatSituation(d) {
        if (d === "clamp")
            d = "Papuča na kolese";
        if (d === "towing")
            d = "Odtiahnutie vozidla";
        if (d === "accident")
            d = "Nehoda";
        if (d === "broken_lights")
            d = "Pokazené svetlá";
        if (d === "vagabonds")
            d = "Nebezpečné osoby";
        if (d === "parking_tickets")
            d = "Parkovacie lístky";
        return d;
    }
    ;
 
    function loadRunningSecurity() {
        if (vm.parkingData.id === "") {
            ParkingService.getCurrentSecurity(vm.car.id).then(function (d) {
                if (d && d.data.data && d.data.data.length === 1) {
                    var minutes = getDifference(d.data.data[0].to);
                    if (minutes < 0){
                        vm.parkingData.id = d.data.data[0].id;  
                        unsecureMe();
                    }                     
                    else {
                        vm.parkingData.from = d.data.data[0].from;
                        vm.parkingData.to = d.data.data[0].to;
                        vm.parkingData.coords = {
                            latitude: d.data.data[0].geo[0],
                            longitude: d.data.data[0].geo[1]
                        };
                        geolocationService.getCurrentLocation(vm.parkingData.coords).then(function (loc) {
                            var address_components = loc[0].address_components;
                            var location = {};
                            angular.forEach(address_components, function (value1, key1) {
                                angular.forEach(value1.types, function (value2, key2) {
                                    location[value2] = value1.long_name;
                                });
                            });
                            vm.parkingData.location = location;
                            secureMe();
                        });
                    }

                } else
                    vm.startSecure = false;
            });
        }
    };
    
    function unsecureMe() {
        ParkingService.disableSecurity(vm.parkingData.id).then(function (d) {
             clearSecurityValues();
            vm.startSecure = false;
            $interval.cancel(interval);
            vm.hours = 0;
            vm.minutes = 0;
        });      
    }
    ;

    function timeSetup() {
        vm.hours = 0;
        vm.minutes = getDifference(vm.parkingData.to);
        vm.time = getPadded(vm.hours) + ':' + getPadded(vm.minutes);
        interval = $interval(function () {
            if (vm.minutes === 0) {
                if (vm.hours === 0)
                    unsecureMe();
                else {
                    vm.hours -= 1;
                    vm.minutes = 59;
                }
            }               
            vm.minutes -= 1;
            vm.time = getPadded(vm.hours) + ':' + getPadded(vm.minutes);
        }, 60000);
    }
    ;

    function getPadded(val) {
        return val < 10 ? ('0' + val) : val;
    }
    ;
    function getDifference(toTime) {
        var to = $filter('date')(toTime, 'yyyy-MM-dd HH:mm:ss');
        var now = moment(new Date()); //todays date
        var end = moment(new Date(to)); // another date
        var duration = moment.duration(end.diff(now));
        var minutes = duration.asMinutes();
        return minutes.toFixed(0); 
    };

    function showDistance(not_geo) {
        if (not_geo && vm.parkingData.coords) {
            openModal();
            var myPos = vm.parkingData.coords;
            var notPos = {
                lat: not_geo[0],
                lang: not_geo[1]
            };
            var Latlng = new google.maps.LatLng(myPos.latitude, myPos.longitude);
            var LatlngNot = new google.maps.LatLng(notPos.lat, notPos.lang);
            var pathCoords = [Latlng, LatlngNot];
            var mapOptions = {
                zoom: 14,
                center: Latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                disableDefaultUI: true
            };
            var map = new google.maps.Map(document.getElementById('distanceMap'), mapOptions);
            var myPosMarker = new google.maps.Marker({
                position: Latlng,
                map: map,
                title: 'Moje vozidlo'
            });

            var notPosMarker = new google.maps.Marker({
                position: LatlngNot,
                map: map,
                title: 'Upozornenie'
            });


            var infowindowPos = new google.maps.InfoWindow({});
            infowindowPos.setContent('Moje vozidlo');
            infowindowPos.open(map, myPosMarker);

            var infowindowNot = new google.maps.InfoWindow({});
            infowindowNot.setContent('Upozornenie');
            infowindowNot.open(map, notPosMarker);

            var path = new google.maps.Polyline({
                path: pathCoords,
                strokeColor: "#ef473a",
                strokeOpacity: 0.8,
                strokeWeight: 1
            });
            vm.distance = calcDistance(Latlng, LatlngNot);
            path.setMap(map);
        }

    }
    ;

    function openModal() {
        vm.modal.show();
    }
    ;
    function closeModal() {
        vm.modal.hide();
    }
    ;

    function calcDistance(p1, p2) {
        var distance = {
            distance: 0,
            unit: "m"
        };
        distance.distance = google.maps.geometry.spherical.computeDistanceBetween(p1, p2).toFixed(2);
        if (distance.distance > 1000) {
            distance.distance = (distance.distance / 1000).toFixed(2);
            distance.unit = "km";
        }
        return distance;
    }
    ;

    function goToProfile(profile) {
        var currentState = $state.current.name;
        if (profile.identity)
            return $state.go('profile', {userID: profile.from, from: currentState});
    }
    ;
}