// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
// SPDX-FileCopyrightText: 2025 <Alexander Marthin Klemensen stud-marthin@ruc.dk>
// SPDX-FileCopyrightText: 2025 <Ian Valentin Christensen stud-ianc@ruc.dk>
// SPDX-FileCopyrightText: 2025 <Zahed Noos zahed@ruc.dk>
// SPDX-License-Identifier: GPL-3.0-or-later

package com.example.portfolio2;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.List;

/// Bachelorizer - JavaFX Window view
// Class is final to forbid subclassing,
// because object is passed to controller during instantiation
public final class Window extends Application {

	/// Default constructor
	// (declared explicitly only to silence javadoc)
	public Window() { }

	/// window width
	private static final int WINDOW_WIDTH = 1000;

	/// window height
	private static final int WINDOW_HEIGHT = 500;

	/// box width
	private static final int LIST_WIDTH = 250;

	/// box height
	private static final int LIST_HEIGHT = 35;

	/// Label styling
	private static final String LABEL_STYLE =
		"-fx-font-weight: bold;"
		+ "-fx-font-size: 18;"
		+ "-fx-padding: 10";

	/// Storage model
	private Database store = new Database();

	/// Application controller
	private Controller con = new Controller(store, this);

	@Override
	public void start(final Stage stage) throws IOException {
		// clear old insertions into participation table
		con.initialize();

		// define list of columns based on their names
		List<ActivityColumn> columns = List.of(
			new ActivityColumn("Program"),
			new ActivityColumn("Subject 1"),
			new ActivityColumn("Subject 2"),
			new ActivityColumn("Elective")
		);

		// define list of subject modules
		List<String> subjectModules = List.of(
			"Computer Science", "Informatik", "Astrology");

		// define button functionality for each activity column
		for (ActivityColumn col : columns) {
			col.nameLabel.setStyle(LABEL_STYLE);
			col.ectsLabel.setStyle(LABEL_STYLE);
			col.categoryCombo.setPrefSize(
				LIST_WIDTH, LIST_HEIGHT);
			col.activitySelect.setPrefSize(
				LIST_WIDTH, LIST_HEIGHT);
			col.area.setPrefWidth(LIST_WIDTH);

			// all boxes share same activity logic
			col.activitySelect.setOnAction(event -> {
				con.onActivitySelected(
					col.categoryCombo,
					col.activitySelect,
					col.area);
				con.updateEcts(
					col.ectsLabel,
					col.categoryCombo);
			});

			// handle each category box
			switch (col.name) {
			  case "Program" -> {
				col.categoryCombo.getItems().addAll(
					"HumTek", "NatBach");
				col.categoryCombo.setOnAction(event -> {
					con.onCategorySelected(
						col.categoryCombo,
						col.activitySelect,
						col.area);
				});
			}
			  // TODO: use the list for filling the box
			  case "Subject 1" -> {
				col.categoryCombo.getItems().addAll(
					"Computer Science",
					"Informatik",
					"Astrology");
				col.categoryCombo.setOnAction(event -> {
					con.onSubjectModuleSelected(
						col.categoryCombo,
						columns.get(2)
							.categoryCombo,
						subjectModules);
					con.onCategorySelected(
						col.categoryCombo,
						col.activitySelect,
						col.area);
				});
			}
			  case "Subject 2" -> {
				col.categoryCombo.getItems().addAll(
					"Computer Science",
					"Informatik",
					"Astrology");
				// TODO: figure out a better way...
				col.categoryCombo.setOnAction(event -> {
					con.onSubjectModuleSelected(
						col.categoryCombo,
						columns.get(1)
							.categoryCombo,
						subjectModules);
					con.onCategorySelected(
						col.categoryCombo,
						col.activitySelect,
						col.area);
				});
			}
			  case "Elective" -> {

				// hide useless box
				col.categoryCombo.setVisible(false);

				con.fillElective(col.activitySelect);
			}
			}
		}

		// define HBox and scene for columns
		HBox root = new HBox(
			columns.get(0).asVBox(),
			columns.get(1).asVBox(),
			columns.get(2).asVBox(),
			columns.get(3).asVBox());
		Scene scene = new Scene(
			root, WINDOW_WIDTH, WINDOW_HEIGHT);
		stage.setTitle(
			"Course Selector RUC: Ultimate Deluxe Edition");
		stage.setScene(scene);
		stage.show();
	}

	/// JVM entry point
	///
	/// @param args  command-line arguments
	public static void main(final String[] args) {
		launch();
	}

	/// column of activities
	///
	/// @param name            identifier stored in the text felt
	/// @param nameLabel       display text
	/// @param categoryCombo   dropdown list for categories
	/// @param activitySelect  dropdown list for activities
	/// @param area            description of chosen activities
	/// @param ectsLabel       text to display ECTS points
	private record ActivityColumn(
		String name,
		Label nameLabel,
		ComboBox<String> categoryCombo,
		ComboBox<String> activitySelect,
		TextArea area,
		Label ectsLabel
	) {
		public ActivityColumn(String name) {
			this(
				name,
				new Label(name),
				new ComboBox<>(),
				new ComboBox<>(),
				new TextArea(),
				new Label()
			);
		}

		/// activity columne as VBox
		///
		/// @return  column of activities as VBox
		VBox asVBox() {
			return new VBox(
				nameLabel,
				categoryCombo,
				activitySelect,
				area,
				ectsLabel);
		}
	}
}