import type WizardTab from './wizard-tab';
import { Prop, toNative } from 'vue-facing-decorator';
import PowerduckState from '../../app/powerduck-state';
import TsxComponent, { Component } from '../../app/vuetsx';
import { slotUnwrapper } from '../../common/slot-unwrapper';
import Button from '../button/button';
import { ButtonLayout } from '../button/button-layout';
import LaddaButton from '../button/ladda-button';
import './css/wizard.css';

interface WizardArgs {
	fullSizeOnMobile?: boolean;
	tabListCssClass?: string;
	cssClass?: string;
	activePageChanged?: (tabId: string) => void;
	validate?: (tabId: string) => Promise<boolean>;
	submitClicked?: () => Promise<any>;
	headerButtonCustomRender?: (h, tab: typeof WizardTab.prototype, index: number) => void;
	submitText?: string;
	customButtons?: (h, tabId: string) => any;
	includeHeaderButtonIndex?: boolean;
}

@Component
class WizardComponentComponent extends TsxComponent<WizardArgs> implements WizardArgs {
	@Prop() submitClicked: () => Promise<any>;
	@Prop() tabListCssClass?: string;
	@Prop() cssClass?: string;
	@Prop() validate: (tabId: string) => Promise<boolean>;
	@Prop() activePageChanged?: (tabId: string) => void;
	@Prop() customButtons: (h, tabId: string) => any;
	@Prop() headerButtonCustomRender?: (h, tab: typeof WizardTab.prototype, index: number) => void;
	@Prop() fullSizeOnMobile: boolean;
	@Prop() submitText!: string;
	@Prop() includeHeaderButtonIndex: boolean;
	activePageIndex: number = 0;

	private getChildTabs(): typeof WizardTab.prototype[] {
		return (this.getSlotProperties('WizardTab') as typeof WizardTab.prototype[]).filter(p => p.visible != false);
	}

	public setActivePageIndex(index: number): void {
		this.activePageIndex = index;
	}

	public getActivePageIndex(): number {
		return this.activePageIndex;
	}

	public nextPage(): void {
		if (this.validate != null) {
			const activeTab = this.getChildTabs()[this.getActivePageIndex()];
			this.validate(activeTab.id).then((valid) => {
				if (valid) {
					this.performNextPage();
				}
			});
		} else {
			this.performNextPage();
		}
	}

	private performNextPage(): void {
		this.activePageIndex += 1;
		if (this.activePageIndex >= this.getChildTabs().length) {
			this.activePageIndex = this.getChildTabs().length - 1;
		}

		if (this.activePageChanged != null) {
			this.activePageChanged(this.getChildTabs()[this.activePageIndex].id);
		}
	}

	private previousPage(): void {
		this.activePageIndex -= 1;
		if (this.activePageIndex < 0) {
			this.activePageIndex = 0;
		}

		if (this.activePageChanged != null) {
			this.activePageChanged(this.getChildTabs()[this.activePageIndex].id);
		}
	}

	private handleHeaderClicked(newIndex: number): void {
		if (this.activePageIndex > newIndex) {
			this.activePageIndex = newIndex;

			if (this.activePageChanged != null) {
				this.activePageChanged(this.getChildTabs()[this.activePageIndex].id);
			}
		}
	}

	private render(h) {
		const childTabs = this.getChildTabs();
		const activeIndex = this.getActivePageIndex();
		const activeTab: typeof WizardTab.prototype = childTabs[activeIndex] || ({} as any);
		const widthPct = 100 / childTabs.length;
		const lineWidth = 100 - widthPct + 1;
		const btnRender = (this.customButtons != null ? this.customButtons(h, activeTab.id) : null);
		const renderCustomHeaderButton = this.headerButtonCustomRender != null;

		return (
			<div class={`wizard${this.fullSizeOnMobile == true ? ' wizard-fullsize-mob' : ''}${this.cssClass ? ` ${this.cssClass}` : ''} wizard-activetab-${activeTab.id}`}>
				<div class="wizard-outer">
					<div class="wizard-inner">
						<div class="wz-connecting-line" style={`width:${lineWidth}%;`}></div>
						<ul class={`nav nav-tabs${this.tabListCssClass != null ? ` ${this.tabListCssClass}` : ''}`} role="tablist">
							{childTabs.map((tab, i) => (
								<li role="presentation" class={activeIndex == i ? 'active' : 'disabled'} style={`width:${widthPct}%;`}>
									<a
										href="javascript:"
										data-toggle="tab"
										role="tab"
										onClick={(e) => {
											this.handleHeaderClicked(i);
										}}
									>
										{renderCustomHeaderButton && this.headerButtonCustomRender(
											h,
											tab,
											i,
										)}

										{!renderCustomHeaderButton && this.includeHeaderButtonIndex
										&& (
											<span class="round-tab">
												<i class="step">
													{i + 1}
												</i>
											</span>
										)}

										{!renderCustomHeaderButton
										&& (
											<span class="text">
												{tab.title}
											</span>
										)}
									</a>
								</li>
							))}
						</ul>
					</div>
				</div>

				<div role="form">
					<div class="tab-content">
						<div class="tab-pane active" role="tabpanel">
							<h4 class="wizard-title">{activeTab.title}</h4>
							{activeTab.subtitle
							&& <p class="wizard-subtitle">{activeTab.subtitle}</p>}

							{slotUnwrapper(this.$slots.default?.())[activeIndex]}
						</div>

						<div class="wizard-buttons">
							{activeIndex > 0 && (
								<Button
									text={PowerduckState.getResourceValue('back')}
									layout={ButtonLayout.Default}
									icon="icon icon-arrow-left-circle"
									cssClass="wizard-btn-back"
									clicked={() => {
										this.previousPage();
									}}
								/>
							)}
							{activeIndex < childTabs.length - 1 && (
								<Button
									text={PowerduckState.getResourceValue('continueLabel')}
									layout={ButtonLayout.Primary}
									icon="icon icon-arrow-right-circle"
									cssClass="wizard-btn-forward"
									iconOnRight={true}
									clicked={() => {
										this.nextPage();
									}}
								/>
							)}
							{activeIndex == childTabs.length - 1 && (
								<LaddaButton
									text={this.submitText || PowerduckState.getResourceValue('submit')}
									layout={ButtonLayout.Primary}
									icon="icon icon-check"
									cssClass="wizard-btn-submit"
									iconOnRight={true}
									clicked={async () => {
										await this.submitClicked();
									}}
								/>
							)}

							{btnRender}
						</div>
					</div>
				</div>
			</div>
		);
	}
}

const WizardComponent = toNative(WizardComponentComponent);
export default WizardComponent;
