import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

public class RapihkanUnduhan {
    // Peta ekstensi -> kategori folder tujuan.
    private static final Map<String, String> KATEGORI = Map.of(
            "pdf", "dokumen", "txt", "dokumen", "md", "dokumen",
            "jpg", "gambar", "png", "gambar",
            "json", "data", "csv", "data",
            "py", "skrip");

    public static void main(String[] args) throws IOException {
        Path unduhan = Path.of("unduhan");
        Files.createDirectories(unduhan);

        // Pohon contoh dibuat oleh program agar contoh ini mandiri.
        for (String n : new String[]{"laporan.pdf", "catatan.txt", "tulisan.md",
                "foto-budi.jpg", "icon.png", "penjualan.json", "biaya.csv", "alat.py"}) {
            Files.writeString(unduhan.resolve(n), "contoh", StandardCharsets.UTF_8);
        }

        System.out.println("== sebelum ==");
        tampilkanPohon(unduhan);

        // Kumpulkan dulu seluruh berkas (stream ditutup) baru dipindahkan,
        // agar pohon tidak berubah di tengah penelusuran Files.walk.
        List<Path> daftar;
        try (Stream<Path> berkas = Files.walk(unduhan)) {
            daftar = berkas.filter(Files::isRegularFile).sorted().toList();
        }

        System.out.println("== pindahan ==");
        for (Path p : daftar) {
            String kategori = KATEGORI.get(ekstensi(p));
            if (kategori != null) {
                Path tujuanDir = unduhan.resolve(kategori);
                Files.createDirectories(tujuanDir);
                Files.move(p, tujuanDir.resolve(p.getFileName()));
                System.out.printf("%-16s -> %s/%n", p.getFileName(), kategori);
            }
        }

        System.out.println("== sesudah ==");
        tampilkanPohon(unduhan);
    }

    private static String ekstensi(Path p) {
        String nama = p.getFileName().toString();
        int titik = nama.lastIndexOf('.');
        return titik < 0 ? "" : nama.substring(titik + 1).toLowerCase();
    }

    private static void tampilkanPohon(Path akar) throws IOException {
        try (Stream<Path> semua = Files.walk(akar)) {
            semua.sorted().forEach(p -> {
                int kedalaman = p.equals(akar) ? 0
                        : akar.relativize(p).getNameCount();
                System.out.println("  ".repeat(kedalaman)
                        + (kedalaman == 0 ? "unduhan/" : p.getFileName()));
            });
        }
        System.out.println();
    }
}
