package org.academiadecodigo.bootcamp11.hotel;

/**
 * MIT License
 * (c) 2017 Ricardo Constantino
 */
public class Hotel {
    private String name;
    private boolean open;
    private int stars;
    private int maxRooms;
    private Room[] rooms;
    private double basePrice;

    public Hotel(String name, int maxRooms, int stars) {
        this.name = name;
        this.maxRooms = maxRooms;
        this.stars = Math.min(Math.max(1, stars), 5);
        this.basePrice = 20.0 * stars; // seems reasonable...
        this.open = true;

        this.rooms = constructRooms();
    }

    public Hotel(String name, int maxRooms, int stars, boolean open) {
        this.name = name;
        this.maxRooms = maxRooms;
        this.stars = Math.min(Math.max(1, stars), 5);
        this.basePrice = 20.0 * stars;
        this.open = open;

        this.rooms = constructRooms();
    }

    private Room[] constructRooms() {
        Room[] rooms = new Room[this.maxRooms];
        int roomNumber = 1;

        // Patented algorithm. DO NOT STEAL™
        int roomsPreOccupied = (int) Math.floor(((this.stars-1.0)/4) * this.maxRooms);

        // construct occupied rooms
        for (int roomsCreated = 0;
             roomsCreated < roomsPreOccupied; roomsCreated++) {
            rooms[roomsCreated] = new Room(true, roomNumber++);
        }
        // construct free rooms
        for (int roomsCreated = roomsPreOccupied;
             roomsCreated < this.maxRooms; roomsCreated++) {
            int price = (int) calculateRoomPrice(roomNumber++) * 100;
            rooms[roomsCreated] = new Room(false, roomNumber, price);
        }
        return rooms;
    }

    public String getName() {
        return this.name;
    }

    public int getStars() {
        return this.stars;
    }

    public Room giveRoomKey(Room room) {
        room.setOccupied();
        return room;
    }

    public void returnRoomKey(Room room, double moneyToPayForRoom) {
        if (moneyToPayForRoom == room.getPriceInEur()) {
            room.setFree();
            say("Thank you for spending the night with " +
                    this.name + ".\nCome back any time!");
        } else {
            say("This isn't enough. Hey, where are you going?!");
        }
    }

    public boolean welcomeVisitor() {
        if (this.open) {
            say("Hello and welcome to "+this.name+".");
            return true;
        } else {
            say("ASAE closed us, sorry.");
            return false;
        }
    }

    public Room getFirstFreeRoom() {
        for (int roomNum = 0; roomNum < rooms.length; roomNum++) {
            if (!this.rooms[roomNum].isOccupied()) {
                say("We can place you in " + this.rooms[roomNum].getName() +
                        ".\nIt has a very nice view of the 4-star hotel opposite to us.");
                String cost = String.format("It's €%.2f per night.",
                        this.rooms[roomNum].getPriceInEur());
                say(cost);
                return this.rooms[roomNum];
            }
        }
        say("We're extremely sorry, there's no vacancy.");
        return null;
    }

    private double calculateRoomPrice(int roomNumber) {
        double price = this.basePrice * (1 + roomNumber / this.maxRooms);
        return price;
    }

    private void say(String something) {
        System.out.println("\n" + this.name + " Receptionist:");
        System.out.println(something);
    }
}
