package eu.dnetlib.dsm;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import eu.dnetlib.common.controller.AbstractDnetController;
import eu.dnetlib.data.is.vocabulary.repository.VocabularyTermRepository;
import eu.dnetlib.data.openaire.dsm.model.Api;
import eu.dnetlib.data.openaire.dsm.model.BrowseTerm;
import eu.dnetlib.data.openaire.dsm.model.view.SimpleDsWithApis;
import eu.dnetlib.dsm.utils.DsmBrowsableFields;
import eu.dnetlib.is.errors.DsmException;
import eu.dnetlib.is.info.KeyValue;
import eu.dnetlib.is.protocol.ProtocolService;

@RestController
@RequestMapping("/ajax/dsm")
public class DsmAjaxController extends AbstractDnetController {

	@Autowired
	private DsmService dsmService;

	@Autowired
	private VocabularyTermRepository vocabularyTermRepository;

	@Autowired
	private ProtocolService protocolService;

	@GetMapping("/browsableFields")
	public List<KeyValue> browsableFields() {
		return Arrays.stream(DsmBrowsableFields.values())
			.map(f -> new KeyValue(f.name(), f.desc))
			.collect(Collectors.toList());
	}

	@GetMapping("/conf")
	public Map<String, Iterable<?>> configuration() {
		final Map<String, Iterable<?>> map = new LinkedHashMap<>();
		map.put("protocols", protocolService.listProtocols());
		map.put("compatibilityLevels", vocabularyTermRepository.findTermsByVocabulary("dnet:compatibilityLevel"));
		map.put("contentDescTypes", vocabularyTermRepository.findTermsByVocabulary("dnet:content_description_typologies"));
		return map;
	}

	@GetMapping("/browse/{field}")
	public List<BrowseTerm> browse(@PathVariable final String field) {
		return dsmService.browseTerm(DsmBrowsableFields.valueOf(field));
	}

	@GetMapping("/searchByField/{field}/{page}/{size}")
	public Page<SimpleDsWithApis> searchByField(@PathVariable final String field,
		@PathVariable final int page,
		@PathVariable final int size,
		@RequestParam final String value) {
		return dsmService.searchByField(DsmBrowsableFields.valueOf(field), value, page, size);
	}

	@GetMapping("/search/{page}/{size}")
	public Page<SimpleDsWithApis> search(@RequestParam final String value, @PathVariable final int page, @PathVariable final int size) {
		return dsmService.search(value, page, size);
	}

	@GetMapping("/api")
	public Api findApi(@RequestParam final String id) throws DsmException {
		return dsmService.findApi(id);
	}

	@PostMapping("/api")
	public Api saveApi(@RequestBody final Api api) throws DsmException {
		throw new DsmException("TO BE IMPLEMENTED");
	}

}
