package com.atlassian.stash.internal.web.onboarding;

import com.atlassian.bitbucket.util.UrlUtils;
import com.atlassian.sal.api.usersettings.UserSettings;
import com.atlassian.stash.internal.user.InternalUserSettingsService;
import com.atlassian.stash.internal.web.soy.StashSoyResponseBuilder;
import com.atlassian.bitbucket.auth.AuthenticationContext;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

import static com.atlassian.stash.internal.ApplicationConstants.SEEN_BITBUCKET_UPGRADE_PAGE_KEY;
import static com.atlassian.stash.internal.ApplicationConstants.SHOW_GETTING_STARTED_PAGE_KEY;

@Controller
public class OnboardingController {
    private static final String NEXT_URL = "nextUrl";

    static final String GETTING_STARTED = "bitbucket.internal.onboarding.gettingstarted";
    static final String UPGRADE_ONBOARDING = "bitbucket.internal.onboarding.upgradeonboarding";
    static final String WAS_REDIRECTED = "wasRedirected";

    private final InternalUserSettingsService userSettingsService;
    private final AuthenticationContext authenticationContext;

    @Autowired
    public OnboardingController(InternalUserSettingsService userSettingsService,
                                AuthenticationContext authenticationContext) {
        this.userSettingsService = userSettingsService;
        this.authenticationContext = authenticationContext;
    }

    @RequestMapping(value = "/getting-started", method = RequestMethod.GET)
    public ModelAndView gettingStarted(@RequestParam(value = "next", required = false) String nextUrl,
                                       @RequestHeader(value = "referer", required = false) String referrer,
                                       HttpServletRequest request) {
        Map<String, Object> context = ImmutableMap.of(WAS_REDIRECTED, showGettingStarted());

        if (StringUtils.isBlank(nextUrl)) {
            nextUrl = StringUtils.isBlank(referrer) ? request.getContextPath() : UrlUtils.getPathAndQuery(referrer);
        }

        return render(GETTING_STARTED, nextUrl, "/getting-started", context, request);
    }

    @RequestMapping(value = "/upgrade-onboarding", method = RequestMethod.GET)
    public ModelAndView upgradeOnboarding(@RequestParam(value = "next", required = false) String nextUrl,
                                       HttpServletRequest request) {
        updateUserSettings();
        return render(UPGRADE_ONBOARDING, nextUrl, "/upgrade-onboarding", null, request);
    }

    private ModelAndView render(String template, String nextUrl, String requestPath, Map<String, Object> context,
                                HttpServletRequest request) {
        StashSoyResponseBuilder builder = new StashSoyResponseBuilder(template);
        if (context != null) {
            builder.putAll(context);
        }
        builder.put(NEXT_URL, StringUtils.isBlank(nextUrl) || nextUrl.contains(requestPath) ? request.getContextPath() : nextUrl);
        return builder.build();
    }

    private boolean showGettingStarted() {
        ApplicationUser currentUser = authenticationContext.getCurrentUser();
        UserSettings userSettings = userSettingsService.getUserSettings(currentUser);

        boolean showGettingStarted = userSettings.getBoolean(SHOW_GETTING_STARTED_PAGE_KEY).getOrElse(false);
        if (showGettingStarted) {
            updateUserSettings();
        }
        return showGettingStarted;
    }

    private void updateUserSettings() {
        ApplicationUser currentUser = authenticationContext.getCurrentUser();

        if (currentUser != null) {
            userSettingsService.updateUserSettings(currentUser, input -> {
                return input
                        .remove(SHOW_GETTING_STARTED_PAGE_KEY)
                        .put(SEEN_BITBUCKET_UPGRADE_PAGE_KEY, true)
                        .build();
            });
        }
    }
}
