import React, { useEffect, useState } from 'react'
import { IconContext } from 'react-icons'
import { FaRegStar, FaStar } from 'react-icons/fa6'
import { GetNumericValue, GetPercentage, IsFlagSet, SetFlag } from '../../../common/Helper';
import { TfiPencil, TfiTrash } from 'react-icons/tfi';
import ProgressBarWithText from './ProgressBarWithText';
import { ProgressBarTextOption } from '../Types';
import { atom, useAtom } from 'jotai';
import { UserInfo } from '../../../api/models/AccountTypes';

const expandedRatingAtom = atom<string | null>();

export interface IRateComponentProps{
	user: UserInfo | null | undefined,
	rateObjectId: string,
	ratePercentage?: number | null | undefined,
	// rates?: Array<number> | null | undefined,
	userRatePercentage?: number | null | undefined,
	progressBarTextShowOption?: ProgressBarTextOption,
	// isExpanded: boolean | undefined
	setRate: (value: number | null) => Promise<string | undefined>,
	deleteRate: () => Promise<string | undefined>,
	forceRefresh?: () => void | null | undefined,
}

export default function RatingComponent(props: IRateComponentProps) {
	const [ratePercentage, setRatePercentage] = useState<number | null>(null);
	const [userRatePercentage, setUserRatePercentage] = useState<number | null>(null);
	const [rateEditId, setRateEditId] = useAtom(expandedRatingAtom);
	const setRateEdit = (value: string | null) => {
		// console.log('value: ' + value)
		if (rateEditId != undefined && rateEditId == props.rateObjectId) setRateEditId(null);
		else setRateEditId(value);
	};
	
	const [rateHovered, setRateHovered] = useState<number | null>(null);
	const OnPointerLeaveOrEnter = (rate: number, entered: boolean) => {
		// console.log(`Entered: ${entered ? 'true' : 'false'}`)
		if (entered) setRateHovered(rate);
		else setRateHovered(null);
	};
	const valueMax = 10;
	// const [ratePercentSelected, setRatePercentSelected] = useState<number | null>(60);
	const OnSelectRate = (rate: number) => {
		const ratePercentage = GetPercentage(rate, valueMax);
		if (rate != null && props.ratePercentage != ratePercentage) {
			// await props.setRate(props.rateObjectId, ratePercentage);
			props.setRate(ratePercentage)
			.then(() => {
				setRateEditId(null);
				setRateHovered(null);
				if (props.forceRefresh != null) props.forceRefresh();
			});
		}
		else{
			// await props.deleteRate(props.rateObjectId);
			props.deleteRate()
			.then(() => {
				setRateEditId(null);
				setRateHovered(null);
				if (props.forceRefresh != null) props.forceRefresh();
			});
		}
	};

	useEffect(() => {
		// setRatePercentage(GetPercentage(props.ratePercentage, valueMax));
		setRatePercentage(props.ratePercentage ?? null);
		setUserRatePercentage(props.userRatePercentage ?? null);
	}, [props]);
	
	// const isEditing = false;
	// const isDeleting = false;
	return (
		// <div className='col d-flex flex-row w-100'>
		<div className="input-group">
			{(!IsEditing(props.rateObjectId, rateEditId) || props.user == null) &&
				<div className='col d-flex p-1 align-items-center bg-secondary rounded-start'>
					{
						// <ProgressBarWithText value={GetNumericValue(props.ratePercentage, valueMax)} valuePercentage={props.ratePercentage} textShowOption={props.progressBarTextShowOption ?? ProgressBarTextOption.None} valueMax={valueMax} />
						<ProgressBarWithText value={GetNumericValue(ratePercentage, valueMax)} valuePercentage={ratePercentage} textShowOption={props.progressBarTextShowOption ?? ProgressBarTextOption.None} valueMax={valueMax} />
						// <ProgressBarWithText value={GetNumericValue(10, valueMax)} valuePercentage={10}  textShowOption={ProgressBarTextOption.Fraction} valueMax={10} />
					}
				</div>
			}
			{(IsEditing(props.rateObjectId, rateEditId) && props.user != null) &&
				<div className='col d-flex flex-row p-2 bg-secondary'>
					{
						// RateEditElements(props.userRatePercentage, rateHovered, OnPointerLeaveOrEnter, OnSelectRate, 10)
						RateEditElements(userRatePercentage, rateHovered, OnPointerLeaveOrEnter, OnSelectRate, 10)
					}
				</div>
			}
			
			{/* <span className="input-group-text">{GetNumericValue(10, valueMax)} / {valueMax}</span> */}
			<span className={'input-group-text border border-top-0 border-bottom-0 bg-secondary' + (IsEditing(props.rateObjectId, rateEditId) ? ' user-select-none' : '')}
				onClick={() =>{
					if (!IsEditing(props.rateObjectId, rateEditId)) return;
					setRateEdit(null);
				}}
				>
				{GetNumericValue(ratePercentage, valueMax)}
			</span>
			

			{/* { ShowItem(props, inputValue, editGenreError == undefined ? null : editGenreError, SetEditGenreError) } */}
			{ ShowButton({
				rateObjectId: props.rateObjectId,
				rateEditId: rateEditId,
				userRate: userRatePercentage,
				valueMax: valueMax,
				setRateEdit: setRateEdit,
				deleteRate: props.deleteRate,
				forceRefresh: props.forceRefresh
			} as ButtonProps, props.user == null) }
		</div>
	)
}

