import CollectionConfig from './CollectionConfig';
//import MediaObject from '../../model/MediaObject';
//import MediaSegment from '../../model/MediaSegment';


class NISVCatalogueConfigFlat extends CollectionConfig {

	constructor(clientId, user, collectionId, collectionMetadata) {
		super(clientId, user, collectionId, collectionMetadata);
		this.FORBIDDEN_FACETS = [
			//filter out carrier times & IDs
			"bg:carriers.bg:carrier.bg:carrier-endposition.keyword",
			"bg:carriers.bg:carrier.bg:carrier-startposition",
			"bg:carriers.bg:carrier.bg:carrierid",
			"bg:carriers.bg:carrier.bg:carrierreference",
			"bg:carriers.bg:carrier.bg:dmguid",
			"bg:carriers.bg:carrier.bg:sorting",
			"bg:carriers.bg:carrier.bg:endoncarrier",
			"bg:carriers.bg:carrier.bg:endtime.keyword",
			"bg:carriers.bg:carrier.bg:externalreference.keyword",
			"bg:carriers.bg:carrier.bg:parentcarrierid.keyword",
			"bg:carriers.bg:carrier.bg:starttime.keyword",
			"bga:segment.bg:carriers.bg:carrier.bg:sorting",
			"bga:segment.bg:carriers.bg:carrier.bg:sorting.keyword",
			"bga:segment.bg:carriers.bg:carrier.bg:starttime.keyword",
			"bga:segment.bg:carriers.bg:carrier.bg:carrier-endposition",
			"bga:segment.bg:carriers.bg:carrier.bg:carrier-startposition",
			"bga:segment.bg:carriers.bg:carrier.bg:carrierid",
			"bga:segment.bg:carriers.bg:carrier.bg:carrierreference",
			"bga:segment.bg:carriers.bg:carrier.bg:dmguid",
			"bga:segment.bg:carriers.bg:carrier.bg:endtime.keyword",

			//filter out all these titles
			"bg:maintitles.bg:title.keyword",
			"bga:segment.bg:maintitles.bg:title.keyword",
			"bg:subtitles.bg:title.keyword",
			"bga:segment.bg:subtitles.bg:title.keyword",
			"bg:publications.bg:publication.bg:title.keyword",
			"bga:season.bg:subtitles.bg:title.keyword",
			"bga:series.bg:maintitles.bg:title.keyword",

			//filter out time/date/number fields
			"bg:publications.bg:publication.bg:starttimestamp.keyword",
			"bga:segment.bg:recordings.bg:recording.bg:dateprecision",

			//filter out all the transcript fields
			"bg:transcripts.bg:transcript.@annotation.keyword",
			"bg:transcripts.bg:transcript.@endtime.keyword",
			"bg:transcripts.bg:transcript.@label.keyword",
			"bg:transcripts.bg:transcript.@rights.keyword",
			"bg:transcripts.bg:transcript.@sequencenumber.keyword",
			"bg:transcripts.bg:transcript.@source.keyword",
			"bg:transcripts.bg:transcript.@starttime.keyword",
			"bg:transcripts.bg:transcript.bg:text.keyword",
			"bga:segment.bg:transcripts.bg:transcript.@annotation.keyword",
			"bga:segment.bg:transcripts.bg:transcript.@endtime.keyword",
			"bga:segment.bg:transcripts.bg:transcript.@label.keyword",
			"bga:segment.bg:transcripts.bg:transcript.@rights.keyword",
			"bga:segment.bg:transcripts.bg:transcript.@source.keyword",
			"bga:segment.bg:transcripts.bg:transcript.@starttime.keyword",
			"bga:segment.bg:transcripts.bg:transcript.bg:text.keyword",

			//filter out these big text fields
			"bga:segment.bg:museum-summary.keyword",
			"bga:series.bg:museum-summary.keyword",
			"bga:segment.bg:museum-description.keyword",
			"layer__asr.wordTimes.keyword"
		];
		this.ALLOWED_FACETS = [
		  "bg:availablecollections.bg:collection",
		  "bg:carriers.bg:carrier.bg:archivestatus.keyword",
		  "bg:carriers.bg:carrier.bg:audiotype.keyword",
		  "bg:carriers.bg:carrier.bg:carrierclass.keyword",
		  "bg:carriers.bg:carrier.bg:carriertype.keyword",
		  "bg:carriers.bg:carrier.bg:depotstatus",
		  "bg:carriers.bg:carrier.bg:format.keyword",
		  "bg:carriers.bg:carrier.bg:location.keyword",
		  "bg:carriers.bg:carrier.bg:metrage.keyword",
		  "bg:carriers.bg:carrier.bg:origin.keyword",
		  "bg:carriers.bg:carrier.bg:repository",
		  "bg:carriers.bg:carrier.bg:storageunit",
		  "bg:casts.bg:cast.bg:character.keyword",
		  "bg:casts.bg:cast.bg:clarification.keyword",
		  "bg:casts.bg:cast.bg:name.keyword",
		  "bg:catalog.keyword",
		  "bg:clearingstatus.keyword",
		  "bg:context.bg:awards.keyword",
		  "bg:context.bg:colour",
		  "bg:context.bg:composition.keyword",
		  "bg:context.bg:context.keyword",
		  "bg:context.bg:occasion.keyword",
		  "bg:context.bg:silent.keyword",
		  "bg:contractors.bg:contractor.bg:name.keyword",
		  "bg:creators.bg:creator.bg:clarification.keyword",
		  "bg:creators.bg:creator.bg:name.keyword",
		  "bg:creators.bg:creator.bg:roles.bg:role.keyword",
		  "bg:deprecatedkeyword.bg:keyword.keyword",
		  "bg:executives.bg:executive.bg:clarification.keyword",
		  "bg:executives.bg:executive.bg:name.keyword",
		  "bg:executives.bg:executive.bg:role.keyword",
		  "bg:funders.bg:funder.bg:name.keyword",
		  "bg:genres.bg:genre.keyword",
		  "bg:keywords.bg:keyword.keyword",
		  "bg:languages.bg:language.bg:language",
		  "bg:languages.bg:language.bg:use",
		  "bg:links.bg:link.keyword",
		  "bg:locations.bg:location.keyword",
		  "bg:museum-annotation.keyword",
		  "bg:museum-genres.bg:genre.keyword",
		  "bg:museum-keywords.bg:keyword.keyword",
		  "bg:museum-locations.bg:location.keyword",
		  "bg:museum-names.bg:name.keyword",
		  "bg:museum-personnames.bg:personname.keyword",
		  "bg:museum-themes.bg:theme.keyword",
		  "bg:musicstyles.bg:musicstyle.keyword",
		  "bg:names.bg:name.keyword",
		  "bg:nationalities.bg:nationality.bg:country.keyword",
		  "bg:nationalities.bg:nationality.bg:role.keyword",
		  "bg:originalCreators.bg:creator.bg:clarification.keyword",
		  "bg:originalCreators.bg:creator.bg:name.keyword",
		  "bg:originalCreators.bg:creator.bg:role.keyword",
		  "bg:part.keyword",
		  "bg:personnames.bg:personname.keyword",
		  "bg:producers.bg:producer.bg:name.keyword",
		  "bg:productioncountries.bg:country.keyword",
		  "bg:publications.bg:publication.bg:broadcasters.bg:broadcaster",
		  "bg:publications.bg:publication.bg:broadcastnorm.keyword",
		  "bg:publications.bg:publication.bg:dateprecision.keyword",
		  "bg:publications.bg:publication.bg:distributionchannel",
		  "bg:publications.bg:publication.bg:distributionformat.keyword",
		  "bg:publications.bg:publication.bg:frequency.keyword",
		  "bg:publications.bg:publication.bg:live.keyword",
		  "bg:publications.bg:publication.bg:networks.bg:network",
		  "bg:publications.bg:publication.bg:publication-annotation.keyword",
		  "bg:publications.bg:publication.bg:rebroadcast.keyword",
		  "bg:publications.bg:publication.bg:timecodestandard.keyword",
		  "bg:publications.bg:publication.bg:type",
		  "bg:publications.bg:publication.bg:ugstatus",
		  "bg:publications.bg:publication.bg:weeknumber.keyword",
		  "bg:qualification.bg:block.keyword",
		  "bg:qualification.bg:license.keyword",
		  "bg:qualification.bg:rights.keyword",
		  "bg:qualification.bg:source.keyword",
		  "bg:recordinglocations.bg:location",
		  "bg:recordings.bg:recording.bg:withaudience.keyword",
		  "bg:sourcecatalog",
		  "bg:speakers.bg:speaker.bg:name.keyword",
		  "bg:speakers.bg:speaker.bg:role.keyword",
		  "bg:sponsors.bg:sponsor.bg:name.keyword",
		  "bg:targetgroups.bg:targetgroup.keyword",
		  "bg:themes.bg:theme.keyword",
		  "bg:used-archivematerials.bg:used-archivematerial.keyword",
		  "bga:season.bg:casts.bg:cast.bg:character.keyword",
		  "bga:season.bg:casts.bg:cast.bg:clarification.keyword",
		  "bga:season.bg:casts.bg:cast.bg:name.keyword",
		  "bga:season.bg:context.bg:awards.keyword",
		  "bga:season.bg:context.bg:colour.keyword",
		  "bga:season.bg:context.bg:context.keyword",
		  "bga:season.bg:context.bg:occasion.keyword",
		  "bga:season.bg:contractors.bg:contractor.bg:name.keyword",
		  "bga:season.bg:creators.bg:creator.bg:clarification.keyword",
		  "bga:season.bg:creators.bg:creator.bg:name.keyword",
		  "bga:season.bg:creators.bg:creator.bg:roles.bg:role.keyword",
		  "bga:season.bg:executives.bg:executive.bg:clarification.keyword",
		  "bga:season.bg:executives.bg:executive.bg:name.keyword",
		  "bga:season.bg:executives.bg:executive.bg:role.keyword",
		  "bga:season.bg:funders.bg:funder.bg:name.keyword",
		  "bga:season.bg:genres.bg:genre.keyword",
		  "bga:season.bg:keywords.bg:keyword.keyword",
		  "bga:season.bg:languages.bg:language.bg:language",
		  "bga:season.bg:languages.bg:language.bg:use.keyword",
		  "bga:season.bg:links.bg:link.keyword",
		  "bga:season.bg:locations.bg:location.keyword",
		  "bga:season.bg:maintitles.bg:title.keyword",
		  "bga:season.bg:names.bg:name.keyword",
		  "bga:season.bg:personnames.bg:personname.keyword",
		  "bga:season.bg:producers.bg:producer.bg:name.keyword",
		  "bga:season.bg:productioncountries.bg:country.keyword",
		  "bga:season.bg:qualification.bg:block.keyword",
		  "bga:season.bg:qualification.bg:license.keyword",
		  "bga:season.bg:qualification.bg:rights.keyword",
		  "bga:season.bg:qualification.bg:source.keyword",
		  "bga:season.bg:recordinglocations.bg:location.keyword",
		  "bga:season.bg:recordings.bg:recording.bg:withaudience.keyword",
		  "bga:season.bg:speakers.bg:speaker.bg:name.keyword",
		  "bga:season.bg:speakers.bg:speaker.bg:role.keyword",
		  "bga:season.bg:sponsors.bg:sponsor.bg:name.keyword",
		  "bga:season.bg:targetgroups.bg:targetgroup.keyword",
		  "bga:segment.bg:availablecollections.bg:collection.keyword",
		  "bga:segment.bg:carriers.bg:carrier.bg:archivestatus.keyword",
		  "bga:segment.bg:carriers.bg:carrier.bg:audiotype.keyword",
		  "bga:segment.bg:carriers.bg:carrier.bg:carrierclass",
		  "bga:segment.bg:carriers.bg:carrier.bg:carriertype",
		  "bga:segment.bg:carriers.bg:carrier.bg:depotstatus",
		  "bga:segment.bg:carriers.bg:carrier.bg:format",
		  "bga:segment.bg:carriers.bg:carrier.bg:location.keyword",
		  "bga:segment.bg:carriers.bg:carrier.bg:metrage.keyword",
		  "bga:segment.bg:carriers.bg:carrier.bg:origin.keyword",
		  "bga:segment.bg:carriers.bg:carrier.bg:parentcarrierid.keyword",
		  "bga:segment.bg:carriers.bg:carrier.bg:repository",
		  "bga:segment.bg:carriers.bg:carrier.bg:storageunit",
		  "bga:segment.bg:casts.bg:cast.bg:character.keyword",
		  "bga:segment.bg:casts.bg:cast.bg:clarification.keyword",
		  "bga:segment.bg:casts.bg:cast.bg:name.keyword",
		  "bga:segment.bg:clearingstatus.keyword",
		  "bga:segment.bg:context.bg:awards.keyword",
		  "bga:segment.bg:context.bg:colour.keyword",
		  "bga:segment.bg:context.bg:composition.keyword",
		  "bga:segment.bg:context.bg:context.keyword",
		  "bga:segment.bg:context.bg:occasion.keyword",
		  "bga:segment.bg:context.bg:silent.keyword",
		  "bga:segment.bg:contractors.bg:contractor.bg:name.keyword",
		  "bga:segment.bg:creators.bg:creator.bg:clarification.keyword",
		  "bga:segment.bg:creators.bg:creator.bg:name.keyword",
		  "bga:segment.bg:creators.bg:creator.bg:roles.bg:role.keyword",
		  "bga:segment.bg:deprecatedkeyword.bg:keyword.keyword",
		  "bga:segment.bg:executives.bg:executive.bg:clarification.keyword",
		  "bga:segment.bg:executives.bg:executive.bg:name.keyword",
		  "bga:segment.bg:executives.bg:executive.bg:role.keyword",
		  "bga:segment.bg:funders.bg:funder.bg:name.keyword",
		  "bga:segment.bg:genres.bg:genre.keyword",
		  "bga:segment.bg:keywords.bg:keyword.keyword",
		  "bga:segment.bg:languages.bg:language.bg:language",
		  "bga:segment.bg:languages.bg:language.bg:use.keyword",
		  "bga:segment.bg:links.bg:link.keyword",
		  "bga:segment.bg:locations.bg:location.keyword",
		  "bga:segment.bg:museum-annotation.keyword",
		  "bga:segment.bg:museum-languageid.keyword",
		  "bga:segment.bg:museum-locations.bg:location.keyword",
		  "bga:segment.bg:musicstyles.bg:musicstyle.keyword",
		  "bga:segment.bg:names.bg:name.keyword",
		  "bga:segment.bg:nationalities.bg:nationality.bg:country.keyword",
		  "bga:segment.bg:nationalities.bg:nationality.bg:role.keyword",
		  "bga:segment.bg:originalCreators.bg:creator.bg:clarification.keyword",
		  "bga:segment.bg:originalCreators.bg:creator.bg:name.keyword",
		  "bga:segment.bg:originalCreators.bg:creator.bg:role.keyword",
		  "bga:segment.bg:personnames.bg:personname.keyword",
		  "bga:segment.bg:producers.bg:producer.bg:name.keyword",
		  "bga:segment.bg:qualification.bg:block.keyword",
		  "bga:segment.bg:qualification.bg:license.keyword",
		  "bga:segment.bg:qualification.bg:rights.keyword",
		  "bga:segment.bg:qualification.bg:source.keyword",
		  "bga:segment.bg:recordinglocations.bg:location.keyword",
		  "bga:segment.bg:recordings.bg:recording.bg:withaudience.keyword",
		  "bga:segment.bg:sourcecatalog",
		  "bga:segment.bg:speakers.bg:speaker.bg:name.keyword",
		  "bga:segment.bg:speakers.bg:speaker.bg:role.keyword",
		  "bga:segment.bg:sponsors.bg:sponsor.bg:name.keyword",
		  "bga:segment.bg:themes.bg:theme.keyword",
		  "bga:segment.bg:type.keyword",
		  "bga:series.bg:casts.bg:cast.bg:character.keyword",
		  "bga:series.bg:casts.bg:cast.bg:clarification.keyword",
		  "bga:series.bg:casts.bg:cast.bg:name.keyword",
		  "bga:series.bg:catalog.keyword",
		  "bga:series.bg:context.bg:awards.keyword",
		  "bga:series.bg:context.bg:composition.keyword",
		  "bga:series.bg:context.bg:context.keyword",
		  "bga:series.bg:context.bg:occasion.keyword",
		  "bga:series.bg:contractors.bg:contractor.bg:name.keyword",
		  "bga:series.bg:creators.bg:creator.bg:clarification.keyword",
		  "bga:series.bg:creators.bg:creator.bg:name.keyword",
		  "bga:series.bg:creators.bg:creator.bg:roles.bg:role.keyword",
		  "bga:series.bg:distributionchannel",
		  "bga:series.bg:executives.bg:executive.bg:clarification.keyword",
		  "bga:series.bg:executives.bg:executive.bg:name.keyword",
		  "bga:series.bg:executives.bg:executive.bg:role.keyword",
		  "bga:series.bg:funders.bg:funder.bg:name.keyword",
		  "bga:series.bg:genres.bg:genre.keyword",
		  "bga:series.bg:keywords.bg:keyword.keyword",
		  "bga:series.bg:links.bg:link.keyword",
		  "bga:series.bg:locations.bg:location.keyword",
		  "bga:series.bg:museum-genres.bg:genre.keyword",
		  "bga:series.bg:musicstyles.bg:musicstyle.keyword",
		  "bga:series.bg:names.bg:name.keyword",
		  "bga:series.bg:originalCreators.bg:creator.bg:clarification.keyword",
		  "bga:series.bg:originalCreators.bg:creator.bg:name.keyword",
		  "bga:series.bg:originalCreators.bg:creator.bg:role.keyword",
		  "bga:series.bg:personnames.bg:personname.keyword",
		  "bga:series.bg:producers.bg:producer.bg:name.keyword",
		  "bga:series.bg:productioncountries.bg:country.keyword",
		  "bga:series.bg:qualification.bg:block.keyword",
		  "bga:series.bg:qualification.bg:license.keyword",
		  "bga:series.bg:qualification.bg:rights.keyword",
		  "bga:series.bg:qualification.bg:source.keyword",
		  "bga:series.bg:recordinglocations.bg:location.keyword",
		  "bga:series.bg:recordings.bg:recording.bg:withaudience.keyword",
		  "bga:series.bg:speakers.bg:speaker.bg:name.keyword",
		  "bga:series.bg:speakers.bg:speaker.bg:role.keyword",
		  "bga:series.bg:sponsors.bg:sponsor.bg:name.keyword",
		  "bga:series.bg:targetgroups.bg:targetgroup.keyword",
		  "mediaType"
		];
	}

