package ee.ut.math.tvt2008.salessystem.ui.model;

import java.util.NoSuchElementException;

import org.apache.log4j.Logger;

import ee.ut.math.tvt2008.salessystem.domain.data.StockItem;
import ee.ut.math.tvt2008.salessystem.util.Translations;
import java.math.BigDecimal;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * Stock item table model.
 */
public class StockTableModel extends SalesSystemTableModel<StockItem> {

    private static final long serialVersionUID = 1L;
    private static final Logger log = Logger.getLogger(StockTableModel.class);
    private Session session;

    public StockTableModel() {

        super(new String[]{
                    Translations.getString("main.id"),
                    Translations.getString("main.name"),
                    Translations.getString("main.price"),
                    Translations.getString("main.quantity")
                });
    }

    public StockTableModel(Session session) {
        this();
        this.session = session;
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        if(columnIndex>0)return true;
        else return false;
    }

    @Override
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        StockItem changeable = rows.get(rowIndex);
        try {
            switch (columnIndex) {
                case 1:
                    String name = ((String) value);
                    if(!name.isEmpty())
                    changeable.setName((String) value);
                    break;
                case 2:
                    Double price = Double.parseDouble((String) value);
                    if(price>=0)                    
                    changeable.setPrice(BigDecimal.valueOf(price));
                    break;
                case 3:
                    Integer quantity = Integer.parseInt((String) value);
                    if(quantity>=0)changeable.setQuantity(quantity);
                    break;
                default:
                    return;
            }
            Transaction tx = session.beginTransaction();
            session.save(changeable);
            tx.commit();
            this.fireTableDataChanged();
        } catch (Exception e) {
        }
    }

    @Override
    protected Object getColumnValue(StockItem item, int columnIndex) {
        switch (columnIndex) {
            case 0:
                return item.getId();
            case 1:
                return item.getName();
            case 2:
                return item.getPrice();
            case 3:
                return item.getQuantity();
        }
        throw new IllegalArgumentException("Column index out of range");
    }

    /**
     * Add new stock item to table. If there already is a stock item with
     * same id, then existing item's quantity will be increased.
     * @param stockItem
     */
    public void addItem(final StockItem stockItem) {
        try {
            StockItem item = getItemById(stockItem.getId());
            item.setQuantity(item.getQuantity() + stockItem.getQuantity());
            log.debug("Found existing item " + stockItem.getName() + " increased quantity by " + stockItem.getQuantity());
        } catch (NoSuchElementException e) {
            rows.add(stockItem);
            log.debug("Added " + stockItem.getName() + " quantity of " + stockItem.getQuantity());
        }
        fireTableDataChanged();
    }

    @Override
    public String toString() {
        final StringBuffer buffer = new StringBuffer();

        for (int i = 0; i < headers.length; i++) {
            buffer.append(headers[i] + "\t");
        }
        buffer.append("\n");

        for (final StockItem stockItem : rows) {
            buffer.append(stockItem.getId() + "\t");
            buffer.append(stockItem.getName() + "\t");
            buffer.append(stockItem.getPrice() + "\t");
            buffer.append(stockItem.getQuantity() + "\t");
            buffer.append("\n");
        }
        return buffer.toString();
    }

    @Override
    public void populateWithData(final List<StockItem> data) {
        super.populateWithData(data);
    }
}
