import { Prop, toNative } from 'vue-facing-decorator';
import TsxComponent, { Component } from '../../app/vuetsx';
import { isNullOrEmpty } from '../../common/utils/is-null-or-empty';
import './css/progress-bar.css';

export enum ProgressBarTextPlacement {
	Above = 0,
	Below = 1,
	Rigth = 2,
	Left = 3,
}

interface ProgressBarArgs {
	maxCount: number;
	currentCount: number;
	customPercentages?: number[];
	fullWidth?: boolean;
	cssClass?: string;
	textPlacement?: ProgressBarTextPlacement;
	showSteps?: boolean;
	hideText?: boolean;
	renderText?: (h: any, currentCount: number, maxCount: number) => void;
	renderStep?: (h: any, index: number) => void;
	renderStepContent?: (h: any, index: number, currentPercentage: number) => void;
}

@Component
class ProgressBarComponent extends TsxComponent<ProgressBarArgs> implements ProgressBarArgs {
	@Prop() maxCount!: number;
	@Prop() currentCount!: number;
	@Prop() customPercentages!: number[];
	@Prop() fullWidth!: boolean;
	@Prop() cssClass: string;
	@Prop() textPlacement!: ProgressBarTextPlacement;
	@Prop() showSteps!: boolean;
	@Prop() hideText!: boolean;
	@Prop() renderText!: (h: any, currentCount: number, maxCount: number) => void;
	@Prop() renderStep!: (h: any, index: number) => void;
	@Prop() renderStepContent!: (h: any, index: number, currentPercentage: number) => void;

	getTextPlacementSuffix(): string {
		if (this.textPlacement == null || this.textPlacement == ProgressBarTextPlacement.Above) {
			return 'above';
		} else if (this.textPlacement == ProgressBarTextPlacement.Rigth) {
			return 'rigth';
		} else if (this.textPlacement == ProgressBarTextPlacement.Left) {
			return 'left';
		} else {
			return 'below';
		}
	}

	getStepPercentages(): number[] {
		const stepPercentages = [];
		const maxCount = this.maxCount || 0;

		for (let i = 1; i <= maxCount; i++) {
			stepPercentages.push((i * 100) / maxCount);
		}

		return stepPercentages;
	}

	getCurrentStepPercentage(): number {
		const currentCount = this.currentCount || 0;
		const maxCount = this.maxCount || 0;

		return (currentCount * 100) / maxCount;
	}

	getPercentageWrap() {
		return this.$refs.percentageWrap;
	}

	getMaxCount(): number {
		return !isNullOrEmpty(this.customPercentages) ? Math.max(...this.customPercentages) : (this.maxCount || 0);
	}

	getPercentage(): number {
		const currentCount = this.currentCount || 0;

		if (isNullOrEmpty(this.customPercentages)) {
			return Math.round((currentCount * 100) / this.getMaxCount());
		}

		if (currentCount >= this.customPercentages.length) {
			return 0;
		}

		return this.customPercentages[currentCount];
	}

	render(h) {
		const currentCount = this.currentCount || 0;
		const maxCount = this.getMaxCount();
		const percentage = this.getPercentage();
		const steps = this.getStepPercentages();

		return (
			<div ref="percentageWrap" class={`percentage-fm-wrap percentage-fm-text${this.getTextPlacementSuffix()}${!isNullOrEmpty(this.cssClass) ? ` ${this.cssClass}` : ''}`} style={(this.fullWidth != true ? '' : 'width:100%;')}>
				{!this.hideText && (this.renderText != null
					? this.renderText(
							h,
							currentCount,
							maxCount,
						)
					: (
							<div class="percentage-fm-text">
								{`${currentCount.toString()} / ${maxCount.toString()}`}
							</div>
						)
				)}

				<div class="percentage-fm-pbwrap">
					<div class="percentage-fm-pbinner" style={`width:${percentage}%`}></div>
				</div>

				{this.showSteps
				&& (
					<div class="percentage-fm-steps" style={this.hideText ? 'top: -13px' : 'top: -35px;'}>
						{steps.map((percentage, index) => (
							<div key={index} class="percentage-fm-step">
								<div class={`step-point ${(index < currentCount ? 'active' : '')}`}></div>
								{this.renderStep != null ? this.renderStep(h, index) : <div class="default-step"></div>}

								{this.renderStepContent != null
								&& (
									<div class="step-content-box">
										{this.renderStepContent(
											h,
											index,
											percentage,
										)}
									</div>
								)}
							</div>
						))}
					</div>
				)}
			</div>
		);
	}
}

const ProgressBar = toNative(ProgressBarComponent);
export default ProgressBar;
