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

/**
 * Created by shumailovr on 30.01.15.
 */

@Entity
@Table(name = "training_euclidean_distances")
public class TrainingEuclideanDistanceModel {

    private TrainingEuclideanDistanceId trainingEuclideanDistanceId;
    private double distance;

    public TrainingEuclideanDistanceModel() {
    }

    public TrainingEuclideanDistanceModel(TrainingEuclideanDistanceId trainingEuclideanDistanceId, double distance) {
        this.trainingEuclideanDistanceId = trainingEuclideanDistanceId;
        this.distance = distance;
    }

    @EmbeddedId
    public TrainingEuclideanDistanceId getTrainingEuclideanDistanceId() {
        return trainingEuclideanDistanceId;
    }

    public void setTrainingEuclideanDistanceId(TrainingEuclideanDistanceId trainingEuclideanDistanceId) {
        this.trainingEuclideanDistanceId = trainingEuclideanDistanceId;
    }

    @Column(name = "distance")
    public double getDistance() {
        return distance;
    }

    public void setDistance(double distance) {
        this.distance = distance;
    }

    /**
     * Finds and inserts all euclidean distances between every book (where they have in common users that rated them) in the library
     * This is for BX (Book-Crossing) dataset!
     */
    public static void findAndInsertBXEuclideanDistances() {
        PersistenceManager persistenceManager = new PersistenceManager();

        //Votab koik isbnd
        ArrayList<String> isbns = persistenceManager.getBXIsbns();
        System.out.println("ISBNS SIZE " + isbns.size());

        //eukleidese kauguste leidmine raamat raamatu jarel
        for (String currentBookIsbn : isbns) {
            ArrayList<BXRatingModel> currentBookRatings = persistenceManager.getBXRatingsByISBN(currentBookIsbn);
            ArrayList<String> corresBooksIsbns = persistenceManager.getBXCorrISBNs(currentBookIsbn);
            for (String corresBookIsbn : corresBooksIsbns) {
                if ((persistenceManager.getTrainingEuclideanDistByIsbns(corresBookIsbn, currentBookIsbn) != null)
                        || (currentBookIsbn.equals(corresBookIsbn))) {
                    continue;
                }
                ArrayList<BXRatingModel> corresBookRatings = persistenceManager.getBXRatingsByISBN(corresBookIsbn);
                double ratingsSum = 0;
                for (BXRatingModel currentBookRating : currentBookRatings) {
                    for (BXRatingModel corresBookRating : corresBookRatings) {
                        if (currentBookRating.getRatingModelId().getUserId() == corresBookRating.getRatingModelId().getUserId()) {
                            double dist = Math.pow((Math.abs(currentBookRating.getRating() - corresBookRating.getRating())), 2);
                            ratingsSum += dist;
                        }
                    }
                }
                double averDist = Math.pow(ratingsSum, 0.5);
                //Here save the distance for those two books
                TrainingEuclideanDistanceId trainingEuclideanDistanceId = new TrainingEuclideanDistanceId(currentBookIsbn, corresBookIsbn);
                TrainingEuclideanDistanceModel trainingEuclideanDistanceModel = new TrainingEuclideanDistanceModel(trainingEuclideanDistanceId, averDist);
                persistenceManager.saveTrainingEuclideanDistance(trainingEuclideanDistanceModel);
            }
        }
        persistenceManager.close();
    }
}
