package net.tinsae;

import java.util.Scanner;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class Delegator {

    private final Client client;
    private final Scanner sc = new Scanner(System.in);

    public Delegator(String path, String table) {
        client = new Client(path, table);
    }

    public void executeCommand(String command) {
        switch (command) {
            case "delete" -> delegateDelete();
            case "insert" -> delegateInsert();
            case "read" -> delegateRead();
            case "update" -> delegateUpdate();
            default -> System.err.println("Unknown command, please repeat");
        }
    }

    private void delegateDelete() {
        try {
            System.out.print("ID of the item you want to delete: ");
            int id = sc.nextInt();
            // consume next line, safety
            sc.nextLine(); 
            int response = client.deleteItem(id);
            System.out.println("Command executed with response code " + response);
        } catch (Exception e) {
            System.err.println("Error in executing delete command: " + e.getMessage());
        }
    }

    private void delegateInsert() {
        try {
            System.out.print("Name: ");
            String name = sc.nextLine().strip();

            System.out.print("Description: ");
            String description = sc.nextLine();

            System.out.print("Price: ");
            float price = sc.nextFloat();
            // consume newline, is just safety
            sc.nextLine();

            int response = client.postItem(makeJson(name, description, price));
            System.out.println("Command executed with response code " + response);

        } catch (Exception e) {
            System.err.println("Error in executing insert command: " + e.getMessage());
        }
    }

    private String makeJson(String name, String desc, float price) {
        return String.format("""
            {
              "name": "%s",
              "description": "%s",
              "price": %s
            }
            """, name, desc, price);
    }

    private void delegateRead() {
        try {
            System.out.print("Read All or One? (A/O): ");
            String input = sc.nextLine();

            if (input.equalsIgnoreCase("A")) {
                client.getItems();
                return;
            }

            System.out.print("Enter ID: ");
            int id = sc.nextInt();
            // to be safe
            sc.nextLine();
            client.getItem(id);

        } catch (Exception e) {
            System.err.println("Error in executing read command: " + e.getMessage());
        }
    }

    private void delegateUpdate() {
        try {
            System.out.print("Enter ID: ");
            int id = sc.nextInt();
            // consume next line
            sc.nextLine();

            // get old values
            String response = client.getItem(id).body();
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode node = (ObjectNode) mapper.readTree(response);

            while (true) {
                System.out.println("Which field do you want to update? (name, description, price, done)");
                String field = sc.nextLine().trim().toLowerCase();

                if (field.equals("done")) {
                    break;
                }

                if(!node.has(field)){
                    System.out.println(" no "+field+" field in database. please choose apropriately");
                    continue;
                }

                System.out.println("New value for "+field+": ");
                String value = sc.nextLine().trim();

                if (field.equals("price")) {
                    node.put(field, Double.parseDouble(value));
                } else {
                    node.put(field, value);
                }
            }

        String updatedJson = mapper.writeValueAsString(node);
        client.putItem(id, updatedJson);

        System.out.println("Update successful!");

        } catch (Exception e) {
            System.err.println("Error in executing update command: " + e.getMessage());
        }
    }
}