/* eslint-disable @typescript-eslint/no-explicit-any */
/*---------------------------------------------------------
 * Copyright 2021 The Go Authors. All rights reserved.
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 *--------------------------------------------------------*/

'use strict';

import vscode = require('vscode');
import { getLocalGoplsVersion } from './language/goLanguageServer';
import { outputChannel } from './goStatus';
import { extensionId } from './const';
import { getFromGlobalState, getFromWorkspaceState, updateGlobalState } from './stateUtils';
import {
	developerSurveyConfig,
	getDeveloperSurveyConfig,
	maybePromptForDeveloperSurvey,
	promptForDeveloperSurvey
} from './goDeveloperSurvey';
import { getGoConfig } from './config';
import { getGoVersion } from './util';
import { GoExtensionContext } from './context';

// GoplsSurveyConfig is the set of global properties used to determine if
// we should prompt a user to take the gopls survey.
export interface GoplsSurveyConfig {
	// prompt is true if the user can be prompted to take the survey.
	// It is false if the user has responded "Never" to the prompt.
	prompt?: boolean;

	// promptThisMonth is true if we have used a random number generator
	// to determine if the user should be prompted this month.
	// It is undefined if we have not yet made the determination.
	promptThisMonth?: boolean;

	// dateToPromptThisMonth is the date on which we should prompt the user
	// this month.
	dateToPromptThisMonth?: Date;

	// dateComputedPromptThisMonth is the date on which the values of
	// promptThisMonth and dateToPromptThisMonth were set.
	dateComputedPromptThisMonth?: Date;

	// lastDatePrompted is the most recent date that the user has been prompted.
	lastDatePrompted?: Date;

	// lastDateAccepted is the most recent date that the user responded "Yes"
	// to the survey prompt. The user need not have completed the survey.
	lastDateAccepted?: Date;
}

export function maybePromptForGoplsSurvey(goCtx: GoExtensionContext) {
	// First, check the value of the 'go.survey.prompt' setting to see
	// if the user has opted out of all survey prompts.
	const goConfig = getGoConfig();
	if (goConfig.get('survey.prompt') === false) {
		return;
	}
	const now = new Date();
	let cfg = shouldPromptForSurvey(now, getGoplsSurveyConfig());
	if (!cfg) {
		return;
	}
	if (!cfg.dateToPromptThisMonth) {
		return;
	}
	const callback = async () => {
		const currentTime = new Date();

		// Make sure the user has been idle for at least a minute.
		if (minutesBetween(goCtx.lastUserAction, currentTime) < 1) {
			setTimeout(callback, 5 * timeMinute);
			return;
		}
		cfg = await promptForGoplsSurvey(goCtx, cfg, now);
		if (cfg) {
			flushSurveyConfig(goplsSurveyConfig, cfg);
		}
	};
	const ms = msBetween(now, cfg.dateToPromptThisMonth);
	setTimeout(callback, ms);
}

export function shouldPromptForSurvey(now: Date, cfg: GoplsSurveyConfig): GoplsSurveyConfig | undefined {
	// If the prompt value is not set, assume we haven't prompted the user
	// and should do so.
	if (cfg.prompt === undefined) {
		cfg.prompt = true;
	}
	flushSurveyConfig(goplsSurveyConfig, cfg);
	if (!cfg.prompt) {
		return;
	}

	// Check if the user has taken the survey in the last year.
	// Don't prompt them if they have been.
	if (cfg.lastDateAccepted) {
		if (daysBetween(now, cfg.lastDateAccepted) < 365) {
			return;
		}
	}

	// Check if the user has been prompted for the survey in the last 90 days.
	// Don't prompt them if they have been.
	if (cfg.lastDatePrompted) {
		if (daysBetween(now, cfg.lastDatePrompted) < 90) {
			return;
		}
	}

	// Check if the extension has been activated this month.
	if (cfg.dateComputedPromptThisMonth) {
		// The extension has been activated this month, so we should have already
		// decided if the user should be prompted.
		if (daysBetween(now, cfg.dateComputedPromptThisMonth) < 30) {
			return cfg;
		}
	}
	// This is the first activation this month (or ever), so decide if we
	// should prompt the user. This is done by generating a random number in
	// the range [0, 1) and checking if it is < probability.
	// We then randomly pick a day in the rest of the month on which to prompt
	// the user.
	// Probability is set based on the # of responses received, and will be
	// decreased if we begin receiving > 200 responses/month.
	const probability = 0.06;
	cfg.promptThisMonth = Math.random() < probability;
	if (cfg.promptThisMonth) {
		// end is the last day of the month, day is the random day of the
		// month on which to prompt.
		const end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
		const day = randomIntInRange(now.getUTCDate(), end.getUTCDate());
		cfg.dateToPromptThisMonth = new Date(now.getFullYear(), now.getMonth(), day);
	} else {
		cfg.dateToPromptThisMonth = undefined;
	}
	cfg.dateComputedPromptThisMonth = now;
	flushSurveyConfig(goplsSurveyConfig, cfg);
	return cfg;
}

// randomIntInRange returns a random integer between min and max, inclusive.
function randomIntInRange(min: number, max: number): number {
	const low = Math.ceil(min);
	const high = Math.floor(max);
	return Math.floor(Math.random() * (high - low + 1)) + low;
}