	getFacetSelectionList(allowHeavyFacets) {
		const kwFields = super.getFacetSelectionList(allowHeavyFacets) || [];
		return allowHeavyFacets ? kwFields : kwFields.filter(kw => this.FORBIDDEN_FACETS.indexOf(kw.value) == -1);
	}

	getNamespace() {
		return 'http://av.beeldengeluid.nl/'
	}

	//the type varies for B&G
	getCollectionMediaTypes() {
		return []
	}

	//used to prevent graphs to blow up in case the minimum date is really low (because of incorrect data)
	getMinimunYear() {
		return 1850
	}

	//override so the annotation layer indices are ignored
	getCollectionIndices() {
		return [this.getCollectionId()]
	}

	//this means the resource viewer needs to request access to the content before it can show them
	requiresPlayoutAccess() {
		return true
	}

	hideOffAirContent() {
		return true
	}

	getPreferredDateField() {
		return 'bg:publications.bg:publication.bg:sortdate';
	}

	static __isValidDate(dateString) {
		const regEx = /^\d{2}-\d{2}-\d{4}$/;
		return dateString.match(regEx) !== null;
	}

    // if there's a ; we assume multiple dates, so we split the string into an array and remove any extra spaces (trim)
    getFormattedDates(date) {
    	if(date && typeof(date) === 'string') {
    		const formatDateString = str => { const d = str.trim().split('-'); return d[2] + '-' + d[1] + '-' + d[0]; }
            if(date.indexOf(';') !== -1) {
                return date.split(';').map(formatDateString);
            } else {
                return [formatDateString(date)];
            }
        }
        return null;
    }

