package com.mrbjoern.fitness.service;

import com.mrbjoern.fitness.domain.user.CreateUser;
import com.mrbjoern.fitness.domain.user.FitnessUser;
import com.mrbjoern.fitness.domain.user.Role;
import com.mrbjoern.fitness.domain.user.UserRole;
import com.mrbjoern.fitness.domain.workout.ExerciseConstants;
import com.mrbjoern.fitness.domain.workout.ExerciseType;
import com.mrbjoern.fitness.domain.workout.Workout;
import com.mrbjoern.fitness.repository.exercise.ExerciseTypeRepository;
import com.mrbjoern.fitness.repository.exercise.WorkoutRepository;
import com.mrbjoern.fitness.repository.user.FitnessUserRepository;
import com.mrbjoern.fitness.repository.user.UserRoleRepository;
import com.mrbjoern.fitness.util.UserUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.*;

@Service
public class InitializerService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private FitnessUserRepository fitnessUserRepository;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private ExerciseTypeRepository exerciseTypeRepository;
    @Autowired
    private WorkoutRepository workoutRepository;

    public void setTestUsers() {
        log.info("Initializing test users");

        CreateUser adminUser = new CreateUser()
                .setUsername("admin")
                .setEmail("admin@test.com")
                .setFirstName("Ad")
                .setLastName("Min")
                .setBirthday(LocalDate.of(1999, 1, 1))
                .setPassword("test")
                .setRepeatedPassword("test");
        FitnessUser preparedAdminUser = UserUtil.prepareUser(adminUser);
        Set<UserRole> adminRoles = new HashSet<>();
        adminRoles.add(userRoleRepository.findByRole(Role.ROLE_ADMIN.getRole()));
        adminRoles.add(userRoleRepository.findByRole(Role.ROLE_USER.getRole()));
        preparedAdminUser.setRoles(adminRoles);
        fitnessUserRepository.save(preparedAdminUser);

        CreateUser normalUser = new CreateUser()
                .setUsername("user")
                .setEmail("user@test.com")
                .setFirstName("Us")
                .setLastName("Er")
                .setBirthday(LocalDate.of(1999, 1, 2))
                .setPassword("test")
                .setRepeatedPassword("test");
        FitnessUser preparedNormalUser = UserUtil.prepareUser(normalUser);
        Set<UserRole> normalRoles = new HashSet<>();
        normalRoles.add(userRoleRepository.findByRole(Role.ROLE_USER.getRole()));
        preparedAdminUser.setRoles(normalRoles);
        fitnessUserRepository.save(preparedNormalUser);

    }

    public void setAdminProdUser() {
        log.info("Initializing admin user");

        CreateUser adminUser = new CreateUser()
                .setUsername("admin")
                .setEmail("admin@springfitness.com")
                .setPassword("admin")
                .setRepeatedPassword("admin");
        FitnessUser preparedAdminUser = UserUtil.prepareUser(adminUser);
        Set<UserRole> adminRoles = new HashSet<>();
        adminRoles.add(userRoleRepository.findByRole(Role.ROLE_ADMIN.getRole()));
        adminRoles.add(userRoleRepository.findByRole(Role.ROLE_USER.getRole()));
        preparedAdminUser.setRoles(adminRoles);
        fitnessUserRepository.save(preparedAdminUser);
    }

    public void setDefaultRoles() {
        log.info("Initializing user roles");

        userRoleRepository.save(new UserRole(Role.ROLE_ADMIN));
        userRoleRepository.save(new UserRole(Role.ROLE_SUPERUSER));
        userRoleRepository.save(new UserRole(Role.ROLE_USER));
    }

    public void setDefaultExerciseTypes() {
        log.info("Initializing exercise types");

        List<ExerciseType> exerciseTypes = new LinkedList<>();

        exerciseTypes.add(new ExerciseType()
                .setName("Walk")
                .setUnitType(ExerciseConstants.UnitTypes.METER));

        exerciseTypes.add(new ExerciseType()
                .setName("Run")
                .setUnitType(ExerciseConstants.UnitTypes.METER));

        exerciseTypes.add(new ExerciseType()
                .setName("Deadlift")
                .setUnitType(ExerciseConstants.UnitTypes.KILOGRAM));

        exerciseTypeRepository.save(exerciseTypes);
    }

    public void setDefaultExercisesForUserWithId(final long id) {
        log.info("Initializing workouts for user with id " + id);

        FitnessUser user = fitnessUserRepository.findOne(id);

        Workout workout = new Workout();
        workout.setFitnessUser(user);
        workout.setTimestamp(new Timestamp(System.currentTimeMillis()));
        workoutRepository.save(workout);

        Workout workout2 = new Workout();
        workout2.setFitnessUser(user);
        workout2.setTimestamp(new Timestamp(System.currentTimeMillis()));
        workoutRepository.save(workout2);
    }
}
