package com.alttd.altitudeweb.controllers.particles;

import com.alttd.altitudeweb.api.ParticlesApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

@Slf4j
@RequiredArgsConstructor
@RestController
public class ParticleController implements ParticlesApi {

//    @Value("${login.secret:#{null}}")
//    private String loginSecret;

    @Value("${particles.file_path}")
    private String particlesFilePath;

//    @Value("${notification.server.url:http://localhost:8080}")
//    private String notificationServerUrl;

    @Override
    public ResponseEntity<Resource> downloadFile(String filename) {
        File file = new File(particlesFilePath);
        if (!file.exists() || !file.isDirectory()) {
            log.error("Particles file path {} is not a directory, not downloading particles file", particlesFilePath);
            return ResponseEntity.status(404).build();
        }
        return getFileForDownload(file, filename);
    }

    @Override
    public ResponseEntity<Resource> downloadFileForUser(String uuid, String filename) {
        File file = new File(particlesFilePath);
        if (!file.exists() || !file.isDirectory()) {
            log.error("Particles file path {} is not a directory, not downloading particles user file", particlesFilePath);
            return ResponseEntity.status(404).build();
        }
        File targetDir = new File(file, uuid);
        if (targetDir.exists()) {
            return getFileForDownload(targetDir, filename);
        } else {
            log.warn("User {} does not have a directory for particles files", uuid);
            return ResponseEntity.notFound().build();
        }
    }

    private ResponseEntity<Resource> getFileForDownload(File file, String filename) {
        filename += ".json";
        File targetFile = new File(file, filename);
        if (!targetFile.exists()) {
            log.warn("Particles file {} does not exist", targetFile.getAbsolutePath());
            return ResponseEntity.notFound().build();
        }

        if (!targetFile.isFile()) {
            log.warn("Particles file {} is not a file", targetFile.getAbsolutePath());
            return ResponseEntity.status(404).build();
        }

        try {
            Path path = targetFile.toPath();
            ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path));

            return ResponseEntity.ok()
                    .contentLength(targetFile.length())
                    .contentType(MediaType.APPLICATION_JSON)
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                    .body(resource);
        } catch (IOException e) {
            log.error("Failed to read particles file {}: {}", targetFile.getAbsolutePath(), e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }

    }

    @Override
    public ResponseEntity<Void> saveFile(String filename, MultipartFile content) {
        File file = new File(particlesFilePath);
        if (!file.exists() || !file.isDirectory()) {
            log.error("Particles file path {} is not a directory, not saving particles file", particlesFilePath);
            return ResponseEntity.status(404).build();
        }
        return writeContentToFile(file, filename, content);
    }

    @Override
    public ResponseEntity<Void> saveFileForUser(String uuid, String filename, MultipartFile content) {
        File file = new File(particlesFilePath);
        if (!file.exists() || !file.isDirectory()) {
            log.error("Particles file path {} is not a directory, not saving particles user file", particlesFilePath);
            return ResponseEntity.status(404).build();
        }
        File targetDir = new File(file, uuid);
        if (!file.exists()) {
            log.debug("Creating particles directory {}", targetDir.getAbsolutePath());
            if (targetDir.mkdirs()) {
                log.info("Created particles user directory {}", targetDir.getAbsolutePath());
            }
        }

        return writeContentToFile(file, filename, content);
    }


    private ResponseEntity<Void> writeContentToFile(File dir, String filename, MultipartFile content) {
        filename += ".json";
        File targetFile = new File(dir, filename);
        if (!Files.isWritable(targetFile.toPath())) {
            log.error("Particles file {} is not writable", targetFile.getAbsolutePath());
            return ResponseEntity.status(403).build();
        }

        if (targetFile.exists()) {
            log.warn("Overwriting existing particles file {}", targetFile.getAbsolutePath());
        }

        try {
            content.transferTo(targetFile);
        } catch (Exception e) {
            log.error("Failed to write particles file {}", targetFile.getAbsolutePath(), e);
            return ResponseEntity.status(500).build();
        }

        return ResponseEntity.ok().build();
    }
}
