package com.moviesdb;

import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Alert.AlertType;

import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;

import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.fxml.FXMLLoader;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
//For reading properties from .properties file


public class BrowserController extends Controller {
    @FXML
    AnchorPane browserPane;
    @FXML
    MenuItem addMenu;
    @FXML
    FlowPane moviesGrid;
    @FXML
    ScrollPane scrollPane;
    @FXML
    AnchorPane detailsPane;
    @FXML
    TextFlow detailsContent;
    @FXML
    //AnchorPane detailsPicPane;
    ImageView detailsPicPane;
    @FXML
    AnchorPane filterPane;
    @FXML
    Label button;
    @FXML
    Label logInButton;
    @FXML
    Button logInButton2;
    @FXML
    MenuBar menuPane;
    @FXML
    MenuItem reloadMenu;

    @FXML
    Label deleteMovieButton;
    @FXML
    Label editMovieButton;

    @FXML
            TextField userTextBox;
    @FXML
            TextField passTextBox;
    @FXML
            TextFlow errorTextBox;
    @FXML
            Label userLabel;

    Map<Label, Movie> map;
    Label[] labelsMovies;
    Movie[] movies;
    Movie my_movie;
    public DataBaseConnector my_connector;
    ConnectionParams workParams;

    double xOffset;
    double yOffset;

