#pragma once

#include "CDTable.h"
#include <list>
#include <optional>

typedef int32_t AnimationGroupID;
typedef std::string AnimationID;
typedef std::pair<std::string, AnimationGroupID> CDAnimationKey;

struct CDAnimation {
	// uint32_t animationGroupID;
	// std::string animation_type;
	// The above two are a pair to represent a primary key in the map.
	std::string animation_name;        //!< The animation name
	float chance_to_play;           //!< The chance to play the animation
	UNUSED_COLUMN(uint32_t min_loops;)                 //!< The minimum number of loops
	UNUSED_COLUMN(uint32_t max_loops;)                 //!< The maximum number of loops
	float animation_length;         //!< The animation length
	UNUSED_COLUMN(bool hideEquip;)                 //!< Whether or not to hide the equip
	UNUSED_COLUMN(bool ignoreUpperBody;)           //!< Whether or not to ignore the upper body
	UNUSED_COLUMN(bool restartable;)               //!< Whether or not the animation is restartable
	UNUSED_COLUMN(std::string face_animation_name;)   //!< The face animation name
	UNUSED_COLUMN(float priority;)                 //!< The priority
	UNUSED_COLUMN(float blendTime;)                //!< The blend time
};

class CDAnimationsTable : public CDTable<CDAnimationsTable, std::map<CDAnimationKey, std::list<CDAnimation>>> {
public:
	void LoadValuesFromDatabase();
	/**
	 * Given an animationType and the previousAnimationName played, return the next animationType to play.
	 * If there are more than 1 animationTypes that can be played, one is selected at random but also does not allow
	 * the previousAnimationName to be played twice.
	 * 
	 * @param animationType The animationID to lookup
	 * @param previousAnimationName The previously played animation
	 * @param animationGroupID The animationGroupID to lookup
	 * @return CDAnimationLookupResult 
	 */
	[[nodiscard]] std::optional<CDAnimation> GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID);

	/**
	 * Cache a full AnimationGroup by its ID.
	 */
	void CacheAnimationGroup(AnimationGroupID animationGroupID);
private:

	/**
	 * Cache all animations given a premade key
	 */
	void CacheAnimations(const CDAnimationKey animationKey);

	/**
	 * Run the query responsible for caching the data.
	 * @param queryToCache 
	 * @return true 
	 * @return false 
	 */
	bool CacheData(CppSQLite3Statement& queryToCache);
};