package controllers;

import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Popup;
import javafx.stage.Stage;
import model.SharedTrip;
import model.Stop;
import model.Trip;
import model.TripStop;

import java.net.URL;
import java.util.HashMap;
import java.util.ResourceBundle;
import java.util.regex.Pattern;

/**
 * Created by Gondr on 28/05/2017.
 */
public class SharedTripsController extends Controller{

    @FXML
    private TableView<SharedTrip> sharedTripsTable;
    @FXML
    private TableColumn<SharedTrip, String> tripNameColumn;
    @FXML
    private TableColumn<SharedTrip, String> directionColumn;
    @FXML
    private TableColumn<SharedTrip, String> daysColumn;
    @FXML
    private ComboBox<TripStop> stopsFilter;
    @FXML
    private ObservableList<SharedTrip> sharedTrips;
    @FXML
    private TextField stopName;
    @FXML
    private ComboBox<String> directionBox;

    public void showDetails(){
        SharedTrip trip = sharedTripsTable.getSelectionModel().getSelectedItem();
        Stage tripDetails = new Stage();
        tripDetails.setWidth(600);
        tripDetails.setHeight(400);
        tripDetails.setTitle(String.format("%1s Details", trip.name));

        AnchorPane wrapper = new AnchorPane();

        GridPane popUpGrid = new GridPane();
        ColumnConstraints columnConstraints = new ColumnConstraints();
        columnConstraints.setPercentWidth(50);
        popUpGrid.getColumnConstraints().add(columnConstraints);
        popUpGrid.getColumnConstraints().add(columnConstraints);

        popUpGrid.addColumn(0);
        popUpGrid.addColumn(0);
        popUpGrid.addRow(0);//title
        popUpGrid.addRow(0);//driver title
        popUpGrid.addRow(0);//driver name
        popUpGrid.addRow(0);//driver photo
        popUpGrid.addRow(0);//
        popUpGrid.addRow(0);//Car title
        popUpGrid.addRow(0);//car model
        popUpGrid.addRow(0);//car color
        popUpGrid.addRow(0);//car year
        popUpGrid.addRow(0);//car performance
        popUpGrid.addRow(0);//book button

        //information
        Label tripTitle = new Label(trip.name);
        tripTitle.setAlignment(Pos.CENTER);
        popUpGrid.add(tripTitle, 0, 0, 2, 1);

        Label driverTitle = new Label("Driver");
        driverTitle.setAlignment(Pos.CENTER);
        popUpGrid.add(driverTitle, 0, 1);

        Label driverName = new Label("Driver Name");
        popUpGrid.add(driverName, 0, 2);

        Label driverPhoto = new Label("Driver Photo");
        popUpGrid.add(driverPhoto, 0, 3);

        Label carTitle = new Label("Car");
        popUpGrid.add(carTitle, 0, 4);

        Label carModel = new Label(trip.ride.getModel());
        popUpGrid.add(carModel, 0, 5);

        Label carPlate = new Label(trip.ride.getLicensePlate());
        popUpGrid.add(carPlate, 0, 6);

        Label carColour = new Label(trip.ride.getColour());
        popUpGrid.add(carColour, 0, 7);

        Label carYear = new Label(String.valueOf(trip.ride.getYear()));
        popUpGrid.add(carYear, 0, 8);

        Label seatsAvailable = new Label(String.valueOf(trip.getSeatsAvailable()));
        popUpGrid.add(seatsAvailable, 0, 9);

        //stops
        TableView<TripStop> stopTableView = new TableView<>();

        TableColumn<TripStop, String> addressColumn = new TableColumn<>();
        addressColumn.setText("Address");
        addressColumn.setCellValueFactory(p->new SimpleStringProperty(p.getValue().getName()));
        stopTableView.getColumns().add(addressColumn);

        TableColumn<TripStop, String> timeColumn = new TableColumn<>();
        timeColumn.setText("Time");
        timeColumn.setCellValueFactory(p->new SimpleStringProperty(p.getValue().getTime()));
        stopTableView.getColumns().add(timeColumn);

        stopTableView.setItems(trip.route);

        popUpGrid.add(stopTableView, 1, 1, 1, 9);

        AnchorPane.setTopAnchor(popUpGrid, 0.0);
        AnchorPane.setBottomAnchor(popUpGrid, 0.0);
        AnchorPane.setRightAnchor(popUpGrid, 0.0);
        AnchorPane.setLeftAnchor(popUpGrid, 0.0);

        //book button
        Button bookRide = new Button("Book Ride");
        bookRide.setOnAction(e->{
            trip.bookSeat(parent.getSession().getUserCode());
            tripDetails.close();
            search();
            popUp(Alert.AlertType.CONFIRMATION, "Success!", "You have Successfully booked a ride!", "The ride has been successfully booked and can be viewed in your booked rides.");
        });
        popUpGrid.add(bookRide, 0, 10, 2, 1);

        wrapper.getChildren().add(popUpGrid);

        Scene detailsScene = new Scene(wrapper);

        tripDetails.setScene(detailsScene);

        tripDetails.showAndWait();
    }

