text: import '@brightspace-ui/core/components/inputs/input-percent';
  import '@brightspace-ui/core/components/list/list';
  import '@brightspace-ui/core/components/list/list-item';
  import '@brightspace-ui/core/components/validation/validation-custom.js';
  import '../cards/summary-card';
  import './svg/quiz-reliability-thumbnail.svg';
  import { bodySmallStyles, bodyStandardStyles, heading3Styles } from '@brightspace-ui/core/components/typography/styles';
  import { formatNumber, formatPercent } from '@brightspace-ui/intl';
  import { html, LitElement } from 'lit-element/lit-element.js';
  import { allQuizDetailsSettings } from '../../model/dataApiClient';
  import { defaults } from './defaults';
  import { Localizer } from '../../locales/localizer';
  import { nullOrUndefinded } from '../table/formatUtils';
  import { RtlMixin } from '@brightspace-ui/core/mixins/rtl-mixin';
  import { SettingsListStyles } from './styles';
  import shadowHash from '../../model/shadowHash';
  
  const numberFormatOptions = { maximumFractionDigits: 2 };
  
  export const detailsThresholdTabMapping = ['quiz-reliability-high-coef-edit', 'quiz-reliability-threshold', 'average-score-threshold-edit']
  	.reduce((acc, field) => {
  		acc[field] = 'quiz-detail-metrics';
  		return acc;
  	}, {});
  
  export function areQuizDetailsSettingsValid(settings) {
  	return isAnyCaseForQuizReliabilityThresholdsValid(settings) && isAverageScoreFlagThresholdValid(settings);
  }
  
  export function areQuizReliabilityThresholdsValid(settings) {
  	return settings.showQuizReliabilityCol && settings.showQuizReliabilityCard
  		&& settings.quizReliabilityFlagThreshold < settings.quizReliabilityHighThreshold
  		&& settings.quizReliabilityFlagThreshold >= 0 && settings.quizReliabilityFlagThreshold <= 1
  		&& settings.quizReliabilityHighThreshold >= 0 && settings.quizReliabilityHighThreshold <= 1;
  }
  
  export function isQuizReliabilityFlagThresholdValid(settings) {
  	return settings.showQuizReliabilityCol && !settings.showQuizReliabilityCard
  		&& settings.quizReliabilityFlagThreshold >= 0 && settings.quizReliabilityFlagThreshold <= 1;
  }
  
  export function isAnyCaseForQuizReliabilityThresholdsValid(settings) {
  	if (!settings.showQuizReliabilityCol && !settings.showQuizReliabilityCard) {
  		return true;
  	}
  
  	return areQuizReliabilityThresholdsValid(settings) || isQuizReliabilityFlagThresholdValid(settings);
  }
  
  export function isAverageScoreFlagThresholdValid(settings) {
  	if (!settings.showAverageScoreCol && !settings.showAverageScoreCard) {
  		return true;
  	}
  
  	return settings.showAverageScoreCol
  		&& settings.averageScoreFlagThreshold >= 0 && settings.averageScoreFlagThreshold <= 1;
  }
  
  class QuizDetailsSettingsList extends RtlMixin(Localizer(LitElement)) {
  
  	static get properties() {
  		return {
  			showAverageScoreCol: { type: Boolean, attribute: 'show-average-score-col', reflect: true },
  			averageScoreFlagThreshold: { type: Number, attribute: 'average-score-flag-threshold', reflect: true },
  			showAverageScoreCard: { type: Boolean, attribute: 'show-average-score-card', reflect: true },
  			showFlaggedQuestionCard:  { type: Boolean, attribute: 'show-flagged-question-card', reflect: true },
  			showQuizReliabilityCol: { type: Boolean, attribute: 'show-quiz-reliability-col', reflect: true },
  			showQuizReliabilityCard: { type: Boolean, attribute: 'show-quiz-reliability-card', reflect: true },
  			quizReliabilityFlagThreshold: { type: Number, attribute: 'quiz-reliability-flag-threshold', reflect: true },
  			quizReliabilityHighThreshold: { type: Number, attribute: 'quiz-reliability-high-threshold', reflect: true }
  		};
  	}
  
  	static get styles() {
  		return [bodySmallStyles, bodyStandardStyles, heading3Styles, SettingsListStyles];
  	}
  
  	constructor() {
  		super();
  
  		this.showAverageScoreCard = defaults.showAverageScoreCard;
  		this.showFlaggedQuestionCard = defaults.showFlaggedQuestionCard;
  		this.showAverageScoreCol = defaults.showAverageScoreCol;
  		this.averageScoreFlagThreshold = defaults.averageScoreFlagThreshold;
  		this.showQuizReliabilityCol = defaults.showQuizReliabilityCol;
  		this.showQuizReliabilityCard = defaults.showQuizReliabilityCard;
  		this.quizReliabilityFlagThreshold = defaults.quizReliabilityFlagThreshold;
  		this.quizReliabilityHighThreshold = defaults.quizReliabilityHighThreshold;
  	}
  
  	firstUpdated() {
  		const quizReliabilityFlagThreshold = this.shadowRoot.querySelector('#quiz-reliability-threshold');
  		shadowHash.register(quizReliabilityFlagThreshold);
  
  		const quizReliabilityHighThreshold = this.shadowRoot.querySelector('#quiz-reliability-high-coef-edit');
  		shadowHash.register(quizReliabilityHighThreshold);
  
  		const averageScoreFlagThreshold = this.shadowRoot.querySelector('#average-score-threshold-edit');
  		shadowHash.register(averageScoreFlagThreshold);
  	}
  
  	render() {
  		// NB: list-item keys MUST have the same name as their corresponding component property
  		// e.g. the key for this.showAverageScoreCol must be "showAverageScoreCol" (see _handleListChange)
  
  		return html`
  			<d2l-list id="quiz-details-settings-list" @d2l-list-selection-change="${this._handleListChange}">
  				<d2l-list-item
  					key="showAverageScoreCol"
  					label="${this.localize('settings:averageScoreColumnTitle')}"
  					selectable
  					?selected="${this.showAverageScoreCol}"
  				>
  					${this._renderAverageScoreColSettingItem()}
  				</d2l-list-item>
  
  				<d2l-list-item
  					id="showAverageScoreCardListItemId"
  					key="showAverageScoreCard"
  					label="${this.localize('settings:averageScoreCardTitle')}"
  					selectable
  					?selected="${this.showAverageScoreCard}"
  					?disabled="${!this.showAverageScoreCol}"
  				>
  					${this._renderAverageScoreCardSettingsItem()}
  				</d2l-list-item>
  
  				<d2l-list-item
  					key="showQuizReliabilityCol"
  					label="${this.localize('settings:quizReliabilityColumnTitle')}"
  					selectable
  					?selected="${this.showQuizReliabilityCol}"
  					?disabled="${this.showQuizReliabilityCard}"
  				>
  					${this._renderQuizReliabilityColSettingItem()}
  				</d2l-list-item>
  
  				<d2l-list-item
  					key="showQuizReliabilityCard"
  					label="${this.localize('settings:quizReliabilityCardTitle')}"
  					selectable
  					?selected="${this.showQuizReliabilityCard}"
  					@d2l-list-item-selected="${this._quizReliabilitySelected}"
  				>
  
  					${this._renderQuizReliabilityCardSetting()}
  				</d2l-list-item>
  
  				<d2l-list-item
  					id="showFlaggedQuestionCardListItemId"
  					key="showFlaggedQuestionCard"
  					label="${this.localize('settings:flaggedQuestionsCardTitle')}"
  					selectable
  					?selected="${this.showFlaggedQuestionCard}"
  				>
  					${this._renderFlaggedQuestionsCard()}
  				</d2l-list-item>
  			</d2l-list>
  		`;
  	}
  
  	_quizReliabilitySelected(event) {
  		const showQuizReliabilityCol = this.shadowRoot.querySelector("d2l-list-item[key='showQuizReliabilityCol']");
  		showQuizReliabilityCol.disabled = event.target.selected;
  		if (!event.target.selected) return;
  		showQuizReliabilityCol.setSelected(true);
  	}
  
  	_renderAverageScoreColSettingItem() {
  		return html`
  			<div class="d2l-insights-config-list-item">
  				<div class="d2l-column-example">${formatPercent(0.7793, numberFormatOptions)}</div>
  				<div class="d2l-column-selection-text">
  					<h3 class="d2l-heading-3">${this.localize('settings:averageScoreColumnTitle')}</h3>
  					<p class="d2l-body-standard">${this.localize('settings:averageScoreColumnDescription')}</p>
  
  					<div id="average-score">
  						<span class="d2l-body-small">${this.localize('settings:flagDataPoint')}</span>
  						<d2l-input-percent
  							id="average-score-threshold-edit"
  							class="d2l-threshold-edit-input"
  							value="${this.averageScoreFlagThreshold * 100}"
  							label="${this.localize('settings:flagAverageScoreEditLabel')}"
  							label-hidden
  							placeholder="${defaults.averageScoreFlagThreshold * 100}"
  							maxFractionDigits="2"
  							?required="${this.showAverageScoreCol}"
  							?disabled="${!this.showAverageScoreCol}"
  							@change="${this._handleAverageScoreFlagThresholdChange}"
  							@invalid-change="${this._invalidChange}"
  						></d2l-input-percent>
  					</div>
  				</div>
  			</div>
  		`;
  	}
  
  	_renderAverageScoreCardSettingsItem() {
  		const exampleThreshold = nullOrUndefinded(this.averageScoreFlagThreshold) || isNaN(this.averageScoreFlagThreshold) ?
  			defaults.averageScoreFlagThreshold :
  			this.averageScoreFlagThreshold;
  
  		const tooltip = html`
  			<d2l-tooltip for="showAverageScoreCardListItemId" offset='-50' position="left" announced>
  				${this.localize('settings:tableMetricShouldBeEnabled', { cardMetricName: this.localize('cards:averageScoreCardTitle'), tableMetricName: this.localize('settings:averageScoreColumnTitle') })}
  			</d2l-tooltip>`;
  
  		return html`
  			<div class="d2l-insights-config-list-item" >
  				<d2l-labs-summary-card
  					class="d2l-column-example"
  					card-title="${this.localize('cards:averageScoreCardTitle')}"
  					card-value="22"
  					card-message="${this.localize('cards:averageScoreCardMessage', { 'threshold': exampleThreshold * 100 })}"
  				></d2l-labs-summary-card>
  				<div class="d2l-column-selection-text">
  					<h3 class="d2l-heading-3">${this.localize('settings:averageScoreCardTitle')}</h3>
  					<p class="d2l-body-standard">${this.localize('settings:averageScoreCardDescription')}</p>
  				</div>
  			</div>
  			${!this.showAverageScoreCol ? tooltip : ''}
  		`;
  	}
  
  	_renderFlaggedQuestionsCard() {
  		return html`
  			<div class="d2l-insights-config-list-item" >
  				<d2l-labs-summary-card
  					class="d2l-column-example"
  					card-title="${this.localize('dashboard:flaggedQuestionHeading')}"
  					card-value="10"
  					card-message="${this.localize('dashboard:flaggedQuestionMessage')}"
  				></d2l-labs-summary-card>
  				<div class="d2l-column-selection-text">
  					<h3 class="d2l-heading-3">${this.localize('settings:flaggedQuestionsCardTitle')}</h3>
  					<p class="d2l-body-standard">${this.localize('settings:flaggedQuestionsCardDescription')}</p>
  				</div>
  			</div>
  		`;
  	}
  
  	_renderQuizReliabilityCardSetting() {
  		return html`
  			<div class="d2l-insights-config-list-item">
  				<d2l-insights-quiz-reliability-thumbnail class="d2l-column-example" aria-hidden="true"></d2l-insights-quiz-reliability-thumbnail>
  				<div class="d2l-column-selection-text">
  					<h3 class="d2l-heading-3">${this.localize('settings:quizReliabilityCardTitle')}</h3>
  					<p class="d2l-body-standard">${this.localize('settings:quizReliabilityCardDescription')}</p>
  
  					<div id="quiz-reliability-high-threshold">
  						<span class="d2l-body-small">${this.localize('settings:highCoefQuizReliabilityEditDescription')}</span>
  						<d2l-input-number
  							id="quiz-reliability-high-coef-edit"
  							class="d2l-threshold-edit-input"
  							value="${this.quizReliabilityHighThreshold}"
  							label="${this.localize('settings:highCoefQuizReliabilityEditLabel')}"
  							label-hidden
  							min="0"
  							max="1"
  							?required="${this.showQuizReliabilityCard}"
  							max-fraction-digits="2"
  							placeholder="${defaults.quizReliabilityHighThreshold}"
  							?disabled="${!this.showQuizReliabilityCard}"
  							@change="${this._handleQuizReliabilityHighThresholdChange}"
  							@invalid-change="${this._invalidChange}"
  						></d2l-input-number>
  						<d2l-validation-custom
  							for="quiz-reliability-high-coef-edit"
  							failure-text="${this.localize('settings:quizReliabilityHighThresholdError')}"
  							@d2l-validation-custom-validate="${this._validateQuizReliabilityThresholds}">
  						</d2l-validation-custom>
  					</div>
  				</div>
  			</div>
  		`;
  	}
  
  	_renderQuizReliabilityColSettingItem() {
  		return html`
  			<div class="d2l-insights-config-list-item">
  				<div class="d2l-column-example">${formatNumber(0.73, numberFormatOptions)}</div>
  				<div class="d2l-column-selection-text">
  					<h3 class="d2l-heading-3">${this.localize('settings:quizReliabilityColumnTitle')}</h3>
  					<p class="d2l-body-standard">${this.localize('settings:quizReliabilityColumnDescription')}</p>
  
  					<div id="quiz-reliability-threshold">
  						<span class="d2l-body-small">${this.localize('settings:flagDataPoint')}</span>
  						<d2l-input-number
  							id="quiz-reliability-threshold-edit"
  							class="d2l-threshold-edit-input"
  							value="${this.quizReliabilityFlagThreshold}"
  							label="${this.localize('settings:flagQuizReliabilityEditLabel')}"
  							label-hidden
  							min="0"
  							max="1"
  							?required="${this.showQuizReliabilityCol}"
  							max-fraction-digits="2"
  							placeholder="${defaults.quizReliabilityFlagThreshold}"
  							?disabled="${!this.showQuizReliabilityCol}"
  							@change="${this._handleQuizReliabilityFlagThresholdChange}"
  							@invalid-change="${this._invalidChange}"
  						></d2l-input-number>
  						<d2l-validation-custom
  							for="quiz-reliability-threshold-edit"
  							failure-text="${this.localize('settings:quizReliabilityFlagThresholdError')}"
  							@d2l-validation-custom-validate="${this._validateQuizReliabilityThresholds}">
  						</d2l-validation-custom>
  					</div>
  				</div>
  			</div>
  		`;
  	}
  
  	get _avgScoreThreshold() {
  		return this.shadowRoot.querySelector('#average-score-threshold-edit');
  	}
  
  	get _flagThreshold() {
  		return this.shadowRoot.querySelector('#quiz-reliability-threshold-edit');
  	}
  
  	get _highThreshold() {
  		return this.shadowRoot.querySelector('#quiz-reliability-high-coef-edit');
  	}
  
  	_getPairThreshold(thresholdElement) {
  		const pairs = {
  			'quiz-reliability-threshold-edit': this._highThreshold,
  			'quiz-reliability-high-coef-edit': this._flagThreshold
  		};
  
  		return pairs[thresholdElement.id];
  	}
  
  	_getParentListItem(thresholdElement) {
  		const pairs = {
  			'quiz-reliability-threshold-edit': () => this.shadowRoot.querySelector('d2l-list-item[key="showQuizReliabilityCol"]'),
  			'quiz-reliability-high-coef-edit': () => this.shadowRoot.querySelector('d2l-list-item[key="showQuizReliabilityCard"]')
  		};
  
  		return pairs[thresholdElement.id]();
  	}
  
  	_invalidChange(event) {
  		// this code marks both thresholds' inputs valid if a new value in one of them fix validation for both of them
  		const thresholdEl = event.target;
  		const pairThresholdEl = this._getPairThreshold(thresholdEl);
  		if (thresholdEl.value !== undefined && pairThresholdEl.invalid) {
  			pairThresholdEl.validate();
  		}
  	}
  
  	async _handleListChange(event) {
  		const key = event.detail.key;
  		this[key] = event.detail.selected;
  
  		if (key === 'showQuizReliabilityCol') {
  			await this._flagThreshold.validate();
  		}
  
  		if (key === 'showQuizReliabilityCard') {
  			await this._flagThreshold.validate();
  			await this._highThreshold.validate();
  		}
  
  		if (key === 'showAverageScoreCol') {
  			await this._avgScoreThreshold.validate();
  			if (!this.showAverageScoreCol) {
  				this.showAverageScoreCard = false;
  			}
  		}
  	}
  
  	_handleAverageScoreFlagThresholdChange(event) {
  		this.averageScoreFlagThreshold = event.target.value / 100;
  	}
  
  	_handleQuizReliabilityFlagThresholdChange(event) {
  		this.quizReliabilityFlagThreshold = event.target.value;
  	}
  
  	_handleQuizReliabilityHighThresholdChange(event) {
  		this.quizReliabilityHighThreshold = event.target.value;
  	}
  
  	_validateQuizReliabilityThresholds(event) {
  		let isValid = false;
  		const thresholdEl = event.detail.forElement;
  		const threshold = thresholdEl.value;
  		const pairThresholdEl = this._getPairThreshold(thresholdEl);
  		const pairThreshold = pairThresholdEl.value;
  		const parentListItemDeselected = !this._getParentListItem(thresholdEl).selected;
  
  		// if the parent setting list item is invalid then the threshold does not matter
  		if (!this._getParentListItem(pairThresholdEl).selected) {
  			isValid = threshold >= 0 && threshold <= 1;
  			event.detail.resolve(isValid);
  			return;
  		}
  
  		isValid = isAnyCaseForQuizReliabilityThresholdsValid(this.settings)
  			// Progressive validation. Despite both thresholds can be invalid at the moment,
  			// this line makes input valid anyway if it has a value and the pair input is empty
  			|| (threshold !== undefined && pairThreshold === undefined && threshold >= 0 && threshold <= 1);
  
  		event.detail.resolve(isValid || parentListItemDeselected);
  	}
  
  	async getValidationErrors() {
  		const errors = [];
  
  		if (this._flagThreshold.invalid && this.showQuizReliabilityCol) {
  			const flagThresholdErrors = await this._flagThreshold.validate();
  			errors.push({
  				errorMessage: flagThresholdErrors[0],
  				id: 'quiz-reliability-threshold'
  			});
  		}
  
  		if (this._highThreshold.invalid && this.showQuizReliabilityCard) {
  			const highThresholdErrors = await this._highThreshold.validate();
  			errors.push({
  				errorMessage: highThresholdErrors[0],
  				id: 'quiz-reliability-high-coef-edit'
  			});
  		}
  
  		// bug? this._avgScoreThreshold.invalid return false even the valiate method returns errors.
  		const avgScoreThresholdErrors = await this._avgScoreThreshold.validate();
  		if (avgScoreThresholdErrors.length > 0 && this.showAverageScoreCol) {
  			errors.push({
  				errorMessage: avgScoreThresholdErrors[0],
  				id: 'average-score-threshold-edit'
  			});
  		}
  
  		if (errors.length === 0 && !areQuizDetailsSettingsValid(this.settings)) {
  			// something wrong with thresholds' inputs states. Back-end should return an error
  			console.error('Validation Error. getValidationErrors should return list of errors but it is empty.', this.settings);
  		}
  
  		return errors;
  	}
  
  	get settings() {
  		const settings = {
  			showAverageScoreCol: this.showAverageScoreCol,
  			showAverageScoreCard: this.showAverageScoreCard,
  			averageScoreFlagThreshold: this.averageScoreFlagThreshold,
  			showFlaggedQuestionCard: this.showFlaggedQuestionCard,
  			showQuizReliabilityCol: this.showQuizReliabilityCol,
  			showQuizReliabilityCard: this.showQuizReliabilityCard,
  			quizReliabilityFlagThreshold: this.quizReliabilityFlagThreshold,
  			quizReliabilityHighThreshold: this.quizReliabilityHighThreshold
  		};
  
  		return Object.assign({}, allQuizDetailsSettings, settings);
  	}
  }
  customElements.define('d2l-insights-quiz-details-settings-list', QuizDetailsSettingsList);
  