/* 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 { CommandFactory } from './commands';
import { getGoConfig } from './config';
import { extensionId } from './const';
import { GoExtensionContext } from './context';
import {
	developerSurveyConfig,
	getDeveloperSurveyConfig,
	maybePromptForDeveloperSurvey,
	promptForDeveloperSurvey
} from './goDeveloperSurvey';
import { outputChannel } from './goStatus';
import { getLocalGoplsVersion } from './language/goLanguageServer';
import { getFromGlobalState, getFromWorkspaceState, updateGlobalState } from './stateUtils';
import { getGoVersion } from './util';
import { promptNext4Weeks } from './utils/randomDayutils';

// 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. (It is no longer necessarily in the current 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();
		const { lastUserAction = new Date() } = goCtx;
		// Make sure the user has been idle for at least a minute.
		if (minutesBetween(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) < 28) {
			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 next 4 weeks 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) {
		cfg.dateToPromptThisMonth = promptNext4Weeks(now);
	} else {
		cfg.dateToPromptThisMonth = undefined;
	}
	cfg.dateComputedPromptThisMonth = now;
	flushSurveyConfig(goplsSurveyConfig, cfg);
	return cfg;
}

async function promptForGoplsSurvey(
	goCtx: GoExtensionContext,
	cfg: GoplsSurveyConfig = {},
	now: Date
): Promise<GoplsSurveyConfig> {
	const 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://go.dev/s/ide-hats-survey/?s=c&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;

			const 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 const resetSurveyConfigs: CommandFactory = () => () => {
	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 const showSurveyConfig: CommandFactory = (ctx, goCtx) => async () => {
	// 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());
}
