package com.reg.server.pdf;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@CrossOrigin
public class PdfController {
	private final ResourcePatternResolver resolver;

	@Value("${app.pdf.external-dir:}")
	private String externalDir;

	public PdfController(ResourcePatternResolver resolver) {
		this.resolver = resolver;
	}

	@GetMapping("/api/pdfs")
	public List<PdfFile> listPdfs() throws IOException {
		Map<String, PdfFile> filesByName = new LinkedHashMap<>();

		for (String name : listClasspathPdfs()) {
			filesByName.putIfAbsent(name, toPdfFile(name));
		}
		for (String name : listExternalPdfs()) {
			filesByName.putIfAbsent(name, toPdfFile(name));
		}

		return filesByName.values().stream()
				.sorted(Comparator.comparing(PdfFile::getName, String.CASE_INSENSITIVE_ORDER))
				.collect(Collectors.toList());
	}

	private List<String> listClasspathPdfs() throws IOException {
		Resource[] resources = resolver.getResources("classpath*:/pdf/*.pdf");
		List<String> names = new ArrayList<>();
		for (Resource resource : resources) {
			String filename = resource.getFilename();
			if (filename != null && filename.toLowerCase().endsWith(".pdf")) {
				names.add(filename);
			}
		}
		return names;
	}

	private List<String> listExternalPdfs() {
		if (!StringUtils.hasText(externalDir)) {
			return Collections.emptyList();
		}
		Path dir = Paths.get(externalDir).toAbsolutePath().normalize();
		if (!Files.isDirectory(dir)) {
			return Collections.emptyList();
		}
		try (Stream<Path> stream = Files.list(dir)) {
			return stream
					.filter(Files::isRegularFile)
					.map(path -> path.getFileName().toString())
					.filter(name -> name.toLowerCase().endsWith(".pdf"))
					.sorted(String.CASE_INSENSITIVE_ORDER)
					.collect(Collectors.toList());
		} catch (Exception ignored) {
			return Collections.emptyList();
		}
	}

	private static PdfFile toPdfFile(String name) {
		String encoded = UriUtils.encodePathSegment(name, StandardCharsets.UTF_8);
		return new PdfFile(name, "/pdf/" + encoded);
	}

	public static class PdfFile {
		private String name;
		private String url;

		public PdfFile() {
		}

		public PdfFile(String name, String url) {
			this.name = name;
			this.url = url;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getUrl() {
			return url;
		}

		public void setUrl(String url) {
			this.url = url;
		}
	}
}

