import React, { ChangeEvent, useState } from 'react'
import { TfiPlus } from 'react-icons/tfi';
import { Description, Language } from '../../../../api/models/Types';
import {  useQuery } from 'react-query';
import ErrorField from '../../../common/error/ErrorField';
import ErrorInput from '../../../common/error/ErrorInput';
import { languageQueryKey } from '../../../library/edit/language/LanguageListEditComponent';
import { GetLanguageList } from '../../../../api/LanguageApi';
import { DeepEqual } from '../../../../common/Helper';
import DescriptionItemEditComponent, { IsDescriptionValid, IsLanguageValid } from './DescriptionItemEditComponent';

export interface IDescriptionsEditComponentProps{
	descriptions: Array<Description> | null | undefined,
	dataLoadingError: Error | null,
	createDescription: (description: Description) => Promise<string | undefined>,
	editDescription: (description: Description, newValue: string | null, newLanguage: Language | null) => Promise<string | undefined>,
	deleteDescription: (description: Description) => Promise<string | undefined>,
	forceRefresh: () => void,
}

export default function DescriptionsEditComponent(props: IDescriptionsEditComponentProps) {
	const { data: languagesData, isLoading: languagesIsLoading, isError: languagesIsError, error: languagesError } = useQuery(languageQueryKey, GetLanguageList);

	const [createNewDescriptionError, setCreateNewDescriptionError] = useState<string | null>(null);

	const [descriptions, setDescription] = useState<Array<Description>>([]);
	const [originalDescriptionSelected, setOriginalDescriptionSelected] = useState<boolean>(true);
	const [descriptionLanguageIdValue, selectDescriptionLanguageIdValue] = useState<[languageId: string | null, description: string | null]>();

	const selectLanguage = (id?: string | null) => {
		selectDescriptionLanguageIdValue(
			[
				(id == descriptionLanguageIdValue?.[0] ? null : id) ?? null,
				descriptionLanguageIdValue?.[1] ?? null,
			]
		);
	};

	const onDescriptionChange = (event : ChangeEvent<HTMLTextAreaElement>) => {
		selectDescriptionLanguageIdValue(
			[
				descriptionLanguageIdValue?.[0] ?? null,
				event.target.value ?? null,
			]
		);
	}

	const [editingDescription, SetEditingDescription] = useState<Description | null>(null);
	const SetEditing = (description: Description, value: boolean) => {
		if (DeepEqual(description, editingDescription) || !value){
			SetEditingDescription(null);
		}
		else{
			SetEditingDescription(description);
		}
	};

	const [deletingDescription, SetDeletingDescription] = useState<Description | null>(null);
	const SetDeleting = (description: Description, value: boolean) => {
		if (DeepEqual(description, deletingDescription) || !value){
			SetDeletingDescription(null);
		}
		else{
			SetDeletingDescription(description);
		}
	};

	React.useEffect(() => {
			selectDescriptionLanguageIdValue( [ null, null, ] );
			setDescription( props.descriptions ?? [] );
		}, [props]);
	
	return (
		<div className='card bg-body-tertiary p-0'>
			<div className='card-header'>
				<ul className="nav nav-underline">
					{
						React.Children.toArray(
							[
								{ isOriginal:true, name: 'Оригинальное описание' },
								{ isOriginal:false, name: 'Другие описания' },
							].map((tab) => 
								<li className='user-select-none nav-item' >
									<a className={'nav-link' + (tab.isOriginal == originalDescriptionSelected ? ' active' : '')} onClick={() => setOriginalDescriptionSelected(tab.isOriginal)}>{tab.name}</a>
								</li>
							)
						)
					}
                </ul>
			</div>
			<div className='card-body'>
				{(!isTypeSingle(originalDescriptionSelected) || (isTypeSingle(originalDescriptionSelected) && !containsItems(descriptions, originalDescriptionSelected))) &&
					<ErrorField error={createNewDescriptionError}>
						<div className='row'>
							<div className='col-9 overflow-x-hidden overflow-y-auto' style={{height:'10rem'}}>
								<ErrorInput error={createNewDescriptionError}>
									{/* <textarea type="text" className="form-control" id="newAnimeTitleName" placeholder="Название" onChange={onNameChange} value={nameLanguageIdValue?.[1] ?? ''} ></textarea> */}
									<textarea className="form-control rounded-end-0" placeholder="Описание" style={{minHeight:'10rem'}} onChange={onDescriptionChange} value={descriptionLanguageIdValue?.[1] ?? ''} ></textarea>
									{/* <input type="text" className="form-control" id="newAnimeTitleName" placeholder="Название" onChange={onNameChange} value={nameLanguageIdValue?.[1] ?? ''} /> */}
									
								</ErrorInput>
							</div>
							<div className='col'>
								<ErrorInput error={createNewDescriptionError}>
									<div className="input-group">
										<ErrorInput error={createNewDescriptionError ?? (languagesError as Error | null)?.message}>
											<select className="form-select" aria-label="Язык описания" value={descriptionLanguageIdValue?.[0] ?? ''}
												disabled={languagesError != null || languagesData == null|| languagesData?.length == 0} onChange={(event) => selectLanguage(event.target.value)}>
												<option value={''} >Выберите язык описания</option>
												{!(languagesIsError || languagesIsLoading) && languagesData &&
													React.Children.toArray(
														languagesData.map((item) => 
															<option value={item.id}>
																{item.name} [{item.codeIso3}]
															</option>
														))
												}
												{/* <option value="2">Два</option> */}
											</select>
										</ErrorInput>

										<ErrorInput error={createNewDescriptionError} errorClassses={'btn-danger'}>
											{/* <button id='btn_add_name' type="submit" className='btn btn-primary' */}
											<button type="submit" className='btn btn-primary'
												disabled={!IsLanguageValid(descriptionLanguageIdValue?.[0]) || !IsDescriptionValid(descriptionLanguageIdValue?.[1])}
												onClick={() => {
													if (IsLanguageValid(descriptionLanguageIdValue?.[0]) && IsDescriptionValid(descriptionLanguageIdValue?.[1])){
														props.createDescription({
															language: languagesData?.find(q => q.id == descriptionLanguageIdValue![0]),
															value: descriptionLanguageIdValue![1],
															isOriginal: originalDescriptionSelected
														} as Description)
															.then(() => {
																setCreateNewDescriptionError(null);
																selectDescriptionLanguageIdValue([ null, null ]);
																props.forceRefresh();
															})
															.catch((error: unknown) =>{
																setCreateNewDescriptionError((error as Error)?.message);
																//console.error(error);
															});
													}
												}}>
													<span><TfiPlus /></span>
											</button>
										</ErrorInput>
									</div>
								</ErrorInput>
							</div>
						</div>
					</ErrorField>
				}

				{!isTypeSingle(originalDescriptionSelected) &&
					<hr />
				}

				{(!isTypeSingle(originalDescriptionSelected) || (isTypeSingle(originalDescriptionSelected) && containsItems(descriptions, originalDescriptionSelected))) &&
					<>
						<ul className="list-group gap-2">
							{
								ShowItems(
									{
										descriptions: descriptions?.filter(q => q.isOriginal == originalDescriptionSelected) ?? [],
										languages: languagesData ?? [],
										isLoading: languagesIsLoading,
										isError: props.dataLoadingError != null,
										error: props.dataLoadingError,
										setDeleting: SetDeleting,
										isDeleting: (description: Description | null) => DeepEqual(deletingDescription, description),
										deleteDescription: props.deleteDescription,
										setEditing: SetEditing,
										isEdited: (description: Description | null) => DeepEqual(editingDescription, description),
										editDescription: props.editDescription,
										forceRefresh: props.forceRefresh
									}, languagesData) 
							}
						</ul>
					</>
				}

			</div>
		</div>
	)
}

