import type { VNode } from 'vue';
import type { Language } from '../../common/enums/language';
import type { ILocalizedText } from '../../common/localized-text';
import type { DropdownButtonItemArgs } from '../dropdown-button/dropdown-button-item';
import type { FormItemWrapperArgs, HintType, MarginType } from '../form/form-item-wrapper';
import type { TranslateGetRequest, TranslateGetResponse } from './translate';
import { Prop, toNative } from 'vue-facing-decorator';
import PowerduckState from '../../app/powerduck-state';
import TsxComponent, { Component } from '../../app/vuetsx';
import { LanguageUtils } from '../../common/utils/language-utils';
import FormItemWrapper from '../form/form-item-wrapper';
import { TabPage } from '../tabs/tab-page';
import Tabs, { TabsRenderMode } from '../tabs/tabs';
import TextArea from './textarea';
import Translate from './translate';

interface LocalizedStringInputArgs extends FormItemWrapperArgs {
	value: ILocalizedText;
	changed: (e: ILocalizedText) => void;
	supportedLanguages?: Language[];
	placeholder?: string;
	translatable?: boolean;
	translateApiMethod?: <RQ extends TranslateGetRequest, RS extends TranslateGetResponse>(data?: RQ) => Promise<RS>;
}

@Component
class LocalizedStringTextareaComponent extends TsxComponent<LocalizedStringInputArgs> implements LocalizedStringInputArgs {
	@Prop() label!: string | VNode;
	@Prop() labelButtons!: DropdownButtonItemArgs[];
	@Prop() subtitle!: string;
	@Prop() value!: ILocalizedText;
	@Prop() changed: (e: ILocalizedText) => void;
	@Prop() supportedLanguages?: Language[];
	@Prop() marginType?: MarginType;
	@Prop() maxWidth?: number;
	@Prop() placeholder!: string;
	@Prop() mandatory!: boolean;
	@Prop() wrap!: boolean;
	@Prop() showClearValueButton!: boolean;
	@Prop() hint: string;
	@Prop() hintType!: HintType;
	@Prop() appendIcon: string;
	@Prop() prependIcon: string;
	@Prop({ default: false }) translatable: boolean;
	@Prop() translateApiMethod: <RQ extends TranslateGetRequest, RS extends TranslateGetResponse>(data?: RQ) => Promise<RS>;
	@Prop() appendClicked: () => void;
	@Prop() prependClicked: () => void;
	currentValue: ILocalizedText = null;

	raiseChangeEvent(newValue: ILocalizedText): void {
		this.populateValidationDeclaration();

		if (this.changed != null) {
			if (newValue != null) {
				newValue = JSON.parse(JSON.stringify(newValue));
			}

			this.changed(newValue);
		}
	}

	changeValue(lang: Language, newValue: string): void {
		const value = this.value || ({} as ILocalizedText);
		value[lang] = newValue;
		this.raiseChangeEvent(value);
	}

	getActualValue(lang: Language, value: ILocalizedText): string {
		if (value == null) {
			return null;
		}

		return value[lang];
	}

	render(h) {
		const langArr = this.supportedLanguages == null ? LanguageUtils.getLanguageList() : LanguageUtils.getLanguageList().filter(p => this.supportedLanguages.includes(p.id));
		let initialTabIndex = langArr.map(p => p.id).indexOf(PowerduckState.getCurrentLanguage());
		if (initialTabIndex == null || initialTabIndex < 1) {
			initialTabIndex = 0;
		}

		return (
			<FormItemWrapper
				cssClass={`localized-string-input localized-input ${this.value != null ? 'hasval' : 'empty'}`}
				label={this.label}
				mandatory={this.mandatory}
				wrap={this.wrap}
				appendIcon={this.appendIcon}
				prependIcon={this.prependIcon}
				hint={this.hint}
				hintType={this.hintType}
				appendClicked={this.appendClicked}
				prependClicked={this.prependClicked}
				marginType={this.marginType}
				maxWidth={this.maxWidth}
				validationState={this.validationState}
				labelButtons={this.labelButtons}
				subtitle={this.subtitle}
				showClearValueButton={this.showClearValueButton}
			>
				<Tabs renderMode={TabsRenderMode.Normal} initialTabIndex={initialTabIndex}>
					{langArr.map(lang => (
						<TabPage
							navCaption={`<img src="${LanguageUtils.getLanguageFlagUrl(lang.flag)}"/>&nbsp;${lang.id.toUpperCase()}`}
							escapeCaption={false}
							key={lang.id}
							icon={null}
						>
							<TextArea
								key={lang.id}
								wrap={false}
								label={null}
								value={this.getActualValue(lang.id, this.value)}
								changed={(e) => {
									this.changeValue(lang.id, e);
								}}
								rows={4}
							/>
							{this.translatable !== false && (
								<Translate
									value={this.value}
									currentLangId={lang.id}
									langArr={langArr}
									changeValue={this.changeValue.bind(this)}
									getActualValue={(langId, value) => this.getActualValue(langId, value as ILocalizedText)}
									apiMethod={this.translateApiMethod}
								/>
							)}
						</TabPage>
					))}
				</Tabs>
			</FormItemWrapper>
		);
	}
}

const LocalizedStringTextarea = toNative(LocalizedStringTextareaComponent);
export default LocalizedStringTextarea;
