package dev.peerat.backend.repository;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Puzzle;

public class DatabaseChapterRepository extends BaseDatabaseQuery{
	
	private static enum Query{

		// CHAPTERS
		SPECIFIC_CHAPTER_QUERY("SELECT * FROM chapters WHERE id_chapter = ?"),
		CHAPTER_FROM_PUZZLE("SELECT c.*\r\n"
				+ "FROM chapters c\r\n"
				+ "JOIN puzzles p ON p.fk_chapter = c.id_chapter\r\n"
				+ "WHERE p.id_puzzle = ?"),
		ALL_CHAPTERS_QUERY("SELECT * FROM chapters WHERE id_chapter > 0");


		private String request;

		Query(Query parent, String request) {
			this.request = parent.request + request;
		}

		Query(String request) {
			this.request = request;
		}

		public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
			return base.prepare(this.request);
		}

		@Override
		public String toString() {
			return this.request;
		}
	}
	
	
	private Configuration config;
	private DatabasePuzzleRepository puzzleRepo;
	
	public DatabaseChapterRepository(ConnectionManager con, Configuration config, DatabasePuzzleRepository puzzleRepo){
		super(con);
		this.config = config;
		this.puzzleRepo = puzzleRepo;
	}
	
	/**
	 * Get a specific chapter
	 *
	 * @param id The id of the chapter
	 * @return The chapter or null if an error occurred
	 */
	public Chapter getChapter(int id) {
		try {
			ensureConnection();
			PreparedStatement chapterStmt = Query.SPECIFIC_CHAPTER_QUERY.prepare(this);
			chapterStmt.setInt(1, id);
			ResultSet chapterResult = chapterStmt.executeQuery();
			if (chapterResult.next()) {
				Chapter chapter = makeChapter(chapterResult);
				List<Puzzle> puzzles = puzzleRepo.getPuzzlesInChapter(id);
				chapter.setPuzzles(puzzles);
				return chapter;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public Chapter getChapter(Puzzle puzzle){
		try {
			ensureConnection();
			PreparedStatement chapterStmt = Query.CHAPTER_FROM_PUZZLE.prepare(this);
			chapterStmt.setInt(1, puzzle.getId());
			ResultSet chapterResult = chapterStmt.executeQuery();
			if (chapterResult.next()) {
				Chapter chapter = makeChapter(chapterResult);
				List<Puzzle> puzzles = puzzleRepo.getPuzzlesInChapter(chapter.getId());
				chapter.setPuzzles(puzzles);
				return chapter;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Get all chapters in the database
	 *
	 * @return List of all chapters or null if an error occurred
	 */
	public List<Chapter> getAllChapters() {
		try {
			List<Chapter> chapterList = new ArrayList<>();
			ensureConnection();
			PreparedStatement chapterStmt = Query.ALL_CHAPTERS_QUERY.prepare(this);
			ResultSet chapterResult = chapterStmt.executeQuery();
			while (chapterResult.next()) {
				Chapter chapter = makeChapter(chapterResult);
				chapter.setPuzzles(puzzleRepo.getPuzzlesInChapter(chapter.getId()));
				chapterList.add(chapter);
			}
			return chapterList;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
}