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

public class TinyTextEditor {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("File name (default notes.txt): ");
        String fileName = scanner.nextLine().trim();
        if (fileName.isEmpty()) {
            fileName = "notes.txt";
        }

        EditorState editor = new EditorState(Path.of(fileName));
        editor.load();

        System.out.println("Commands: show, append, edit, delete, save, quit");

        while (true) {
            System.out.print("> ");
            String command = scanner.nextLine().trim().toLowerCase();

            switch (command) {
                case "show":
                    editor.show();
                    break;
                case "append":
                    System.out.print("Text: ");
                    editor.append(scanner.nextLine());
                    break;
                case "edit":
                    System.out.print("Line number: ");
                    int editLine = parseLineNumber(scanner.nextLine());
                    if (editLine > 0) {
                        System.out.print("New text: ");
                        editor.edit(editLine, scanner.nextLine());
                    }
                    break;
                case "delete":
                    System.out.print("Line number: ");
                    int deleteLine = parseLineNumber(scanner.nextLine());
                    if (deleteLine > 0) {
                        editor.delete(deleteLine);
                    }
                    break;
                case "save":
                    editor.save();
                    break;
                case "quit":
                    if (editor.isDirty()) {
                        System.out.print("Unsaved changes. Type quit! to force: ");
                        String confirm = scanner.nextLine().trim();
                        if (!"quit!".equals(confirm)) {
                            break;
                        }
                    }
                    System.out.println("Bye.");
                    return;
                default:
                    System.out.println("Use: show, append, edit, delete, save, quit");
            }
        }
    }

    private static int parseLineNumber(String raw) {
        try {
            return Integer.parseInt(raw.trim());
        } catch (NumberFormatException e) {
            System.out.println("Please enter a number.");
            return -1;
        }
    }

    private static class EditorState {
        private final Path file;
        private final List<String> lines = new ArrayList<>();
        private boolean dirty = false;

        private EditorState(Path file) {
            this.file = file;
        }

        private void load() {
            if (!Files.exists(file)) {
                System.out.println("New file: " + file);
                return;
            }
            try {
                lines.addAll(Files.readAllLines(file));
                System.out.println("Loaded " + lines.size() + " line(s).");
            } catch (IOException e) {
                System.out.println("Could not read file. Starting empty.");
            }
        }

        private void show() {
            if (lines.isEmpty()) {
                System.out.println("(empty)");
                return;
            }
            for (int i = 0; i < lines.size(); i++) {
                System.out.printf("%3d | %s%n", i + 1, lines.get(i));
            }
        }

        private void append(String text) {
            lines.add(text);
            dirty = true;
            System.out.println("Appended line " + lines.size() + ".");
        }

        private void edit(int lineNumber, String newText) {
            int index = lineNumber - 1;
            if (index < 0 || index >= lines.size()) {
                System.out.println("Line out of range.");
                return;
            }
            lines.set(index, newText);
            dirty = true;
            System.out.println("Line updated.");
        }

        private void delete(int lineNumber) {
            int index = lineNumber - 1;
            if (index < 0 || index >= lines.size()) {
                System.out.println("Line out of range.");
                return;
            }
            lines.remove(index);
            dirty = true;
            System.out.println("Line deleted.");
        }

        private void save() {
            try {
                Files.write(file, lines);
                dirty = false;
                System.out.println("Saved to " + file + ".");
            } catch (IOException e) {
                System.out.println("Save failed.");
            }
        }

        private boolean isDirty() {
            return dirty;
        }
    }
}
