/**
 * @file warehouse_picking_opt_debug.cpp
 * @author Jan Holáň, xholan11 (xholan11@vutbr.cz)
 * @brief translated with gcc version 12.2.1
 * @version 0.1
 * @date 2023-05-01
 * 
 * @copyright Copyright (c) 2023
 * 
 */

#include "warehouse_picking_opt_debug.h"

void debugCustomerMultimap(multimap<int, Customer, greater<int>> cust_mult)
{
    int current_volume = -50;
    for (auto cust : cust_mult)
    {
        if (cust.first != current_volume)
        {
            current_volume = cust.first;
            cout << current_volume << " --->" << endl;
        }
        debugCustomer(cust.second);
        cout << endl;
    }
}

void debugCustomer(Customer cust)
{
    cout << "\tvolume: " << cust.getTotalVolume() << ", weight: " << cust.getTotalWeight() << endl;

    for (auto item : cust.item_vect)
    {
        cout << "\t"
             << "Product: " << item.Product << endl;
        cout << "\t"
             << "Customer ID: " << item.Customer << endl;
        cout << "\t"
             << "Customer Qty: " << item.Qty << endl;
        cout << "\t"
             << "Volume: " << item.getVolume() << endl;
    }

    cout << "\t"
         << " ==== Full Boxes: " << cust.getBoxesDecomp().size();
    cout << "\t"
         << " ==== Single Boxes: " << 0;
}

void debugCartsCustomers(list<Cart> cart_list)
{
    float total_volume = 0.0f;
    float total_weight = 0.0f;

    cout << cart_list.size() << " CARTS" << endl;
    int i = 1;
    for (auto cart : cart_list)
    {
        cout << "  |--CART " << i++ << endl;
        for (auto cust : cart.getCustomerVector())
        {
            bool printed = false;
            for (auto item : cust.item_vect)
            {
                if (!printed)
                {
                    printed = true;
                    cout << "  |   |--CUSTOMER " << item.Customer << endl;
                }

                cout << "  |   |    |--ITEM " << item.Product << endl;
                cout << "  |   |    |   |--Qty: " << item.Qty << endl;
                cout << "  |   |    |   |--Volume: " << item.getVolume() << endl;
                cout << "  |   |    |   |--Weight: " << item.getWeight() << endl;
            }
        }
    }
}

void debugCartsOItems(list<Cart> cart_list, bool additional_spec)
{
    float total_volume = 0.0f;
    float total_weight = 0.0f;

    cout << cart_list.size() << " CARTS" << endl;
    int i = 1;
    for (auto cart : cart_list)
    {
        cout << "  |--CART " << i++ << endl;
        cout << "  |    Total items: " << cart.getItemVector().size() << endl;
        for (auto cust : cart.getCustomerVector())
        {
            for (auto item : cust.item_vect)
            {
                cout << "  |   |--ITEM " << item.Product << endl;
                if (additional_spec) // print additional specification
                {
                    cout << "  |   |    |--Qty: " << item.Qty << endl;
                    cout << "  |   |    |--Volume: " << item.getVolume() << endl;
                    cout << "  |   |    |   |--Weight: " << item.getWeight() << endl;
                }
            }
        }
    }
}

void debugCartsBoxes(list<Cart> cart_list)
{
    float total_volume = 0.0f;
    float total_weight = 0.0f;
    float total_boxes = 0;
    int total_oitems = 0;
    cout << cart_list.size() << " CARTS" << endl;
    int i = 1;

    for (auto cart : cart_list)
    {
        int full = 0, one = 0, all = 0;
        for (auto shelf : cart.getCartShelvesVector())
        {
            full += shelf.getBoxes()->full_box_vect.size();
            one += shelf.getBoxes()->one_item_box_vect.size();
        }
        total_boxes += full + one;
        total_oitems += cart.getCartOItemVector().size();
        cout << "   |--CART " << i++ << endl;
        cout << "   |    Total full boxes: " << full << endl;
        cout << "   |    Total full one: " << one << endl;
        cout << "   |    Cart used space: " << ((9 * 29400 ) - cart.getCartFreeSpace())/(9 * 29400 ) << endl;
        cout << "   |    Total estimated walk distance: " << cart.getEstimatedWalkedDistance() << endl;
        cout << "   |    Total customers: " << cart.getCustomerVector().size() << endl;
        cout << "   |    Total items: " << cart.getCartOItemVector().size() << endl;
    }

    cout << "TOTAL BOXES: " << total_boxes << endl;
    cout << "TOTAL OITEMS: " << total_oitems << endl;
}

void debugCustomerBoxItems(vector<BoxItem> boxitem_vect)
{
    cout << "***** " << boxitem_vect[0].order_item.Customer << " *****" << endl;
    for (auto &item : boxitem_vect)
    {
        cout << "BOX_ITEM===> " << item.order_item.Product << endl;
        cout << "             " << (item.item_specification.Unit == ItemSpecification::Type::Unit ? "Unit" : "Carton") << endl;
        cout << "             " << item.getCountOfUnits() << endl;
    }
    cout << endl;
}

void debugCustomerBoxes(vector<Box> box_vect)
{
    cout << "***** " << box_vect[0].getItemsInTheBox().begin()->second.order_item.Customer << " *****" << endl;

    for (int i = 0; i < box_vect.size(); i++)
    {
        cout << "|--> "
             << "box " << i << "; type: " << box_vect[i].name << "; used: " << box_vect[i].getUsedCapacity() << ", free: " << box_vect[i].getFreeCapacity() << endl;
        for (auto boxit : box_vect[i].getItemsInTheBox())
        {
            cout << "    |BOX_ITEM===> " << boxit.second.order_item.Product << endl;
            cout << "                  " << (boxit.second.item_specification.Unit == ItemSpecification::Type::Unit ? "Unit" : "Carton") << endl;
            cout << "                  " << boxit.second.getCountOfUnits() << endl;
        }
    }

    cout << endl;
}
