/**
 * license: GPLv3
 * lodge.reservationsystem
*/
package lodge.reservationsystem;

import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;

import lodge.data.Address;
import lodge.data.KitchenTypeEnum;
import lodge.reservation.Reservation;

public final class HouseReservation extends Reservation {

  public HouseReservation() {
    super();
    this.setType('Z');
    this.setNumberOfBeds(2);
    this.setNumberOfBedRooms(1);
    this.setNumberOfBathRooms(1);
    this.setNumberOfFloors(1);
    this.setKitchen(KitchenTypeEnum.Kitchenette);
  }

  public static Reservation copy(String reservationType) {
    return new HouseReservation();    
  }

  public HouseReservation(final Address physical_address) {
    super();
    this.setType('Z');
    this.setNumberOfBeds(2);
    this.setNumberOfBedRooms(1);
    this.setNumberOfBathRooms(1);
    this.setNumberOfFloors(1);
    this.setKitchen(KitchenTypeEnum.Kitchenette);
    this.setPhysical_address(
        new Address(physical_address.getStreet(), physical_address.getCity(), physical_address.getState(),
            physical_address.getZip()));
  }

  @Override
  public final String ReservationType() {
    return "HouseReservation";
  }

  @Override
  public boolean checkValid() throws IllegalArgumentException {
    if (getPhysical_address() == null) {
      throw new IllegalArgumentException(String.format("not valid, physical_address %s", this.getReservation_number()));
    }
    if (getMailing_address() == null) {
      throw new IllegalArgumentException(String.format("not valid, mailing_address: %s", this.getReservation_number()));
    }
    return true;
  }

  // House price plus additional flat fee for additional space per day
  @Override
  public float getPricePerNight() {
    return (getSquareFeet() > 900.0f) ? 120.0f + 15.0f : 120.0f;
  }

  // calculate and return the reservation's price
  @Override
  public float calculatePrice() {
    ZonedDateTime enddt = getReservation_end_date().truncatedTo(ChronoUnit.DAYS);
    ZonedDateTime startdt = getReservation_start_date().truncatedTo(ChronoUnit.DAYS);
    long days = ChronoUnit.DAYS.between(startdt, enddt);
    days = (days < 2) ? 1 : days - 1;
    float calcprice = getPricePerNight() * days;
    return calcprice;
  }
}