	getFieldsToExclude() {
		return ['layer__asr', 'bga:season.bg:transcripts', 'bg:transcripts', 'bga:segment.bg:transcripts']
	}

	getFacets() {
		return [
			{
				field: 'bg:publications.bg:publication.bg:broadcasters.bg:broadcaster',
				title : 'Broadcaster',
				id : 'broadcaster',
				type : 'string'
			},
			{
				field: 'bga:series.bg:genres.bg:genre.keyword',
				title : 'Genre (series)',
				id : 'genre',
				type : 'string'
			},
			{
				field: 'bg:keywords.bg:keyword.keyword',
				title : 'Keyword',
				id : 'keyword',
				type : 'string'
			}
		];
	}

	getNestedSearchLayers() {
		// return [{
		// 	path : 'layer__asr',
		// 	fields : [
		// 		'layer__asr.words'
		// 	]
		// }];
	}

	getMetadataFieldCategories() {
		return [
			{
				id : 'titles',
				label : 'Titles',
				fields : [
					'bga:series.bg:maintitles.bg:title',
					'bga:season.bg:maintitles.bg:title',
					'bga:segment.bg:maintitles.bg:title',
					'bg:maintitles.bg:title'
				]
			},
			{
				id : 'descriptions',
				label : 'Descriptions',
				fields : [
					'bg:summary',
					'bg:description',
					'bga:segment.bg:description',
					'bg:museum-description',
					'bga:series.bg:museum-description',
					'bga:segment.bg:museum-description'
				]
			},
			{
				id : 'subtitles',
				label : 'Keywords from Subtitles',
				fields : [
					'bg:transcripts.bg:transcript.bg:text',
					'bga:segment.bg:transcripts.bg:transcript.bg:text'
				]
			},
			{
				id: 'subject',
				label: 'Subject keywords',
				fields: [
					'bg:keywords.bg:keyword',
					'bga:season.bg:keywords.bg:keyword',
					'bga:segment.bg:keywords.bg:keyword',
					'bga:series.bg:keywords.bg:keyword'
				]
			},
			{
				id : 'asr',
				label : 'Speech transcripts (ASR)',
				// nestedPath : 'layer__asr',
				// enrichment : true,
				fields : [
					'layer__asr.words'
				]
			}
		]
	}

