import java.io.PrintStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

public class Main {

    private static final class TuitionPlan {
        private final BigDecimal hourlyRateGbp;
        private final int lessonMinutes;
        private final BigDecimal lessonsPerWeek;
        private final int numberOfWeeks;

        TuitionPlan(
                BigDecimal hourlyRateGbp,
                int lessonMinutes,
                BigDecimal lessonsPerWeek,
                int numberOfWeeks) {

            this.hourlyRateGbp = hourlyRateGbp;
            this.lessonMinutes = lessonMinutes;
            this.lessonsPerWeek = lessonsPerWeek;
            this.numberOfWeeks = numberOfWeeks;
        }

        void validate() {
            if (hourlyRateGbp.compareTo(BigDecimal.ZERO) <= 0) {
                throw new IllegalArgumentException(
                        "Hourly rate must be greater than zero."
                );
            }

            if (lessonMinutes < 15 || lessonMinutes > 180) {
                throw new IllegalArgumentException(
                        "Lesson length must be between 15 and 180 minutes."
                );
            }

            if (lessonsPerWeek.compareTo(BigDecimal.ZERO) <= 0) {
                throw new IllegalArgumentException(
                        "Lessons per week must be greater than zero."
                );
            }

            if (numberOfWeeks < 1 || numberOfWeeks > 52) {
                throw new IllegalArgumentException(
                        "Number of weeks must be between 1 and 52."
                );
            }
        }

        BigDecimal lessonCost() {
            return hourlyRateGbp
                    .multiply(BigDecimal.valueOf(lessonMinutes))
                    .divide(
                            BigDecimal.valueOf(60),
                            2,
                            RoundingMode.HALF_UP
                    );
        }

        BigDecimal fourWeekCost() {
            return lessonCost()
                    .multiply(lessonsPerWeek)
                    .multiply(BigDecimal.valueOf(4))
                    .setScale(2, RoundingMode.HALF_UP);
        }

        BigDecimal periodCost() {
            return lessonCost()
                    .multiply(lessonsPerWeek)
                    .multiply(BigDecimal.valueOf(numberOfWeeks))
                    .setScale(2, RoundingMode.HALF_UP);
        }
    }

    private static String money(BigDecimal value) {
        return String.format(Locale.UK, "£%,.2f", value);
    }

    public static void main(String[] args) {
        // Ensure that the pound sign is printed correctly.
        System.setOut(
                new PrintStream(
                        System.out,
                        true,
                        StandardCharsets.UTF_8
                )
        );

        /*
         * Edit these four values before running:
         *
         * 30 = hourly rate in pounds
         * 60 = lesson length in minutes
         * 1  = lessons per week
         * 12 = number of weeks
         */
        TuitionPlan plan = new TuitionPlan(
                new BigDecimal("30"),
                60,
                new BigDecimal("1"),
                12
        );

        plan.validate();

        System.out.println("ONLINE TUITION BUDGET EXAMPLE");
        System.out.println("-".repeat(36));

        System.out.printf(
                "Hourly rate:       %s%n",
                money(plan.hourlyRateGbp)
        );

        System.out.printf(
                "Lesson length:     %d minutes%n",
                plan.lessonMinutes
        );

        System.out.printf(
                "Lessons per week:  %s%n",
                plan.lessonsPerWeek.toPlainString()
        );

        System.out.printf(
                "Selected period:   %d weeks%n",
                plan.numberOfWeeks
        );

        System.out.println();

        System.out.printf(
                "Cost per lesson:   %s%n",
                money(plan.lessonCost())
        );

        System.out.printf(
                "Four-week example: %s%n",
                money(plan.fourWeekCost())
        );

        System.out.printf(
                "Period total:      %s%n",
                money(plan.periodCost())
        );

        System.out.println();
        System.out.println("Before booking, confirm:");

        String[] prompts = {
                "the tutor's current live rate and lesson length",
                "subject, level and exam-board experience",
                "normal availability and cancellation terms",
                "how progress and homework will be handled",
                "the online platform and safeguarding arrangements"
        };

        for (int i = 0; i < prompts.length; i++) {
            System.out.printf("%d. %s%n", i + 1, prompts[i]);
        }

        System.out.println();
        System.out.println(
                "One UK directory using a pay-as-you-go model:"
        );
        System.out.println(
                "https://l...content-available-to-author-only...n.com/find-a-tutor"
        );
        System.out.println(
                "Live profiles and current terms are the source of truth."
        );
    }
}