type ButtonProps = {
	rateObjectId: string,
	rateEditId: string | undefined | null,
	userRate: number | undefined | null,
	valueMax: number,
	// isEditing: boolean,
	deleteRate: (value: string) => Promise<string | undefined>,	
	setRateEdit: (value: string | null) => void,
	forceRefresh?: () => void | null,
}

function ShowButton(props: ButtonProps, isUserNull: boolean){
	if (isUserNull){
		return (
			<div className='btn btn-secondary px-0'>&nbsp;</div>
		);
	}
	if (!IsEditing(props.rateObjectId, props.rateEditId)){
		return (
			<>

				{/* <button id={GetElementId('btn_switch_to_genre_edit_mode', props.genre.id)} type="button" className='btn btn-primary' disabled={!props.enabled} */}
				<button type="button" className='btn btn-primary'
					onClick={() => props.setRateEdit(props.rateObjectId)}
					>
						{GetNumericValue(props.userRate, props.valueMax) ?? '—//—'} <span><TfiPencil /></span>
				</button>
			</>
		);
	}
	else{
		return (
			<>
				{/* <button id={GetElementId('btn_edit_genre_submit', props.genre.id)} type="button" className='btn btn-danger' */}
				<button type="button" className={'btn btn-danger' + (props.userRate == undefined || props.userRate == null ? ' disabled' : '')}
					disabled={isUserNull} onClick={async() => props.deleteRate(props.rateObjectId)
										.then(() =>{
											props.setRateEdit(null);
											if (props.forceRefresh != null) props.forceRefresh();
										})
					 }>
						<span><TfiTrash /></span>
				</button>
			</>
		);
	}
}


function RateEditElements(userRatePercentage: number | undefined | null, rateHovered: number | null, onhover: (rate: number, entered: boolean) => void, onselect: (rate: number) => void, steps?: number | null) {
	const rateSequence = [...Array(steps ?? 10).keys()]
	return (
		React.Children.toArray(
			rateSequence.map((item) =>
				{
					const value = item + 1;
					return (
						<div className='flex-fill d-flex align-items-center'
							onMouseEnter={() => onhover(value, true)}
							onMouseLeave={() => onhover(value, false)}
							onClick={() => onselect(value)}
							>
							{
								RateEditElement(value, userRatePercentage != null ? userRatePercentage / 10 : null, rateHovered)
							}
							<br/>
							{/* <span>{value}</span> */}
						</div>
					);
				}
			)
		)
	)
}

function RateEditElement(elementValue: number, valueSelected: number | null, valueHovered: number | null) {
	const flag = GetElementFlag(elementValue, valueSelected, valueHovered);
	const icon = IsFlagSet(flag, RateElementFlag.IsSelected) || IsFlagSet(flag, RateElementFlag.IsHovered)
		? <FaStar />
		: <FaRegStar />;

	const opacity = IsFlagSet(flag, RateElementFlag.IsSelected)
		? 1
		: IsFlagSet(flag, RateElementFlag.IsHovered)
			? 0.5
			: 0.3;

	const color = IsFlagSet(flag, RateElementFlag.IsHovered) && IsFlagSet(flag, RateElementFlag.IsGraterThenSelected)
		? 'greenyellow'
		: !IsFlagSet(flag, RateElementFlag.IsHovered) && IsFlagSet(flag, RateElementFlag.IsLessThenSelected)
			? 'darkorange'
			: 'gold';
	return (
			<IconContext.Provider value={{ color: color, className: 'w-100 h-100', style: { opacity: opacity, verticalAlign: 'middle' } }}>
				{ icon }
			</IconContext.Provider>
	)
}

// function IsRateDefined(percentage: number | null | undefined){
// 	return percentage != undefined && percentage != null && percentage > 0;
// }

function IsEditing(rateObjectId: string | undefined | null, rateEditId: string | undefined | null){
	return rateObjectId != undefined && rateObjectId == rateEditId;
}


function GetElementFlag(elementValue: number, valueSelected: number | null, valueHovered: number | null): RateElementFlag{
	let type = RateElementFlag.None;
	if (valueHovered != null && elementValue <= valueHovered) type = SetFlag(type, RateElementFlag.IsHovered);

	if (valueSelected != null && elementValue <= valueSelected) type = SetFlag(type, RateElementFlag.IsSelected);

	if (valueSelected != null && valueHovered != null){
		if (valueHovered > valueSelected && elementValue > valueSelected && elementValue <= valueHovered){
			type = SetFlag(type, RateElementFlag.IsGraterThenSelected);
		}
		else if (valueHovered < valueSelected && elementValue <= valueSelected && elementValue > valueHovered){
			type = SetFlag(type, RateElementFlag.IsLessThenSelected);
		}
	}

	return type;
}

enum RateElementFlag{
	None = 0,
	IsSelected = 1,
	IsHovered = 2,
	IsGraterThenSelected = 4,
	IsLessThenSelected = 8,
}