import React from 'react';
import { garanterListe, garanterObjekt, ledetekst } from '..';

export const ARBEIDSTIDER = ['INNENFOR_ARBEIDSTID', 'UTENFOR_ARBEIDSTID'];

export function navngiTiltak(plantype, kategori, alternativ, arbeidstid) {
	const navn = ledetekst.getTekst(
		`arbeidsvarsling.soknad.Vegarbeidbeskrivelse.tiltak.${
			plantype.name ?? plantype
		}.${kategori}.${alternativ.felt}`
	);
	const tid = arbeidstid
		? ` - ${ledetekst.getTekst(
				`arbeidsvarsling.frontendkomponenter.Arbeidstid.${arbeidstid}`
		  )}`
		: '';
	return `${navn}${tid}`;
}

export function getRelevanteTiltak(plantype, vegarbeidsbeskrivelse) {
	switch (plantype?.name ?? plantype) {
		case 'GENERELL':
			return [
				getValgteTiltak(
					vegarbeidsbeskrivelse
						? vegarbeidsbeskrivelse.getGenerelleTiltak
							? vegarbeidsbeskrivelse.getGenerelleTiltak()
							: vegarbeidsbeskrivelse.generelleTiltak
						: {}
				),
				(tiltak) =>
					vegarbeidsbeskrivelse
						? vegarbeidsbeskrivelse.setGenerelleTiltak
							? vegarbeidsbeskrivelse.setGenerelleTiltak(tiltak)
							: undefined
						: undefined,
			];
		case 'SPESIELL':
			return [
				getValgteTiltak(
					vegarbeidsbeskrivelse
						? vegarbeidsbeskrivelse.getSpesielleTiltak
							? vegarbeidsbeskrivelse.getSpesielleTiltak()
							: vegarbeidsbeskrivelse.spesielleTiltak
						: {}
				),
				(tiltak) =>
					vegarbeidsbeskrivelse
						? vegarbeidsbeskrivelse.setSpesielleTiltak
							? vegarbeidsbeskrivelse.setSpesielleTiltak(tiltak)
							: undefined
						: undefined,
			];
		default:
			return [{}, () => undefined];
	}
}

function getValgteTiltak(alleTiltak) {
	const valgteTiltak = {};
	Object.keys(garanterObjekt(alleTiltak)).forEach((kategori) => {
		const tiltak = alleTiltak[kategori];
		if (!tiltak.valgt) {
			return;
		}
		const valgtTiltak = { ...tiltak, alternativer: [] };
		garanterListe(tiltak.alternativer).forEach((alternativ) => {
			if (!alternativ.valgt) {
				return;
			}
			valgtTiltak.alternativer.push(alternativ);
		});
		if (valgtTiltak.alternativer.length > 0) {
			valgteTiltak[kategori] = valgtTiltak;
		}
	});
	return valgteTiltak;
}

export function utledTiltaksskissefeilmelding(opplastedeSkisser, vegarbeid) {
	const plantype = vegarbeid.getPlantype
		? vegarbeid.getPlantype()
		: vegarbeid.plantype;

	const [relevanteTiltak] = getRelevanteTiltak(
		plantype,
		vegarbeid.getVegarbeidsbeskrivelse
			? vegarbeid.getVegarbeidsbeskrivelse()
			: vegarbeid.vegarbeidsbeskrivelse
	);

	const skisserMedFlereArbeidstider = getSkisserMedFlereArbeidstider(
		opplastedeSkisser,
		relevanteTiltak
	);

	if (skisserMedFlereArbeidstider.length > 0) {
		return (
			<div className="blokk">
				<p>
					{ledetekst.getTekst(
						'arbeidsvarsling.frontendkomponenter.tiltaksskisse.flerearbeidstider'
					)}
				</p>
				<ul>
					{skisserMedFlereArbeidstider.map((skisse, i) => (
						<li key={i}>{skisse.filnavn}</li>
					))}
				</ul>
			</div>
		);
	}
	const tiltakUtenSkisser = getTiltakUtenSkisser(
		opplastedeSkisser,
		relevanteTiltak
	);

	function tiltakSomIkkeErKobletTilSkisse(tiltakUtenSkisser, arbeidstid) {
		const tiltakUtenSkisserForArbeidsEksisterer = Object.keys(
			tiltakUtenSkisser
		).some((kategori) => {
			const tiltak = tiltakUtenSkisser[kategori];
			return (
				tiltak.alternativer.filter((alternativ) => {
					return (
						alternativ.arbeidstider.filter((enArbeidstid) => {
							if (arbeidstid !== enArbeidstid) {
								return false;
							}
							return true;
						}).length > 0
					);
				}).length > 0
			);
		});

		if (!tiltakUtenSkisserForArbeidsEksisterer) {
			return null;
		}

		return (
			<>
				<p>
					{ledetekst.getTekst(
						`arbeidsvarsling.frontendkomponenter.Arbeidstid.feilmelding.${arbeidstid}`
					)}
				</p>
				<ul>
					{ARBEIDSTIDER.filter((tid) => tid === arbeidstid).map(
						(arbeidstid, i) => {
							return Object.keys(tiltakUtenSkisser).map(
								(kategori, j) => {
									const tiltak = tiltakUtenSkisser[kategori];
									return tiltak.alternativer.map(
										(alternativ, k) => {
											return alternativ.arbeidstider.map(
												(enArbeidstid, l) => {
													if (
														arbeidstid !==
														enArbeidstid
													) {
														return;
													}
													return (
														<li
															key={`${i}-${j}-${k}-${l}`}
														>
															{navngiTiltak(
																plantype,
																kategori,
																alternativ
															)}
														</li>
													);
												}
											);
										}
									);
								}
							);
						}
					)}
				</ul>
			</>
		);
	}

	if (Object.keys(tiltakUtenSkisser).length > 0) {
		return (
			<div className="blokk">
				<p>
					{ledetekst.getTekst(
						'arbeidsvarsling.frontendkomponenter.tiltaksskisse.utentiltak'
					)}
				</p>
				{tiltakSomIkkeErKobletTilSkisse(
					tiltakUtenSkisser,
					'INNENFOR_ARBEIDSTID'
				)}
				{tiltakSomIkkeErKobletTilSkisse(
					tiltakUtenSkisser,
					'UTENFOR_ARBEIDSTID'
				)}
			</div>
		);
	}
}

