import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.ArrayList;

/**
 * Created by shumailovr on 26.01.15.
 */

@Entity
@Table(name = "`BX-Book-Ratings`")
public class BXRatingModel {

    private BXRatingModelId ratingModelId;
    private int rating;

    @EmbeddedId
    public BXRatingModelId getRatingModelId() {
        return ratingModelId;
    }

    public void setRatingModelId(BXRatingModelId ratingModelId) {
        this.ratingModelId = ratingModelId;
    }

    @Column(name = "`Book-Rating`")
    public int getRating() {
        return rating;
    }

    public void setRating(int rating) {
        this.rating = rating;
    }

    /**
     * Deletes from ratings table ratings, where same user rated book with same title and author, but
     * with different editions (isbns). In current thesis edition does not matter, book content matters
     */
    public static void clearDuplicateRatings() {
        PersistenceManager persistenceManager = new PersistenceManager();
        //Get users
        ArrayList<Integer> userIds = persistenceManager.getBXUserIds();
        //Get every user's ratings and clean them
        for (Integer userId : userIds) {
            ArrayList<BXRatingModel> usersRatings = persistenceManager.getBXRatingsByUser(userId);
            for(BXRatingModel rating : usersRatings) {
                /**
                 * 1) find title and author by isbn
                 * 2) get all isbns with this title and author
                 * 3) if amount of them is > 1, delete current rating, repeat procedure
                 */
                BXBookModel bookModel = persistenceManager.getBXBookByIsbn(rating.getRatingModelId().getIsbn());
                long duplicateRatingsCount = persistenceManager.countBXUserDuplicateRatings(userId, bookModel.getTitle(), bookModel.getAuthor());
                if (duplicateRatingsCount > 1) {
                    persistenceManager.deleteBXRatingByUserAndIsbn(userId, rating.getRatingModelId().getIsbn());
                }
            }
        }
    }

    /**
     * Go through every book and see if we have in books dataset books with same title and author but different edition (isbn).
     * Count how many books excluding current there are with same title and author, if >0 (means there are at least 2 of them),
     * then get first one of those duplicates, get its isbn, reassign to it all ratings that have current isbns. After,
     * delete current book. This is done this way because I am getting list of books and at the same time dynamically
     * modifying the database. This method assures we don't loose precious ratings when clearing duplicate books out.
     * This algorithm is pretty slow and bad but it needs to be done
     */
    public static void reassignDuplicateBooksRatingsAndDeleteBooks() {
        PersistenceManager persistenceManager = new PersistenceManager();

        ArrayList<BXBookModel> bxBooks = persistenceManager.getBXBooks();

        for (BXBookModel bxBook : bxBooks) {
            long duplBooksNum = persistenceManager.countBXBooksByTitleAndAuthorExcludeIsbn(bxBook.getTitle(), bxBook.getAuthor(), bxBook.getIsbn());
            if (duplBooksNum > 0) {
                System.out.println("**********************************************************");
                System.out.println("BOOK THAT IS GOING TO BE DELETED: " + bxBook.getIsbn());
                System.out.println("DUPLICATED BOOKS: " + duplBooksNum);
                String fromIsbn = bxBook.getIsbn();
                ArrayList<BXBookModel> duplBooks = persistenceManager.getBXBooksByTitleAndAuthorExcludeIsbn(bxBook.getTitle(), bxBook.getAuthor(), bxBook.getIsbn());
                String toIsbn = duplBooks.get(0).getIsbn();
                System.out.println("TO ISBN: " + toIsbn);
                //Now go to ratings and change all marked from isbn to isbn
                long updatedRatings = persistenceManager.updateRatingsByIsbn(fromIsbn, toIsbn);
                System.out.println("UPDATED RATINGS: " + updatedRatings);
                long deletedBookIndication = persistenceManager.deleteBXBookByIsbn(bxBook.getIsbn());
                System.out.println("DELETED BOOK INDICATION: " + deletedBookIndication);
                System.out.println("**********************************************************");
            }
        }
    }

}
