package com.server.api.controller;


import com.server.api.controller.dto.RollendruckGenReqDto;
import com.server.api.models.RollenDruckDupliArtikel;
import com.server.api.models.VorlageRollendruck;
import com.server.api.service.rollendruck.VorlageRollendruckService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import com.server.api.service.rollendruck.VorlageRollendruckPDFGeneratorService;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

@RestController
@RequestMapping("/VorlageRollenDruck")
public class VorlageRollendruckController {

    @Autowired private VorlageRollendruckService vorlageRollendruckService;
    @Autowired private VorlageRollendruckPDFGeneratorService vorlagenPDFGeneratorService;


    @PostMapping("/createRollenDruckVorlage")
    public ResponseEntity<String> createVorlageWithCoordinates(
            @RequestBody VorlageRollendruck vorlage) {
        vorlageRollendruckService.createRollendruckVorlage(vorlage);
        return ResponseEntity.ok("Vorlage Rollendruck successfully created.");
    }

    @GetMapping("/getAllRollendruckVorlagen")
    public List<VorlageRollendruck> getAllRollendruckVorlagen() {
        // Get all rollendruck templates
        return vorlageRollendruckService.getAllVorlagen();
    }

    @PostMapping("/alterVorlage")
    public ResponseEntity<?> alterVorlage(@RequestBody VorlageRollendruck vorlage) {
        vorlageRollendruckService.alterVorlage(vorlage);
        return ResponseEntity.ok("Vorlage successfully created with coordinates.");
    }

    @DeleteMapping("/delete/{id}")
    public void deleteVorlageRollendruck(@PathVariable Long id) {
        vorlageRollendruckService.deleteVorlageRollendruck(id);
    }

    @PostMapping(value = "/generate", consumes = "application/json")
    public ResponseEntity<?> uploadFiles(@RequestBody RollendruckGenReqDto rollendruckGenReqDto) {
        List<String> vorlageIds = rollendruckGenReqDto.getVorlageIds();
        String rootDir = rollendruckGenReqDto.getRootDirectory();

        String OUTPUT_DIR = String.valueOf((long) (Math.random() * 9_000_000_000L) + 1_000_000_000L)+"/";

        Path output = Paths.get(OUTPUT_DIR);

        // Ensure the directory path exists before checking it
        if (Files.exists(output)) {
            try {
                deleteDirectoryRecursively(output);
            }catch (Exception e) {


            }
        }

        String sharedFolder = null;
        String next_url = null;

        try {
            sharedFolder = System.getenv("SHARED_FOLDER");
            next_url = System.getenv("NEXT_SERVER_URL");
            if (sharedFolder == null || sharedFolder.isEmpty()) {
                sharedFolder = "../frontend/public";
            }
            if (next_url == null || next_url.isEmpty()) {
                next_url = "http://localhost:3050";
            }
            String uploadPath = sharedFolder + "/" + rootDir + "/";
            File dir = new File(uploadPath);
            if (!dir.exists() && !dir.isDirectory()) {
                throw new Exception("Ordner "+rootDir+" mit Bildern fehlt!");
            }
            for (String vorlageId : vorlageIds) {
                System.out.println("Wird generiert: " + vorlageId);
                vorlagenPDFGeneratorService.generatePdf(
                        Long.parseLong(vorlageId), OUTPUT_DIR, uploadPath);
            }
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }

        try {
            // move final output folder to shared folder
            Path outputDir = output;
            Path sharedOutputDir = Paths.get(sharedFolder + "/" + rootDir + "/output");

            // delete shared output folder if it exists
            if (Files.exists(sharedOutputDir)) {
                deleteDirectoryRecursively(sharedOutputDir);
            }

            Files.walk(outputDir)
                    .forEach(
                            source -> {
                                try {
                                    Path destination = sharedOutputDir.resolve(outputDir.relativize(source));
                                    Files.createDirectories(destination.getParent());
                                    Files.copy(source, destination);
                                } catch (IOException e) {
                                    throw new UncheckedIOException(e);
                                }
                            });
            // Output-Ordner löschen
            deleteDirectoryRecursively(output);

            return ResponseEntity.status(HttpStatus.OK).build();
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    @PostMapping("/addDupliArtikel")
    public ResponseEntity<?> addDupliArtikel(@RequestBody RollenDruckDupliArtikel artikel) {
        vorlageRollendruckService.addDupliArtikel(artikel);
        return ResponseEntity.ok("Vorlage successfully created with coordinates.");
    }

    @GetMapping("/getAllDupliArtikel")
    public List<RollenDruckDupliArtikel> getAllDupliArtikel() {
        return vorlageRollendruckService.getAllDupliArtikel();
    }

    @DeleteMapping("deleteDupli/{id}")
    public void deleteDupli(@PathVariable Long id){
        vorlageRollendruckService.deleteDupliArtikel(id);
    }


    private void deleteDirectoryRecursively(Path path) throws IOException {
        if (Files.exists(path)) {
            Files.walk(path)
                    .sorted((a, b) -> b.compareTo(a)) // Dateien zuerst, dann Verzeichnisse
                    .forEach(
                            p -> {
                                try {
                                    Files.delete(p);
                                } catch (IOException e) {
                                    throw new UncheckedIOException(e);
                                }
                            });
        }
    }
}
