content: package chapter04;
  
  import java.time.Duration;
  import java.time.LocalDateTime;
  import java.util.List;
  import lombok.Builder;
  import lombok.Getter;
  
  @Getter
  public class Movie {
  
      private String title;
      private Duration runningTime;
      private Money fee;
      private List<DiscountCondition> discountConditions;
  
      private MovieType movieType;
      private Money discountAmount;
      private double discountPercent;
  
      @Builder
      public Movie(String title, Duration runningTime, Money fee, List<DiscountCondition> discountConditions,
              MovieType movieType, Money discountAmount, double discountPercent) {
          this.title = title;
          this.runningTime = runningTime;
          this.fee = fee;
          this.discountConditions = discountConditions;
          this.movieType = movieType;
          this.discountAmount = discountAmount;
          this.discountPercent = discountPercent;
      }
  
  
      /**
       * 할인 조건을 하나씩 판단 하면서 할인 조건의 타입을 체크한 다음, 할인 가능 여부를 리턴
       *
       * @param whenScreened 상영 일시
       * @param sequence 상영 순번
       * @return 할인 가능하다면 true
       */
      public boolean isDiscountable(LocalDateTime whenScreened, int sequence) {
          for (DiscountCondition condition : discountConditions) {
              if (condition.getType() == DiscountConditionType.PERIOD) {
                  if (condition.isDiscountable(whenScreened.getDayOfWeek(), whenScreened.toLocalTime())) {
                      return true;
                  }
              } else {
                  if (condition.isDiscountable(sequence)) {
                      return true;
                  }
              }
          }
  
          return false;
      }
  
      public Money calculateAmountDiscountedFee() {
          if (movieType != MovieType.AMOUNT_DISCOUNT) {
              throw new IllegalArgumentException();
          }
  
          return fee.minus(discountAmount);
      }
  
      public Money calculatePercentDiscountedFee() {
          if (movieType != MovieType.PERCENT_DISCOUNT) {
              throw new IllegalArgumentException();
          }
  
          return fee.minus(fee.times(discountPercent));
      }
  
      public Money calculateNoneDiscountedFee() {
          if (movieType != MovieType.NONE_DISCOUNT) {
              throw new IllegalArgumentException();
          }
  
          return fee;
      }
  }
  