	getItemDetailData(result, currentDateField) {
		result = this.formatSearchResult(result);
		const formattedResult = {}
		formattedResult.resourceId = result._id;
		formattedResult.index = result._index;
		formattedResult.docType = result._type;
		formattedResult.collectionId = result.collectionId;
		formattedResult.title = this.__extractTitle(result);
		formattedResult.description = this.__extractDescription(result);
		const dateInfo = this.__extractDateInfo(result, currentDateField);
		if(dateInfo) {
			formattedResult.date = dateInfo.date;
			formattedResult.dateField = dateInfo.field;
		}
		formattedResult.externalSourceInfo = this.__getExternalSourceInfo(result);
		formattedResult.specialProperties = this.__extractSpecialProperties(result);

		const content = this.__extractPlayableContent(result);
		formattedResult.playableContent = content.playableContent;
		formattedResult.mediaTypes = content.mediaTypes;
		formattedResult.rawData = result;
		/*
		//THIS IS ONLY WHEN USING THE MULTI-LAYERED APPROACH OF HAVING MULTIPLE INDEXES
		//if the user did not specify a search string there will be no inner hits and thus no fragment metadata!

		//the media fragment is passed to the resource viewer, so it will skip to that piece of media
		//TODO this should be changed, since the media fragment is now reflected as a URL, which should be hidden to
		//prevent easily downloading it
		if(result._type == 'media_fragment' &&
			formattedResult.playableContent &&
			formattedResult.playableContent.length > 0) {
			formattedResult.mediaFragment = {
				url : formattedResult.playableContent[0].url,
				assetId : formattedResult.playableContent[0].assetId,
				start : result.start || 0,
				end : result.start + result.duration || 5000,
				snippet : result.words ? '(...) "' + result.words  + '" (...)' : '',
				layer : 'asr'
			}

		}*/

		return formattedResult;
	}