    public void initialize(Stage primaryStage){
        prepare();
        stage = primaryStage;

        menuPane.setOnMousePressed(new EventHandler<javafx.scene.input.MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                xOffset = primaryStage.getX() - event.getScreenX();
                yOffset = primaryStage.getY() - event.getScreenY();
            }
        });

        menuPane.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                primaryStage.setX(event.getScreenX() + xOffset);
                primaryStage.setY(event.getScreenY() + yOffset);
            }
        });


        workParams = new ConnectionParams("connection.properties");
        if (!workParams.initilized())
            //TODO this is temporal handler
            System.out.println(workParams.getInitilizeErrCause().toString());
        else {
            my_connector = new DataBaseConnector();
            my_connector.initConnection(workParams);
        }

        System.out.println(my_connector.granted("USAGE"));
        System.out.println(my_connector.granted("INSERT"));
        System.out.println(my_connector.granted("UPDATE"));
        System.out.println(my_connector.granted("DELETE"));


    }

    public void loadPosters()
    {
        //detailsPane.setMinWidth(300);
        //get movies array
        if (my_connector.initialized() & (my_connector.granted("USAGE") || my_connector.granted("SELECT"))) {
            movies = my_connector.getMovies();
            labelsMovies = new Label[movies.length];

            map = new LinkedHashMap<Label, Movie>();
            //
            for (int i = 0; i < movies.length; i++) {
                labelsMovies[i] = new Label();
                ImageView image = new ImageView(movies[i].cover());

                map.put(labelsMovies[i], movies[i]);

                image.setFitHeight(222);
                image.setFitWidth(150);
                labelsMovies[i].setGraphic(image);
                GridPane.setValignment(labelsMovies[i], VPos.CENTER);
                GridPane.setHalignment(labelsMovies[i], HPos.CENTER);
                Label movie = labelsMovies[i];
                labelsMovies[i].setOnMouseClicked(e -> {
                    openDetails(movie);
                });
            }
            //moviesGrid.setPrefWidth(scrollPane.getWidth());
            //clear old data in grid
            moviesGrid.getChildren().clear();
            //moviesGrid.setAlignment(Pos.CENTER);
            //fill grid by movies
            //moviesGrid.addRow(0, labelsMovies[0], labelsMovies[1]);
            //moviesGrid.minHeight(moviesGrid.getMinHeight() + 222);
            //moviesGrid.setPrefWidth(browserPane.getWidth()-26);
            //moviesGrid.setMinHeight(scrollPane.getHeight());
            gridResize();
            //moviesGrid.setPrefHeight(moviesGrid.getHeight());
        }
    }

    public void returnMessage()
    {
        Alert alert = new Alert(AlertType.CONFIRMATION, "Are you sure you want to format your system?");
        alert.showAndWait().ifPresent(response -> {
            if (response == ButtonType.OK) {
            }
        });
    }

    private int detailsViewingNow;
    public void openDetails(Label e)
    {
        if (detailsPane.getMinWidth() < 1 || detailsViewingNow != map.get(e).id()) {
            //detailsInfoPane = new AnchorPane();
            //detailsPicPane.getChildren().clear();

            detailsPane.setMinWidth(300);
            my_movie = map.get(e);
            detailsViewingNow = my_movie.id();
            //my_movie= my_connector.getMovieInfo(1);

            //detailsContent.Text(my_movie.name() + "\n" + my_movie.year() + "\n" + my_movie.duration() + "\n" +  my_movie.genre() + "\n" + my_movie.description());
            Text info = new Text("Name:\n    " + my_movie.name() + "\n" +
                                    "Year: \n    " + my_movie.year() + "\n" +
                                    "Duration: \n    " + my_movie.duration() + "\n" +
                                    "Genre: \n    " + my_movie.genre() + "\n" +
                                    "Description: \n    " + my_movie.description());
            info.setStyle("-fx-font-size: 14; -fx-fill: #9f9f9f;");
            detailsContent.getChildren().clear();
            detailsContent.getChildren().add(info);

            detailsPicPane.setImage(null);
            //detailsPane.setMaxWidth(300);
            //Label movie = e;
            ImageView detailsImage = new ImageView();


            ImageView image = new ImageView((my_movie.cover()));
            image.setFitHeight(222);
            image.setFitWidth(150);

           //movie.


            detailsPicPane.setImage(my_movie.cover());

            Image img = detailsPicPane.getImage();
            if (img != null) {
                double w = 0;
                double h = 0;

                double ratioX = detailsPicPane.getFitWidth() / img.getWidth();
                double ratioY = detailsPicPane.getFitHeight() / img.getHeight();

                double reducCoeff = 0;
                if(ratioX >= ratioY) {
                    reducCoeff = ratioY;
                } else {
                    reducCoeff = ratioX;
                }

                w = img.getWidth() * reducCoeff;
                h = img.getHeight() * reducCoeff;

                detailsPicPane.setX((detailsPicPane.getFitWidth() - w) / 2);
                detailsPicPane.setY((detailsPicPane.getFitHeight() - h) / 2);
            }


            // 300px is details window width
            //scrollPane.setPrefWidth(browserPane.getWidth()-300);
            //scrollPane.setPrefHeight(browserPane.getHeight());
            //moviesGrid.setPrefWidth(browserPane.getWidth());
            //moviesGrid.setPrefHeight(browserPane.getHeight());
            //loadPosters();
            if (my_connector.granted("DELETE")) {
                deleteMovieButton.setDisable(false);
                deleteMovieButton.setOpacity(1);
                deleteMovieButton.setOnMouseClicked(ed -> {
                    System.out.println("delete");
                });

            } else {
                deleteMovieButton.setDisable(true);
                deleteMovieButton.setOpacity(0);
                deleteMovieButton.setOnMouseClicked(null);
            }

            if (my_connector.granted("UPDATE")) {
                editMovieButton.setDisable(false);
                editMovieButton.setOpacity(1);
                editMovieButton.setOnMouseClicked(ed -> {
                    System.out.println("edit");
                });

            } else {
                editMovieButton.setDisable(true);
                editMovieButton.setOpacity(0);
                editMovieButton.setOnMouseClicked(null);
            }


            gridResize();
            //button.setText(Double.toString(browserPane.getWidth()));

        }
        else
        {
            //detailsPicPane.getChildren().clear();
            detailsPane.setMinWidth(0);
            detailsPane.setPrefWidth(0);
            detailsPane.setMaxWidth(0);
            // 300px is details window width
            //scrollPane.setPrefWidth(browserPane.getWidth()+300);
            //scrollPane.setPrefHeight(browserPane.getHeight());
            //moviesGrid.setPrefWidth(scrollPane.getWidth()+300);
            //moviesGrid.setPrefHeight(browserPane.getHeight());
            //browserPane.setPrefWidth(browserPane.getWidth()+300);
            gridResize();
            //button.setText(Double.toString(browserPane.getWidth()));
        }
    }

    public void closeDetails()
    {
        //detailsPicPane.getChildren().clear();
        detailsPane.setMinWidth(1);
        detailsPane.setPrefWidth(1);
    }

    public void openFilter()
    {
        if (filterPane.getWidth() < 1)
        {
            //filterPane.maxWidth(300);
            filterPane.setMinWidth(300);
            filterPane.setPrefWidth(300);
            filterPane.setMaxWidth(300);
            //loadPosters();
            // 300px is filter window width
            //scrollPane.setPrefWidth(browserPane.getWidth()-300);
            //scrollPane.setPrefHeight(browserPane.getHeight());
            //moviesGrid.setPrefWidth(browserPane.getWidth() -300);
            //moviesGrid.setPrefHeight(browserPane.getHeight());

        }
        else
        {
            filterPane.setMinWidth(0);
            filterPane.setPrefWidth(0);
            filterPane.setMaxWidth(0);
            //loadPosters();
            // 300px is filter window width
            //scrollPane.setPrefWidth(browserPane.getWidth()+300);
            //scrollPane.setPrefHeight(browserPane.getHeight());
            //moviesGrid.setPrefWidth(scrollPane.getWidth()+300);
            //moviesGrid.setPrefHeight(browserPane.getHeight());
        }
        gridResize();
    }

    public void gridResize()
    {
        if (!Objects.isNull(movies)) {
            int colsAdd = ((int) scrollPane.getWidth()) / 200 - 2;
            int cols = colsAdd + 2;

            int rows = movies.length / cols + 1;
            if (242 * rows < scrollPane.getHeight())
                moviesGrid.setMinHeight(scrollPane.getHeight());
            else
                moviesGrid.setMinHeight(242 * rows);
            moviesGrid.setMaxWidth(scrollPane.getWidth());
            moviesGrid.setPrefWidth(scrollPane.getWidth());

            moviesGrid.setAlignment(Pos.CENTER);
            moviesGrid.setHgap(75);
            moviesGrid.setVgap(25);

            moviesGrid.getChildren().clear();
            int k = 0;
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    try {
                        moviesGrid.getChildren().add(labelsMovies[k]);
                    } catch (Exception err) {
                        k++;
                    }
                    if (k == movies.length - 1)
                        break;
                    k++;
                }
            }
        }
    }

    LogInController logInWindow;
    public void openLoginForm() {

        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("../../LogInController.fxml"));
            Parent root = loader.load();
            logInWindow = loader.getController();
            logInWindow.stage = new Stage();
            logInWindow.stage.setScene(new Scene(root, 250, 175));
            logInWindow.stage.setUserData(loader);
            logInWindow.open(this);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    AddMovieController addWindow;
    public void openAddForm() {

        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("../../AddMovieWindow.fxml"));
            Parent root = loader.load();
            addWindow = loader.getController();
            addWindow.stage = new Stage();
            addWindow.stage.setScene(new Scene(root, 377, 635));
            addWindow.stage.setUserData(loader);
            addWindow.open(this);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /*AdditionController altAddition;
    public void openAltAddForm(){
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("AddMovieWindow.fxml"));
            Parent root = loader.load();
            altAddition = loader.getController();
            altAddition.stage = new Stage();
            altAddition.stage.setScene(new Scene(root, 377, 635));
            altAddition.stage.setUserData(loader);
            altAddition.open(this);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
*/
    public Boolean newArgLogin(String user, String pass){

        Properties property = new Properties();
        ConnectionParams temporalParams;
        try {
            FileInputStream fis = new FileInputStream("connection.properties");
            property.load(fis);
            temporalParams  = new ConnectionParams(property.getProperty("CONFIG_DEFAULT_HOST"), user, pass);
        }
        catch (IOException ex)
        {
            temporalParams  = new ConnectionParams("127.0.0.1/moviesdb", user, pass);
        }

        if (my_connector.tryConnection(temporalParams)){
            workParams = temporalParams;
            my_connector.initConnection(workParams);
            setUserName(user);
            return my_connector.initialized();
        }
        return false;
    }

    public void setUserName(String name){
        userLabel.setText("Logged in as " + name);
    }
}
