import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { useDropzone } from 'react-dropzone';
import { Felt } from './Felt';
import { ledetekst } from '../diverse/Ledetekst';
import { Spinner } from '../pynt/Spinner';
import { leseligFilStorrelse } from './Gyldighet';
import { Lenke } from '../pynt/Lenke';
import { Feilboks } from '../pynt/Feilboks';

function visFilnavn(filnavn) {
	try {
		return decodeURIComponent(filnavn);
	} catch (error) {
		return filnavn;
	}
}

export const OpplastedeFiler = (props) => {
	const {
		filer,
		vedSletting,
		lasteNedUrl,
		maksStorrelse,
		kapasitetBrukt,
		visningsprefiks,
	} = props;

	if (filer.length === 0 && !kapasitetBrukt) {
		return null;
	}

	const bruktStorrelse = kapasitetBrukt || totalStorrelse(filer);

	return (
		<>
			<ul className="valgte-filer">
				{filer.map(({ id, filnavn, storrelse }, i) => {
					return (
						<li key={id}>
							<div>
								<span
									title={visFilnavn(filnavn)}
									className="filnavn"
									data-hj-suppress
								>
									{visningsprefiks &&
										`${visningsprefiks} ${i + 1}: `}
									{visFilnavn(filnavn)}
								</span>
								<span className="filstorrelse">
									{leseligFilStorrelse(storrelse)}
								</span>
								<Lenke
									handling={() => vedSletting(id)}
									className="slett"
								>
									{ledetekst.getTekst(
										'arbeidsvarsling.frontendkomponenter.Fil.slett'
									)}
								</Lenke>
							</div>
						</li>
					);
				})}
			</ul>
			{maksStorrelse && (
				<FilStorrelseViser
					bruktStorrelse={bruktStorrelse}
					maksStorrelse={maksStorrelse}
				/>
			)}
		</>
	);
};

export const FilStorrelseViser = (props) => {
	const { maksStorrelse, bruktStorrelse } = props;
	const proporsjonBrukt = (bruktStorrelse / maksStorrelse) * 100;

	return (
		<div className={'filfelt-brukt'}>
			<progress
				style={{ display: 'none' }}
				max={100}
				value={proporsjonBrukt}
			/>
			<div className={'filfelt-progress-ytre'}>
				<div
					className={'filfelt-progress-indre'}
					style={{ width: `${proporsjonBrukt}%` }}
				/>
			</div>
			<div className={'filfelt-brukt-tekst'}>
				<span>
					{ledetekst.getTekst(
						'arbeidsvarsling.frontendkomponenter.Filopplastingsfelt.brukthittil',
						leseligFilStorrelse(bruktStorrelse)
					)}
				</span>
				<span>
					{ledetekst.getTekst(
						'arbeidsvarsling.frontendkomponenter.Filopplastingsfelt.bruktmaks',
						leseligFilStorrelse(maksStorrelse)
					)}
				</span>
			</div>
		</div>
	);
};

export const totalStorrelse = (filer) =>
	filer.reduce((storrelse, fil) => fil.storrelse + storrelse, 0);

export const OpplastningsFelt = (props) => {
	const {
		aksepterteTyper,
		vedOpplasting,
		knappTekst,
		registrerFeil,
		kapasitetBrukt,
		maksStorrelse,
	} = props;
	const onDrop = useCallback(
		(acceptedFiles, rejectedFiles) => {
			if (rejectedFiles) {
				const feileFiler = rejectedFiles
					.map((file) => file.name)
					.join(', ');
				registrerFeil(
					ledetekst.getTekst(
						'arbeidsvarsling.frontendkomponenter.Filopplastingsfelt.ugyldig',
						feileFiler,
						aksepterteTyper
					)
				);
			}
			const tommeFiler = acceptedFiles
				.filter((fil) => fil.size === 0)
				.map((fil) => fil.name)
				.join(', ');
			if (tommeFiler.length > 0) {
				registrerFeil(
					ledetekst.getTekst(
						'arbeidsvarsling.frontendkomponenter.Filopplastingsfelt.tommeFiler',
						tommeFiler
					)
				);
			} else if (acceptedFiles.length > 0) {
				const nyFil = acceptedFiles[0];
				if (nyFil.size + kapasitetBrukt > maksStorrelse) {
					registrerFeil(
						ledetekst.getTekst(
							'arbeidsvarsling.frontendkomponenter.Filopplastingsfelt.forStor',
							nyFil.name,
							leseligFilStorrelse(nyFil.size),
							leseligFilStorrelse(
								maksStorrelse - kapasitetBrukt,
								true
							)
						) // vi runder ned den gjenværende kapasiteten
					);
				} else {
					vedOpplasting(nyFil);
				}
			}
		},
		[vedOpplasting, kapasitetBrukt, maksStorrelse]
	);

	const { getRootProps, getInputProps } = useDropzone({
		accept: aksepterteTyper,
		onDrop,
	});

	return (
		<div
			style={{ display: 'inline-block' }}
			{...getRootProps({ className: 'bottom-spacing-mini' })}
		>
			<input {...getInputProps()} />
			<button className="knapp knapp-liten knapp-handling">
				{knappTekst}
			</button>
		</div>
	);
};

