package edu.kit.prog1314.shop;

import edu.kit.prog1314.shop.util.Graph;
import edu.kit.prog1314.shop.util.List;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * A class representing a shop.
 * 
 * @author Janis Schötterl-Glausch
 * @author Raphael von der Grün
 * @version 2
 */
public class Shop {
    private List<Customer> customers = new List<>();
    private List<Order> orders = new List<>();
    private List<Article> articles = new List<>();

    /**
     * Creates a new empty Shop.
     */
    public Shop() { }

    /**
     * Returns the orders of this shop.
     * 
     * @return The orders.
     */
    public List<Order> getOrders() {
        return orders;
    }

    /**
     * Returns the articles of this shop.
     * 
     * @return The articles.
     */
    public List<Article> getArticles() {
        return articles;
    }

    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        String sep = System.lineSeparator();
        for (Customer cust : customers) {
            res.append(cust).append("---").append(sep);
        }
        if (res.length() > 3) {
            res.delete(res.length() - 4, res.length());
        }
        return res.toString();
    }

    private void importFile(String path) {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(path));
            for (String line = in.readLine(); line != null; line = in.readLine()) {
                importLine(line);
            }
        } catch (FileNotFoundException e) {
            System.err.println("Cannot find file: " + e.getMessage());
            System.exit(1);
        } catch (IOException e) {
            System.err.println("There was a problem accesing a file: " + e.getMessage());
            System.exit(1);
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                System.err.println("There was a problem closing a file: " + e.getMessage());
                System.exit(1);
            }
        }
    }

    private void importLine(String line) {
        String[] split = line.split(";");
        if (split.length != 5) {
            System.err.println("Unexpected column count in input file.");
            System.exit(1);
        }

        Customer cust = customers.addUnique(new Customer(split[0], split[1]));
        Article article = articles.addUnique(new Article(split[3], parsePrice(split[4])));
        Order order = orders.addUnique(new Order(split[2]));

        order.getArticles().add(article);
        cust.getOrders().addUnique(order);
    }

    private static int parsePrice(String s) {
        if (!s.matches("\\d+([.,]\\d+)?")) {
            System.err.println("Malformed price field: " + s);
            System.exit(1);
        }
        String[] parts = s.replace(".", ",").split(",");
        int price = Integer.parseInt(parts[0]) * 100;
        if (parts.length > 1) {
            double centMagnitude = Math.pow(10, 2 - parts[1].length());
            price += Math.round(centMagnitude * Integer.parseInt(parts[1]));
        }
        return price;
    }

    /**
     * The entry point; reads a file and outputs its representation.
     * 
     * @param args
     *            The arguments; must be a single file path.
     */
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Supply one valid file path");
            System.exit(1);
        }

        Shop shop = new Shop();
        shop.importFile(args[0]);

        Graph graph = new Graph(shop);

        System.out.print(shop);
        System.out.println("***");
        for (Article article : shop.getArticles()) {
            Graph.Edge max = graph.neighbourhood(article).getMaximum();
            String other = "";
            if (max != null) {
                other = " " + (max.getFirst().equals(article) ? max.getSecond() : max.getFirst());
            }
            System.out.println(article + ":" + other);
        }
    }
}
