import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/** Guarda las canciones en un archivo CSV con encabezado, en UTF-8. */
public class CsvSongRepository implements SongRepository {
    static final String HEADER = "title,artist,seconds";

    private final Path file;

    public CsvSongRepository(Path file) {
        this.file = file;
    }

    @Override
    public void save(List<Song> songs) throws IOException {
        List<String> lines = new ArrayList<>();
        lines.add(HEADER);
        for (Song s : songs) {
            lines.add(Csv.join(List.of(s.title(), s.artist(), String.valueOf(s.seconds()))));
        }
        Files.write(file, lines, StandardCharsets.UTF_8);
    }

    @Override
    public List<Song> load() throws IOException {
        List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
        if (lines.isEmpty() || !lines.get(0).equals(HEADER)) {
            throw new MalformedCsvException(1, "se esperaba el encabezado " + HEADER);
        }
        List<Song> songs = new ArrayList<>();
        for (int i = 1; i < lines.size(); i++) {
            if (!lines.get(i).isBlank()) {
                songs.add(parse(lines.get(i), i + 1));
            }
        }
        return songs;
    }

    private static Song parse(String line, int number) throws MalformedCsvException {
        try {
            List<String> f = Csv.split(line);
            if (f.size() != 3) {
                throw new MalformedCsvException(number, "se esperaban 3 campos y hay " + f.size());
            }
            return new Song(f.get(0), f.get(1), Integer.parseInt(f.get(2).strip()));
        } catch (NumberFormatException e) {
            throw new MalformedCsvException(number, "la duración no es un número");
        } catch (IllegalArgumentException e) {
            // Lo que rechaza Csv.split (comillas) o el constructor de Song.
            throw new MalformedCsvException(number, e.getMessage());
        }
    }
}