	//in case the field name cannot be found in the field descriptions
	formatIndexFieldName(esFieldName) {
		return esFieldName; //don't format, force the field_descriptions to be updated
	}

	//override to add the level to each field (which will display in the FieldSelector)
	//at the same time, exclude the level from the pretty field name
	getAllFields() {
		const fields = super.getAllFields()
		fields.forEach(f => {
			const tmp = f.id.split('.');
			let metadataLayer = 'program';
			if (tmp[0].indexOf('bga:') !== -1) {
				metadataLayer = tmp[0].substring(tmp[0].indexOf(':') + 1);
			}
			f.level = metadataLayer;
			f.title = this.toPrettyFieldName(f.id, false);
		});
		return fields
	}

	usesLayeredModel() {
		return true;
	}

	__extractTitle(result) {
		let title = null;
		//first check the series title
		if (result.hasOwnProperty('bga:series')) {
			const series = result['bga:series'];
			if (series.hasOwnProperty('bg:maintitles') && series['bg:maintitles'].hasOwnProperty('bg:title')) {
				title = series['bg:maintitles']['bg:title'].join(' / ');
			}
		}
		//then check the season title
		if (result.hasOwnProperty('bga:season')) {
			const season = result['bga:season'];
			if (season.hasOwnProperty('bg:maintitles') && season['bg:maintitles'].hasOwnProperty('bg:title')) {
				title = title ? title + '; ' : '';
				title += season['bg:maintitles']['bg:title'].join(' / ');
			}
		}
		//then check the expression title
		if (result.hasOwnProperty('bg:maintitles') && result['bg:maintitles'].hasOwnProperty('bg:title')) {
			title = title ? title + ': ' : '';
			title += result['bg:maintitles']['bg:title'].join(' / ');
			if (result.hasOwnProperty('bg:subtitles') && result['bg:subtitles'].hasOwnProperty('bg:title')) {
				title += ' - ' + result['bg:subtitles']['bg:title'].join('; ');
			}
		}
		return title;
	}