async function promptForGoplsSurvey(
	goCtx: GoExtensionContext,
	cfg: GoplsSurveyConfig = {},
	now: Date
): Promise<GoplsSurveyConfig> {
	let selected = await vscode.window.showInformationMessage(
		`Looks like you are using the Go extension for VS Code.
Could you help us improve this extension by filling out a 1-2 minute survey about your experience with it?`,
		'Yes',
		'Not now',
		'Never'
	);

	// Update the time last asked.
	cfg.lastDatePrompted = now;

	switch (selected) {
		case 'Yes':
			{
				const { latestConfig } = goCtx;
				cfg.lastDateAccepted = now;
				cfg.prompt = true;
				const goplsEnabled = latestConfig?.enabled;
				const usersGoplsVersion = await getLocalGoplsVersion(latestConfig);
				const goV = await getGoVersion();
				const goVersion = goV ? (goV.isDevel ? 'devel' : goV.format(true)) : 'na';
				const surveyURL = `https://google.qualtrics.com/jfe/form/SV_agUVNbrDS0Cak2W?usingGopls=${goplsEnabled}&gopls=${usersGoplsVersion?.version}&extid=${extensionId}&go=${goVersion}&os=${process.platform}`;
				await vscode.env.openExternal(vscode.Uri.parse(surveyURL));
			}
			break;
		case 'Not now':
			cfg.prompt = true;

			vscode.window.showInformationMessage("No problem! We'll ask you again another time.");
			break;
		case 'Never':
			cfg.prompt = false;

			selected = await vscode.window.showInformationMessage(
				`No problem! We won't ask again.
To opt-out of all survey prompts, please disable the 'Go > Survey: Prompt' setting.`,
				'Open Settings'
			);
			switch (selected) {
				case 'Open Settings':
					vscode.commands.executeCommand('workbench.action.openSettings', 'go.survey.prompt');
					break;
				default:
					break;
			}
			break;
		default:
			// If the user closes the prompt without making a selection, treat it
			// like a "Not now" response.
			cfg.prompt = true;

			break;
	}
	return cfg;
}

export const goplsSurveyConfig = 'goplsSurveyConfig';

function getGoplsSurveyConfig(): GoplsSurveyConfig {
	return getStateConfig(goplsSurveyConfig) as GoplsSurveyConfig;
}

export function resetSurveyConfigs() {
	flushSurveyConfig(goplsSurveyConfig, null);
	flushSurveyConfig(developerSurveyConfig, null);
}

export function flushSurveyConfig(key: string, cfg: any) {
	if (cfg) {
		updateGlobalState(key, JSON.stringify(cfg));
	} else {
		updateGlobalState(key, null); // reset
	}
}

export function getStateConfig(globalStateKey: string, workspace?: boolean): any {
	let saved: any;
	if (workspace === true) {
		saved = getFromWorkspaceState(globalStateKey);
	} else {
		saved = getFromGlobalState(globalStateKey);
	}
	if (saved === undefined) {
		return {};
	}
	try {
		const cfg = JSON.parse(saved, (key: string, value: any) => {
			// Make sure values that should be dates are correctly converted.
			if (key.toLowerCase().includes('date') || key.toLowerCase().includes('timestamp')) {
				return new Date(value);
			}
			return value;
		});
		return cfg || {};
	} catch (err) {
		console.log(`Error parsing JSON from ${saved}: ${err}`);
		return {};
	}
}

export async function showSurveyConfig(goCtx: GoExtensionContext) {
	// TODO(rstambler): Add developer survey config.
	outputChannel.appendLine('HaTs Survey Configuration');
	outputChannel.appendLine(JSON.stringify(getGoplsSurveyConfig(), null, 2));
	outputChannel.show();

	outputChannel.appendLine('Developer Survey Configuration');
	outputChannel.appendLine(JSON.stringify(getDeveloperSurveyConfig(), null, 2));
	outputChannel.show();

	let selected = await vscode.window.showInformationMessage('Prompt for HaTS survey?', 'Yes', 'Maybe', 'No');
	switch (selected) {
		case 'Yes':
			promptForGoplsSurvey(goCtx, getGoplsSurveyConfig(), new Date());
			break;
		case 'Maybe':
			maybePromptForGoplsSurvey(goCtx);
			break;
		default:
			break;
	}
	selected = await vscode.window.showInformationMessage('Prompt for Developer survey?', 'Yes', 'Maybe', 'No');
	switch (selected) {
		case 'Yes':
			promptForDeveloperSurvey(getDeveloperSurveyConfig(), new Date());
			break;
		case 'Maybe':
			maybePromptForDeveloperSurvey(goCtx);
			break;
		default:
			break;
	}
}

export const timeMinute = 1000 * 60;
const timeHour = timeMinute * 60;
export const timeDay = timeHour * 24;

// daysBetween returns the number of days between a and b.
export function daysBetween(a: Date, b: Date): number {
	return msBetween(a, b) / timeDay;
}

// minutesBetween returns the number of minutes between a and b.
export function minutesBetween(a: Date, b: Date): number {
	return msBetween(a, b) / timeMinute;
}

export function msBetween(a: Date, b: Date): number {
	return Math.abs(a.getTime() - b.getTime());
}
