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 TuiWordProcessor {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("File name (default draft.txt): ");
        String fileName = scanner.nextLine().trim();
        if (fileName.isEmpty()) {
            fileName = "draft.txt";
        }

        Document doc = new Document(Path.of(fileName));
        doc.load();

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

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

            switch (command) {
                case "show":
                    doc.show();
                    break;
                case "append":
                    System.out.print("Text: ");
                    doc.append(scanner.nextLine());
                    break;
                case "insert":
                    System.out.print("Line number: ");
                    int insertAt = parseLine(scanner.nextLine());
                    if (insertAt > 0) {
                        System.out.print("Text: ");
                        doc.insert(insertAt, scanner.nextLine());
                    }
                    break;
                case "edit":
                    System.out.print("Line number: ");
                    int editAt = parseLine(scanner.nextLine());
                    if (editAt > 0) {
                        System.out.print("New text: ");
                        doc.edit(editAt, scanner.nextLine());
                    }
                    break;
                case "delete":
                    System.out.print("Line number: ");
                    int deleteAt = parseLine(scanner.nextLine());
                    if (deleteAt > 0) {
                        doc.delete(deleteAt);
                    }
                    break;
                case "stats":
                    doc.stats();
                    break;
                case "save":
                    doc.save();
                    break;
                case "quit":
                    if (doc.dirty) {
                        System.out.print("Unsaved changes. Type quit! to force: ");
                        if (!"quit!".equals(scanner.nextLine().trim())) {
                            break;
                        }
                    }
                    return;
                default:
                    System.out.println("Use: show, append, insert, edit, delete, stats, save, quit");
            }
        }
    }

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

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

        private Document(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 load file.");
            }
        }

        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 insert(int lineNo, String text) {
            int index = lineNo - 1;
            if (index < 0 || index > lines.size()) {
                System.out.println("Line out of range.");
                return;
            }
            lines.add(index, text);
            dirty = true;
            System.out.println("Inserted.");
        }

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

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

        private void stats() {
            int wordCount = 0;
            for (String line : lines) {
                String trimmed = line.trim();
                if (!trimmed.isEmpty()) {
                    wordCount += trimmed.split("\\s+").length;
                }
            }
            System.out.println("Lines: " + lines.size() + ", Words: " + wordCount);
        }

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