	__extractSegmentTitle(segment) {
		if (segment.hasOwnProperty('bg:maintitles') && segment['bg:maintitles'].hasOwnProperty('bg:title')) {
			const titles = typeof segment['bg:maintitles']['bg:title'] === "string" ?
				[segment['bg:maintitles']['bg:title']] :
				segment['bg:maintitles']['bg:title']
			return titles.join(' / ');
		}
		return null
	}

	__extractDescription(result) {

		if (result.hasOwnProperty('bg:summary')) {
			return result['bg:summary'];
		} else if (result.hasOwnProperty('bga:series') && result['bga:series'].hasOwnProperty('bg:summary')) {
		    return result['bga:series']['bg:summary'];
		} else if (result.hasOwnProperty('bg:publications') && result['bg:publications'].hasOwnProperty('bg:publication') && result['bg:publications']['bg:publication'].hasOwnProperty('bg:publication-annotation')) {
			return result['bg:publications']['bg:publication']['bg:publication-annotation'];
		} else {
		    const broadcasterGenre = this.__extractSpecialProperties(result);
			if (broadcasterGenre.hasOwnProperty("Broadcaster") && broadcasterGenre.hasOwnProperty("Genre")) {
			    return broadcasterGenre.Genre + " (" + broadcasterGenre.Broadcaster + ")";
			} else if (result.hasOwnProperty('bga:season') && result['bga:season'].hasOwnProperty('bg:summary')) {
                return result['bga:season']['bg:summary'];
			} else {
			    return "";
			}
		}
	}