class Filopplastingsfelt extends Felt {
	constructor(props) {
		super(props);
		this.state = {
			laster: false,
			feil: undefined,
		};

		this._registrer({
			antallFiler: props.opplastedeFiler.length,
			totalStorrelse: totalStorrelse(props.opplastedeFiler),
		});
		this.onUpload = this.onUpload.bind(this);
		this.onDelete = this.onDelete.bind(this);
		this.vedFeil = this.vedFeil.bind(this);
	}

	componentDidUpdate(prevProps) {
		if (this.props.opplastedeFiler !== prevProps.opplastedeFiler) {
			this.setState({
				laster: false,
				feil: undefined,
			});
			this._registrer({
				antallFiler: this.props.opplastedeFiler.length,
				totalStorrelse: totalStorrelse(this.props.opplastedeFiler),
			});
		}
	}

	onUpload(file) {
		this.setState({
			laster: true,
			feil: undefined,
		});
		const formData = new FormData();
		// setter filnavn eksplisitt for ie og edge, for å ikke ta med filstien
		formData.append('file', file, file.name);
		this.props.vedOpplasting(formData);
	}

	onDelete(id) {
		this.setState({
			laster: true,
			feil: undefined,
		});
		this.props.vedSletting(id);
	}

	vedFeil(feilmelding) {
		this.setState({
			laster: false,
			feil: feilmelding,
		});
	}

	render() {
		const {
			opplastedeFiler,
			maksFiler,
			aksepterteTyper,
			vedSletting,
			tekster,
			maksStorrelse,
			lasteNedUrl,
			ValgteFilerTag,
			visningsprefiks,
		} = this.props;
		const { feil, laster } = this.state;
		const kapasitetBrukt =
			+this.props.kapasitetBrukt + totalStorrelse(opplastedeFiler);
		const FilerTittelTag = ValgteFilerTag || 'h4';

		const feilmelding = feil && <Feilboks>{feil}</Feilboks>;

		return (
			<div className="skjemagruppe filopplastingsfelt">
				{this._renderObligatorisk()}
				{((opplastedeFiler && opplastedeFiler.length > 0) ||
					!!kapasitetBrukt) && (
					<>
						{opplastedeFiler && opplastedeFiler.length > 0 && (
							<FilerTittelTag className="valgte-filer-tittel">
								{tekster.tittel}
							</FilerTittelTag>
						)}
						<OpplastedeFiler
							filer={opplastedeFiler}
							kapasitetBrukt={kapasitetBrukt}
							vedSletting={vedSletting}
							maksStorrelse={maksStorrelse}
							lasteNedUrl={lasteNedUrl}
							visningsprefiks={visningsprefiks}
						/>
					</>
				)}
				{maksFiler > opplastedeFiler.length && (
					<OpplastningsFelt
						aksepterteTyper={aksepterteTyper}
						kapasitetBrukt={kapasitetBrukt}
						maksStorrelse={maksStorrelse}
						vedOpplasting={this.onUpload}
						knappTekst={tekster.knapp}
						registrerFeil={this.vedFeil}
					/>
				)}
				{feilmelding}
				{this._renderIrettesettelse()}
				<Spinner
					aktivert={laster}
					tekst={ledetekst.getTekst(
						'arbeidsvarsling.frontendkomponenter.Filopplastingsfelt.laster'
					)}
				/>
			</div>
		);
	}
}

Filopplastingsfelt.defaultProps = {
	kapasitetBrukt: 0,
};

Filopplastingsfelt.propTypes = {
	opplastedeFiler: PropTypes.arrayOf(
		PropTypes.shape({
			id: PropTypes.string.isRequired,
			filnavn: PropTypes.string.isRequired,
			mimetype: PropTypes.string.isRequired,
			storrelse: PropTypes.number.isRequired,
		})
	).isRequired,
	maksFiler: PropTypes.number,
	maksStorrelse: PropTypes.number,
	kapasitetBrukt: PropTypes.number,
	lasteNedUrl: PropTypes.func,
	aksepterteTyper: PropTypes.string.isRequired,
	vedSletting: PropTypes.func.isRequired,
	ValgteFilerTag: PropTypes.string,
	vedOpplasting: PropTypes.func.isRequired,
	tekster: PropTypes.shape({
		tittel: PropTypes.string.isRequired,
		knapp: PropTypes.string.isRequired,
	}).isRequired,
	visningsprefiks: PropTypes.string,
};

export { Filopplastingsfelt };
