package at.oad.trec.controller;

import at.oad.trec.model.*;
import java.awt.event.ActionEvent;
import javax.swing.JPanel;
import at.oad.trec.view.EditHotelView;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.SpinnerModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.Document;


public class EditHotelViewController extends ViewController {
    private final EditHotelView view;
    private Document name;
    private Document address;
    private SpinnerModel new_rating;
    private DefaultTableModel activities;
    private DefaultTableModel ratings;
    private DefaultComboBoxModel dropdown_activity;
    private DefaultComboBoxModel dropdown_destination;
    
    private List<Destination> dest_db;
    private List<Activity> activities_db;
    
    private Hotel hotel;
    private ArrayList<String> new_activity_names = new ArrayList<>();
    private ArrayList<String> activities_to_remove = new ArrayList<>();
    private ArrayList<Integer> new_activity_ratings = new ArrayList<>();
    private ArrayList<Integer> reviews_to_remove = new ArrayList<>();
    
    
    
    public EditHotelViewController(Hotel selected_hotel) {

        view = new EditHotelView(this);
        loadModel();
        hotel = selected_hotel;
        getListsFromDB();
        getInputFromDB();
    }
    
    @Override
    public String getTitle() {
        return "Edit Hotel";
    }
    
    @Override
    JPanel getView() {
        return view;
    }
    
    @Override
    void updateModel() {}
    
    private void loadModel() {
        name = view.getTextName();
        address = view.getTextAddress();
        new_rating = view.getSpinnerRating();
        activities = (DefaultTableModel)view.getTableActivities();
        ratings = (DefaultTableModel)view.getTableRatings();
        dropdown_activity = (DefaultComboBoxModel)view.getDropdownActivity();
        dropdown_destination = (DefaultComboBoxModel)view.getDropdownDestination();
    }
    
    private void getListsFromDB()
    {
        dest_db = DatabaseManager.INSTANCE.getAllItems("Destination");
        activities_db = DatabaseManager.INSTANCE.getAllItems("Activity");
        dropdown_destination.addElement(hotel.getDestination());
        dest_db.forEach(it -> dropdown_destination.addElement(it.getName()));
        activities_db.forEach(it -> dropdown_activity.addElement(it.getName()));
    }
        
    private void getInputFromDB()
    {
        
        stringToDoc(name, hotel.getName());
        stringToDoc(address, hotel.getAddress());
        hotel.getActivities().forEach(it->activities.addRow(new Object[] {false, it.getActivity().getName(), it.getRating()}));
        hotel.getUserReviews().forEach(it->ratings.addRow(new Object[] {false, it.getID(), it.getDate().toString(), it.getUsername(), it.getComment()}));
           
    }
    
    private void saveToDB() {
    
        Destination dest = new Destination();
        hotel.setName(docToString(name));
        hotel.setAddress(docToString(address));

        
        String selected_dest = (String) dropdown_destination.getSelectedItem();

        for (Destination it : dest_db)
        {
            if (selected_dest.contains(it.getName()))
            {
                dest = it;
                break;
            }
        }
        hotel.setDestination(dest);
        
        //add new activities
        
        for(int it = 0; it < new_activity_names.size(); it++)
        {
            for(Activity inner_it : activities_db)
            {
                if (new_activity_names.get(it).contains(inner_it.getName()))
                {
                    HotelActivity act_to_add = new HotelActivity();
                    act_to_add.setActivity(inner_it);
                    act_to_add.setRating(new_activity_ratings.get(it));
                    act_to_add.setHotel(hotel);
                    hotel.getActivities().add(act_to_add);
                    DatabaseManager.INSTANCE.add(act_to_add);
                    
                }
            }
        }
        
        //delete removed activities
        for(String outer_it : activities_to_remove)
        {
            Iterator<HotelActivity> inner_it = hotel.getActivities().iterator();
            HotelActivity object;
            
            while(inner_it.hasNext())
            {
                object = inner_it.next();
                
                if(outer_it.contains(object.getActivity().getName()))
                {
                    hotel.getActivities().remove(object);
                    DatabaseManager.INSTANCE.delete(object);
                    break;
                }
            }
        }
        
        //delete removed reviews
        for(Integer outer_it : reviews_to_remove)
        {
            HotelRating object;
            Iterator<HotelRating> inner_it = hotel.getUserReviews().iterator();
            while(inner_it.hasNext())
            {
                object = inner_it.next();
                
                if(outer_it == object.getID())
                {
                    object.getSetRatings().forEach(it->DatabaseManager.INSTANCE.delete(it));     
                    hotel.getUserReviews().remove(object);
                    DatabaseManager.INSTANCE.delete(object);
                    break;
                }
            }
        }
            DatabaseManager.INSTANCE.persist();
        JOptionPane.showMessageDialog(null, "Changes were saved!");
        
        
    }
    
            
    @Override
    public void actionPerformed(ActionEvent e) {
        
        Set<Integer> temp = new HashSet();
        
        switch (e.getActionCommand()) {
            case "back":
                RootController.INSTANCE.popController();
                break;
            case "reset":
                activities.setRowCount(0);
                ratings.setRowCount(0);
                getInputFromDB();     
                break;
            case "save":
                if(docNotEmpty(name) && docNotEmpty(address))
                {
                    saveToDB();
                    
                    RootController.INSTANCE.popController();
                }
                else
                    JOptionPane.showMessageDialog(null, "Please fill out all textfields!");
                break;
            case "removeActivity":
                temp.clear();
                temp = getSelectedItems(activities, 0);
                temp.forEach(it->activities_to_remove.add(activities.getValueAt(it, 1).toString()));
                deleteSelectedItems(activities, 0);
                break;
            case "removeRating":
                temp.clear();
                temp = getSelectedItems(ratings, 0);
                temp.forEach(it->reviews_to_remove.add((Integer)ratings.getValueAt(it, 1)));
                deleteSelectedItems(ratings, 0);
                break;
            case "insertActivity":
                new_activity_names.add(dropdown_activity.getSelectedItem().toString());
                new_activity_ratings.add((Integer) new_rating.getValue());
                activities.addRow(new Object[]{false, dropdown_activity.getSelectedItem(), new_rating.getValue()});
            default:
                break;
        }
    }
}