	__extractDateInfo(result, currentDateField) {
		const usePublicationDate = true;
		if(currentDateField) {
			//if the selected date field is something else than the default sortdate try to fetch something different
			if(currentDateField.indexOf('sortdate') === -1) {

			}

		}
		if(usePublicationDate) {
			if (result.hasOwnProperty('bg:publications') && result['bg:publications'].hasOwnProperty('bg:publication')) {
				const pubs = result['bg:publications']['bg:publication'];
				if(pubs.hasOwnProperty('bg:sortdate')) {
					return {
						date : pubs['bg:sortdate'],
						field : 'bg:publications.bg:publication.bg:sortdate'
					}
				} else if(pubs.map) { //make sure it is actually an array
					return {
						date : pubs.map((pub) => {
							return pub.hasOwnProperty('bg:sortdate') ? pub['bg:sortdate'] : '';
						}).join(' / '),
						field : 'bg:publications.bg:publication.bg:sortdate'
					}
				}
			}
		}
		return null;
	}

	__extractPlayableContent(result) {
		let mimeType = 'video/mp4';

		//determine whether the content is radio or not
		if(result.hasOwnProperty('bga:series')) {
			const series = result['bga:series'];
			if(series.hasOwnProperty('bg:distributionchannel') &&
				result['bga:series']['bg:distributionchannel'].toLowerCase() === 'radio') {
				mimeType = 'audio/mp3';
			} else if (series.hasOwnProperty('bg:catalog') && series['bg:catalog'] === 'Foto') {
				mimeType = 'image/jpeg';
			}
		}

		//first merge the carriers
		const mergedCarriers = this.__getMergedCarriers(result);

		//fill the playable content array
		const playableContent = Object.keys(mergedCarriers).length > 0 ? this.__generatePlayableContent(mergedCarriers, mimeType) : [];

		//now make sure the mediaTypes are all there
		let mediaTypes = null;
		mediaTypes = ["video"];
		if(mimeType === 'audio/mp3') {
			mediaTypes = ["audio"];
		} else if (mimeType === "image/jpeg") {
			mediaTypes = ["image"];
		}

		return {
			playableContent : playableContent,
			mediaTypes : mediaTypes
		}
	}

	//FIXME https://mediasuite.xlab.nl/tool/resource-viewer?id=5328532@program&cid=nisv-catalogue-aggr-full-18-158&st=zwaard
	// incorrect time per segment...
	__getMergedCarriers(result) {
		const mergedCarriers = {}
		let carriers = [];
		if(result['bg:carriers'] && result['bg:carriers']['bg:carrier']) {
			this.__mergeCarriers(result['bg:carriers']['bg:carrier'], mergedCarriers, 'Program segments:', true)
		}

		//add the content attached to the segments
		if(result['bga:segment']) {
			result['bga:segment'].forEach((segment) => {
				if(segment['bg:carriers'] && segment['bg:carriers']['bg:carrier']) {
					this.__mergeCarriers(
						segment['bg:carriers']['bg:carrier'],
						mergedCarriers,
						this.__extractSegmentTitle(segment)
					)
				}
			});
		}
		return mergedCarriers;
	}

	/* Groups "media archive" carriers (from a certain program level) into a dict with mediaObjects with 0 or more segments.

		- ProgramSegment indicates if carriers/segments reflect the program as a whole.
		- Lastly each mediaObject is marked being "raw content" in case it's "Schone inlas"
	*/
	__mergeCarriers(carrierElement, alreadyMerged, title, programSegment=false) {
		if(carrierElement) {
			const carriers = carrierElement.hasOwnProperty('bg:carrierreference') ? [carrierElement] : carrierElement;
			carriers.forEach(c => {
				if(c['bg:carriertype'] === 'media archive') {// && c['bg:carrierclass'] === 'Programma'
					const segment = this.__toSegment(c, title, programSegment, alreadyMerged);
					if(segment) {
						if(c['bg:carrierreference'] in alreadyMerged) {
							alreadyMerged[c['bg:carrierreference']].segments.push(segment)
						} else {
							alreadyMerged[c['bg:carrierreference']] = {
								assetId : c['bg:carrierreference'],
								segments : [segment],
								isRawContent : c['bg:carrierclass'] !== 'Programma'
							};
						}
					}
				}
			})

		}
	}