function getSkisserMedFlereArbeidstider(opplastedeSkisser, relevanteTiltak) {
	const skisserSineArbeidstider = {};
	Object.entries(relevanteTiltak).forEach(([kategori, tiltak]) => {
		garanterListe(tiltak.alternativer).forEach((alternativ) => {
			const { arbeidstider: tiltaksArbeidstider } = alternativ;

			const vedlagteSkisserIder = garanterObjekt(
				alternativ.vedlagteSkisserIder
			);

			Object.entries(vedlagteSkisserIder)
				.filter(([skisseArbeidstid]) => {
					return tiltaksArbeidstider?.includes(skisseArbeidstid);
				})
				.forEach(([skisseArbeidstid, skisserIder]) => {
					skisserIder.forEach((skisseId) => {
						skisserSineArbeidstider[skisseId] =
							leggTilUnikArbeidstidForSkisse(
								skisserSineArbeidstider[skisseId],
								skisseArbeidstid
							);
					});
				});
		});
	});

	return opplastedeSkisser.filter(
		(skisse) => garanterListe(skisserSineArbeidstider[skisse.id]).length > 1
	);
}

function leggTilUnikArbeidstidForSkisse(
	skisseSineArbeidstider = [],
	arbeidstid
) {
	return [...new Set([...skisseSineArbeidstider, arbeidstid])];
}

function getTiltakUtenSkisser(opplastedeSkisser, relevanteTiltak) {
	const tiltakUtenSkisser = {};
	Object.keys(relevanteTiltak).forEach((kategori) => {
		const tiltak = relevanteTiltak[kategori];
		const tiltakUtenSkisse = { ...tiltak, alternativer: [] };
		garanterListe(tiltak.alternativer).forEach((alternativ) => {
			const vedlagteSkisserIder = garanterObjekt(
				alternativ.vedlagteSkisserIder
			);
			const arbeidstiderUtenSkisse = garanterListe(
				alternativ.arbeidstider
			).filter((arbeidstid) => {
				return !garanterListe(vedlagteSkisserIder[arbeidstid]).some(
					(skisseId) =>
						opplastedeSkisser.some(
							(skisse) => skisse.id === skisseId
						)
				);
			});
			if (arbeidstiderUtenSkisse.length > 0) {
				tiltakUtenSkisse.alternativer.push({
					...alternativ,
					arbeidstider: arbeidstiderUtenSkisse,
					vedlagteSkisserIder: {},
				});
			}
		});
		if (tiltakUtenSkisse.alternativer.length > 0) {
			tiltakUtenSkisser[kategori] = tiltakUtenSkisse;
		}
	});
	return tiltakUtenSkisser;
}

function getSkisserUtenTiltak(skisser = [], tiltak) {
	const skisseIderFraTiltak = new Set(
		Object.values(tiltak)
			.flatMap((tiltak) => {
				return tiltak.alternativer;
			})
			.flatMap((alternativ) => {
				return Object.entries(
					garanterObjekt(alternativ.vedlagteSkisserIder)
				)
					.filter(([arbeidstid]) =>
						alternativ.arbeidstider.includes(arbeidstid)
					)
					.flatMap(([_, skisseIder]) => skisseIder);
			})
	);

	return skisser.filter((skisse) => !skisseIderFraTiltak.has(skisse.id));
}
