package main.java.rdg;

import main.java.DbConnection;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Set;

public class CinemaHall {
    private long id;
    private String hallLabel;
    private int rowCount;
    private int seatsPerRow;
    private String screenType;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getHallLabel() {
        return hallLabel;
    }

    public void setHallLabel(String hallLabel) {
        this.hallLabel = hallLabel;
    }

    public int getRowCount() {
        return rowCount;
    }

    public void setRowCount(int rowCount) {
        this.rowCount = rowCount;
    }

    public int getSeatsPerRow() {
        return seatsPerRow;
    }

    public void setSeatsPerRow(int seatsPerRow) {
        this.seatsPerRow = seatsPerRow;
    }

    public String getScreenType() {
        return screenType;
    }

    public void setScreenType(String screenType) {
        this.screenType = screenType;
    }

    @Override
    public String toString() {
        return "CinemaHall {" +
                hallLabel +
                "}, id=" + id +
                ", " + rowCount + " rows" +
                ", " + seatsPerRow + " seats per row" +
                ", screen type='" + screenType + '\'';
    }

    public boolean create (){
        DbConnection.setIsolationCommitted();

        try (PreparedStatement s = DbConnection.getCon().prepareStatement("INSERT INTO cinema_halls (halllabel, rowcount, seatsperrow, screentype) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)){
            DbConnection.disableCommit();

            String label = this.hallLabel, type = this.screenType;
            int rows = this.rowCount, seats = this.seatsPerRow;

            s.setString(1, label);
            s.setInt(2, rows);
            s.setInt(3, seats);
            s.setString(4, type);

            s.executeUpdate();

            long hallID = 0;
            try (ResultSet r = s.getGeneratedKeys()){
                r.next();
                hallID = r.getLong(1);
                this.id=hallID;
            }

            if (hallID == 0) return false;

            //generovanie sedadiel v sale
            for (int row = 1 ; row <= rows ; row++){
                for (int seat = 1 ; seat <= seats ; seat++) {
                    Seat seatInstance = new Seat();
                    seatInstance.setSeatNumber(seat);
                    seatInstance.setCinemaHall(hallID);
                    seatInstance.setRow(row);
                    if (!seatInstance.create())
                        return false;
                }
            }

            DbConnection.getCon().commit();
        } catch (SQLException e){
            DbConnection.rollback();
            return false;
        } finally {
            DbConnection.resetCommit();
            DbConnection.resetIsolation();
        }

        return true;
    }

    public static CinemaHall read(long id){
        try (PreparedStatement s = DbConnection.getCon().prepareStatement("SELECT * FROM cinema_halls WHERE cinemahall_id=?")){
            s.setLong(1, id);

            CinemaHall hall = new CinemaHall();

            try (ResultSet r = s.executeQuery()){
                r.next();
                hall.setId(r.getLong(1));
                hall.setHallLabel(r.getString(2));
                hall.setRowCount(r.getInt(3));
                hall.setSeatsPerRow(r.getInt(4));
                hall.setScreenType(r.getString(5));
            }

            return hall;

        } catch (SQLException e){
            return null;
        }
    }

    public boolean update (){
        try (PreparedStatement s = DbConnection.getCon().prepareStatement("UPDATE cinema_halls SET halllabel=?, screentype=? WHERE cinemahall_id=?")){
            s.setString(1, this.hallLabel);
            s.setString(2, this.screenType);
            s.setLong(3, this.id);

            s.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    public boolean delete (){
        try (PreparedStatement ss = DbConnection.getCon().prepareStatement("DELETE FROM cinema_halls WHERE cinemahall_id=?")){
            ss.setLong(1, this.id);
            ss.executeUpdate();

        } catch (SQLException e) {
            return false;
        }

        return true;
    }

    public static Set<Long> getSeats(long id) {
        Set<Long> seatsID = new HashSet<>();

        try (PreparedStatement s = DbConnection.getCon().prepareStatement("SELECT seat_id FROM seats WHERE hall_id=?")){
            s.setLong(1, id);

            try (ResultSet r = s.executeQuery()){
                while (r.next()){
                    seatsID.add(r.getLong(1));
                }
            }
            return seatsID;
        } catch (SQLException e) {
            return null;
        }
    }

    public static Set<CinemaHall> listAll () {
        try (PreparedStatement s = DbConnection.getCon().prepareStatement("SELECT * FROM cinema_halls")){
            Set<CinemaHall> cinemaHalls = new HashSet<>();

            try (ResultSet r = s.executeQuery()) {
                while (r.next()) {
                    CinemaHall cinemaHall = new CinemaHall();
                    cinemaHall.setId(r.getLong(1));
                    cinemaHall.setHallLabel(r.getString(2));
                    cinemaHall.setRowCount(r.getInt(3));
                    cinemaHall.setSeatsPerRow(r.getInt(4));
                    cinemaHall.setScreenType(r.getString(5));

                    cinemaHalls.add(cinemaHall);
                }
            }

            return cinemaHalls;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
}