	//the alreadyMerged also contains the program level carriers, which are needed in case the segment carrier
	//does not have a startoffset.
	__toSegment(carrier, title, programSegment, alreadyMerged) {
		let offset = carrier.hasOwnProperty('bg:startoffset') ? parseInt(carrier['bg:startoffset']) : -1;
		let start = carrier.hasOwnProperty('bg:startoncarrier') ? parseInt(carrier['bg:startoncarrier']) : -1;
		let end = carrier.hasOwnProperty('bg:endoncarrier') ? parseInt(carrier['bg:endoncarrier']) : -1;

		if(offset === -1) {
			if(programSegment) { // if the program has no offset, the start time needs to be zero (+ the end needs correction too)
				start = 0;
				end = (end - start) / 1000;
			} else if(carrier['bg:carrierreference'] !== undefined && alreadyMerged[carrier['bg:carrierreference']] !== undefined) {
				// if a segment has no offset, use the parent's original start time (still in millis).
				const programCarrier = alreadyMerged[carrier['bg:carrierreference']].segments.find(s => s.programSegment);
				offset = programCarrier.parentStartMillis !== -1 ? programCarrier.parentStartMillis : 0;
				start = (start - offset) / 1000;
				end = (end - offset) / 1000;
			}
		} else { //there is an offset in the metadata, just calculate as expected
			start = (start - offset) / 1000;
			end = (end - offset) / 1000;
		}

		if(isNaN(offset) || isNaN(start) || isNaN(end)) {
			return null;
		}
		//return new MediaSegment(start, end, title, programSegment);
		return {
			start : start,
			end : end,
			parentStartMillis : programSegment ? parseInt(carrier['bg:startoncarrier']) : -1, //use the original start time as offset
			title : title,
			programSegment : programSegment
		}
	}

	__generatePlayableContent(mergedCarriers, mimeType) {
		return Object.keys(mergedCarriers).map(assetId => {
			const c = mergedCarriers[assetId];
			c.segments.sort((a, b) => a.start > b.start)
			const url = _play +
				'/api/play/' +
				this.__getContentServerId(mimeType) +
				'/' +
				this.__getContentId(assetId) +
				'?cid=' +
				_clientId +
				'&at=' +
				_chickenStock;
			return {
				assetId : assetId,
				mimeType : mimeType,
				url : url,
				contentId : this.__getContentId(assetId),
				contentServerId : this.__getContentServerId(mimeType),
				segments : c.segments.length > 1 ? c.segments : null,
				resourceStart : mimeType.indexOf('audio') === -1 ? c.segments[0].start : -1, //important, ignore off-air for audio!
				resourceEnd : mimeType.indexOf('audio') === -1 ? c.segments[0].end : -1, //important, ignore off-air for audio!
				isRawContent : c.isRawContent
			}
		})
	}

	__getContentServerId(mimeType) {
		let contentServerId = 'beng-video';
		if (mimeType.indexOf('audio') !== -1) {
			contentServerId = 'beng-audio';
		}
		return contentServerId;
	}

	__getContentId(guci) {
		let i = guci.length-1;
		let cid = '';
		while(i >= 0) {
			cid += String.fromCharCode(guci.charCodeAt(i) + 1);
			i--;
		}
		return cid;
	}

	__getExternalSourceInfo(result) {
		if(result.hasOwnProperty('dc:relation')) {
			return {
				url :result['dc:relation'],
				message : null
			}
		}
		return null;
	}

	//these are the properties that will be shown in the regular item details table
	__extractSpecialProperties(result) {
		const specialProperties = {};
		//broadcaster
		if (result.hasOwnProperty('bg:publications') && result['bg:publications'].hasOwnProperty('bg:publication')) {
			if (result['bg:publications']['bg:publication'].hasOwnProperty('bg:broadcasters')) {
				specialProperties['Broadcaster'] = result['bg:publications']['bg:publication']['bg:broadcasters']['bg:broadcaster'];
			}
		}
		//genre
		if (result.hasOwnProperty('bg:genres') && result['bg:genres'].hasOwnProperty('bg:genre')) {
			specialProperties['Genre'] = result['bg:genres']['bg:genre'];
		}
		return specialProperties;
	}

}

export default NISVCatalogueConfigFlat;