    public void resetSearch(){
        stopsFilter.getSelectionModel().select(0);
    }

    public void search(){
        sharedTrips.remove(0, sharedTrips.size());
        //ignore stop
        boolean ignoreStopFilter = stopsFilter.getSelectionModel().getSelectedIndex() == 0;
        boolean ignoreStopNameSearch = stopName.getText().equals("") || stopName.getText() == null;
        boolean ignoreStopSearch = ignoreStopFilter && ignoreStopNameSearch;
        Pattern stopNamePattern = Pattern.compile(".*"+stopName.getText()+".*", Pattern.CASE_INSENSITIVE);
        //ignore direction
        boolean ignoreDirection = directionBox.getSelectionModel().isSelected(0) || directionBox.getValue() == null;
        for(SharedTrip sharedTrip: parent.getSession().getDataManager().getSharedTrips()){
            if (sharedTrip.isFull()){
                continue;
            }
            //stops are equal
            boolean add = false;
            for (TripStop stop : sharedTrip.route) {
                if (ignoreStopSearch){
                    add = true;
                    break;
                }
                if (stop.equals(stopsFilter.getValue())) {
                    add = true;
                    break;
                }
                if (stopNamePattern.matcher(stop.getName()).matches()){
                    add = true;
                    break;
                }
            }
            if (!ignoreDirection) {
                add = sharedTrip.direction.equals(directionBox.getValue());
            }
            if (add){
                sharedTrips.add(sharedTrip);//for other filters later
            }
        }
    }

    @Override
    public void runLater(){
        sharedTrips = FXCollections.observableArrayList(parent.getSession().getDataManager().getSharedTrips());
        sharedTripsTable.setItems(sharedTrips);
        tripNameColumn.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().name));
        directionColumn.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().direction));
        daysColumn.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().getDays()));
        //add all stops that have shared trips with them. TODO only display visible ones.
        ObservableList<TripStop> stops = FXCollections.observableArrayList();
        stops.add(new TripStop("Any", ""));
        HashMap<TripStop, Boolean> stopAdded = new HashMap<>();
        for (SharedTrip trip:sharedTrips){
            for(TripStop stop: trip.route){
                if (!stopAdded.containsKey(stop)) {
                    stops.add(stop);
                    stopAdded.put(stop, true);
                }
            }
        }
        stopsFilter.setItems(stops);
        stopsFilter.valueProperty().addListener( e ->{
            search();
        });
        stopName.textProperty().addListener(e-> search());
        directionBox.valueProperty().addListener(e->search());
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        ObservableList<String> directions = FXCollections.observableArrayList();
        directions.addAll("Any", Trip.TO_UNI, Trip.TO_HOME);
        directionBox.setItems(directions);
    }
}
