/*
 * Copyright (C) 2023 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

import {TransformedFacet} from './context-type';
import {SCFacet, SCThingTranslator, SCThingType, SCTranslations} from '@openstapps/core';
import {searchFilters} from '../../../../config/search-filter';
import {ThingTranslateService} from '../../../translation/thing-translate.service';

const filterConfig = Object.entries(searchFilters).map(([pattern, entries]) => {
  return {
    typePattern: new RegExp(`^${pattern}$`),
    facetFilter: Object.entries(entries).map(([pattern, facet]) => ({
      pattern: new RegExp(`^${pattern}$`),
      ...facet,
    })),
  };
});

/**
 * Transforms facets to
 *
 * 1. only include facets that are allowed in the options
 * 2. translates all fields
 * 3. sorts the facets according to the config
 */
export function transformFacets(
  facets: SCFacet[],
  language: keyof SCTranslations<unknown>,
  thingTranslate: ThingTranslateService,
  translator: SCThingTranslator,
): TransformedFacet[] {
  return facets
    .map(facet => ({
      facet,
      info: filterConfig
        .filter(({typePattern}) => typePattern.test((facet.onlyOnType as string) || ''))
        .flatMap(({facetFilter}) =>
          facetFilter
            .filter(({pattern}) => pattern.test(facet.field))
            .map(it => ({
              onlyOnType: facet.onlyOnType
                ? (translator.translatedPropertyValue(facet.onlyOnType, 'type') as SCThingType)
                : undefined,
              field:
                it.translations && it.name
                  ? it.translations[language]?.name || it.name
                  : thingTranslate.getPropertyName(
                      facet.onlyOnType || SCThingType.AcademicEvent,
                      facet.field,
                    ),
              sortOrder: it.sortOrder,
            })),
        )
        .sort(({sortOrder: a}, {sortOrder: b}) => a - b)[0],
    }))
    .filter(({info}) => !!info)
    .sort(({info: {sortOrder: a}}, {info: {sortOrder: b}}) => a - b);
}