type ShowGenresProps = {
	descriptions: Array<Description>,
	languages: Array<Language>,
	isLoading: boolean,
	isError: boolean,
	error: Error | null,
	setDeleting: (description: Description, value: boolean) => void,
	isDeleting: (description: Description | null) => boolean,
	deleteDescription: (description: Description) => Promise<string | undefined>,

	setEditing: (description: Description, value: boolean) => void,
	isEdited: (description: Description | null) => boolean,
	editDescription: (description: Description, newValue: string | null, newLanguage: Language | null) => Promise<string | undefined>,
	forceRefresh: () => void,
}

function ShowItems(props: ShowGenresProps, languages: Array<Language> | undefined){
	if (props.isLoading){
		return (
			<>
				<div className="list-group-item placeholder rounded">1. SomeDescription</div>
				<div className="list-group-item placeholder rounded">2. SomeDescription</div>
				<div className="list-group-item placeholder rounded">3. SomeDescription</div>
			</>
		)
	}
	else if (props.isError){
		return (
			<li className="list-group-item card p-0">
				<div className='card-header bg-danger'>
					<h4 className='card-heading'>{props.error?.name ?? 'Unknown error'}</h4>
				</div>
				<div className='card-body bg-danger bg-opacity-50'>
					{/* Error occured during fetching items: */}
					<span>{props.error?.message ?? 'unknown'}</span>
				</div>
			</li>
		)
	}
	else{
		return React.Children.toArray(
			props.descriptions.map((description: Description) => {
				return (
					<DescriptionItemEditComponent
						description={description}
						languages={languages ?? []}
						// enabled={!item.deleted}
						enabled={true}
						setDeleting={props.setDeleting}
						isDeleting={props.isDeleting(description)}
						deleteDescription={props.deleteDescription}
						
						setEditing={props.setEditing}
						isEditing={props.isEdited(description)}
						editDescription={props.editDescription}
						forceRefresh={props.forceRefresh}
						/>
					
				);
			})
		)
	}
}

function isTypeSingle(isOriginal: boolean){
	return isOriginal;
}

function containsItems(names: Array<Description>, isOriginal: boolean){
	return names.filter(q => q.isOriginal == isOriginal).length > 0;
}