package de.antco.projekt;

import de.antco.projekt.model.Person;
import de.antco.projekt.model.ServiceItem;
import de.antco.projekt.model.Vehicle;
import de.antco.projekt.model.WorkOrderDetails;
import de.antco.projekt.model.WorkOrderItem;
import de.antco.projekt.service.WorkshopService;

import java.sql.SQLException;
import java.util.*;

public class ConsoleUi {

    private final WorkshopService service;
    private final Scanner scanner = new Scanner(System.in);

    public ConsoleUi(WorkshopService service) {
        this.service = service;
    }

    public void start() {
        boolean running = true;

        while (running) {
            showMenu();
            String choice = scanner.nextLine().trim();

            try {
                switch (choice) {
                    case "1" -> addPerson();
                    case "2" -> showPersons();
                    case "3" -> addVehicle();
                    case "4" -> showVehiclesOfPerson();
                    case "5" -> createWorkOrder();
                    case "6" -> showWorkOrders();
                    case "0" -> running = false;
                    default -> System.out.println("Ungültige Eingabe.");
                }
            } catch (SQLException e) {
                System.out.println("Ein Fehler ist aufgetreten: " + e.getMessage());
            }
        }

        System.out.println("Programm beendet.");
    }

    private void showMenu() {
        System.out.println("\n=== Werkstatt Menü ===");
        System.out.println("1) Kunde anlegen");
        System.out.println("2) Kunden anzeigen");
        System.out.println("3) Fahrzeug anlegen");
        System.out.println("4) Fahrzeuge einer Person anzeigen");
        System.out.println("5) Werkstattvorgang anlegen");
        System.out.println("6) Vorgänge anzeigen");
        System.out.println("0) Beenden");
        System.out.print("Auswahl: ");
    }

    private int readInt(String text) {
        while (true) {
            System.out.print(text);
            String input = scanner.nextLine();

            try {
                return Integer.parseInt(input.trim());
            } catch (NumberFormatException e) {
                System.out.println("Bitte eine gültige Zahl eingeben.");
            }
        }
    }

    private String readNonEmpty(String text) {
        while (true) {
            System.out.print(text);
            String value = scanner.nextLine().trim();

            if (!value.isEmpty()) {
                return value;
            }

            System.out.println("Eingabe darf nicht leer sein.");
        }
    }

    private String readValidName(String text) {
        while (true) {
            String name = readNonEmpty(text);

            if (name.matches("[a-zA-ZäöüÄÖÜß ]+")) {
                return name;
            }

            System.out.println("Der Name darf nur Buchstaben enthalten.");
        }
    }

    private String readPhoneNumber(String text) {
        while (true) {
            System.out.print(text);
            String phone = scanner.nextLine().trim();

            if (phone.matches("\\d+")) {
                return phone;
            }

            System.out.println("Telefonnummer darf nur Zahlen enthalten.");
        }
    }

    private void addPerson() throws SQLException {
        String name = readValidName("Name: ");
        String phone = readPhoneNumber("Telefonnummer: ");

        Person person = service.createPerson(name, phone);
        System.out.println("Kunde gespeichert (ID: " + person.getId() + ")");
    }

    private void showPersons() throws SQLException {
        List<Person> persons = service.listPersons();

        if (persons.isEmpty()) {
            System.out.println("Keine Kunden vorhanden.");
            return;
        }

        System.out.println("\n--- Kundenliste ---");
        persons.forEach(System.out::println);
    }

    private void addVehicle() throws SQLException {
        int personId = readInt("Personen-ID: ");
        Person person = service.findPerson(personId);

        if (person == null) {
            System.out.println("Person wurde nicht gefunden.");
            return;
        }

        String brand = readNonEmpty("Hersteller: ");
        String model = readNonEmpty("Modell: ");
        String plate = readNonEmpty("Kennzeichen: ");

        Vehicle vehicle = service.createVehicle(personId, brand, model, plate);
        System.out.println("Fahrzeug angelegt (ID: " + vehicle.getId() + ")");
    }

    private void showVehiclesOfPerson() throws SQLException {
        int personId = readInt("Personen-ID: ");
        Person person = service.findPerson(personId);

        if (person == null) {
            System.out.println("Person nicht gefunden.");
            return;
        }

        List<Vehicle> vehicles = service.listVehicles(personId);

        System.out.println("Fahrzeuge von " + person.getName() + ":");
        if (vehicles.isEmpty()) {
            System.out.println("Keine Fahrzeuge vorhanden.");
        } else {
            vehicles.forEach(System.out::println);
        }
    }

    private void createWorkOrder() throws SQLException {
        int vehicleId = readInt("Fahrzeug-ID: ");
        Vehicle vehicle = service.findVehicle(vehicleId);

        if (vehicle == null) {
            System.out.println("Fahrzeug nicht gefunden.");
            return;
        }

        String note = readNonEmpty("Notiz: ");

        List<ServiceItem> catalog = service.listServiceItems();
        Map<Integer, Integer> selectedItems = new LinkedHashMap<>();

        while (true) {
            System.out.println("\n--- Service-Katalog ---");
            catalog.forEach(System.out::println);

            System.out.print("Service-ID (leer = fertig): ");
            String input = scanner.nextLine().trim();

            if (input.isEmpty()) {
                break;
            }

            int serviceId;
            try {
                serviceId = Integer.parseInt(input);
            } catch (NumberFormatException e) {
                System.out.println("Bitte eine gültige ID eingeben.");
                continue;
            }

            ServiceItem item = catalog.stream()
                    .filter(s -> s.getId() == serviceId)
                    .findFirst()
                    .orElse(null);

            if (item == null) {
                System.out.println("Service nicht gefunden.");
                continue;
            }

            int qty = readInt("Menge: ");
            if (qty <= 0) {
                System.out.println("Menge muss größer als 0 sein.");
                continue;
            }

            selectedItems.merge(serviceId, qty, Integer::sum);
        }

        if (selectedItems.isEmpty()) {
            System.out.println("Keine Positionen ausgewählt.");
            return;
        }

        int orderId = service.createWorkOrder(vehicleId, note, selectedItems);
        System.out.println("Vorgang wurde angelegt (ID: " + orderId + ")");
    }

    private void showWorkOrders() throws SQLException {
        List<WorkOrderDetails> orders = service.listWorkOrders();

        if (orders.isEmpty()) {
            System.out.println("Keine Vorgänge vorhanden.");
            return;
        }

        for (WorkOrderDetails order : orders) {
            System.out.println("\n--- Vorgang " + order.getOrderId() + " ---");
            System.out.println("Kunde: " + order.getPersonName());
            System.out.println("Fahrzeug: " + order.getVehicleText());
            System.out.println("Datum: " + order.getCreatedAt());

            if (order.getNote() != null && !order.getNote().isBlank()) {
                System.out.println("Notiz: " + order.getNote());
            }

            for (WorkOrderItem item : order.getItems()) {
                System.out.println("  - " + item.getServiceItem().getTitle() +
                        " x" + item.getQuantity() +
                        " = " + item.getTotalPrice() + " €");
            }

            System.out.println("Gesamtsumme: " + order.getTotal() + " €");
        }
    }
}