#include "sysdeps.h"
#include "imgui.h"
#include "options.h"
#include "gui/gui_handling.h"
#include "uae.h"
#include "imgui_panels.h"

#ifdef _WIN32
#include <cstring>
#include <cctype>
static const char* strcasestr(const char* haystack, const char* needle)
{
	if (!needle[0]) return haystack;
	for (; *haystack; ++haystack) {
		const char* h = haystack;
		const char* n = needle;
		while (*h && *n && tolower((unsigned char)*h) == tolower((unsigned char)*n)) {
			++h; ++n;
		}
		if (!*n) return haystack;
	}
	return nullptr;
}
#endif

static ImVec4 rgb_to_vec4(int r, int g, int b, float a = 1.0f) { return ImVec4{ static_cast<float>(r) / 255.0f, static_cast<float>(g) / 255.0f, static_cast<float>(b) / 255.0f, a }; }
static ImVec4 lighten(const ImVec4& c, float f) { return ImVec4{ std::min(c.x + f, 1.0f), std::min(c.y + f, 1.0f), std::min(c.z + f, 1.0f), c.w }; }

static bool s_configs_initialized = false;

void configurations_panel_reset()
{
	s_configs_initialized = false;
}

void render_panel_configurations()
{
	static int selected = -1;
	static char name[MAX_DPATH] = "";
	static char desc[MAX_DPATH] = "";
	static char search_text[256] = "";
	static char last_seen_config[MAX_DPATH] = "";
	// Check if the current config has changed (e.g. via Quickstart or loading a file)
	// If so, update the fields to match.
	if (!s_configs_initialized || strncmp(last_active_config, last_seen_config, MAX_DPATH) != 0)
	{
		ReadConfigFileList();
		s_configs_initialized = true;
		bool found = false;
		if (last_active_config[0])
		{
			for (int i = 0; i < ConfigFilesList.size(); ++i)
			{
				if (strcmp(ConfigFilesList[i]->Name, last_active_config) == 0)
				{
					selected = i;
					strncpy(name, ConfigFilesList[i]->Name, MAX_DPATH);
					strncpy(desc, ConfigFilesList[i]->Description, MAX_DPATH);
					found = true;
					break;
				}
			}
			
			if (!found)
			{
				// Not in the list (e.g. from Quickstart autofill), use the values directly
				strncpy(name, last_active_config, MAX_DPATH);
				strncpy(desc, changed_prefs.description, MAX_DPATH);
				selected = -1; // Ensure nothing is selected
			}
		}
		else
		{
			// Reset fields if no active config
			name[0] = '\0';
			desc[0] = '\0';
			selected = -1;
		}
		
		// Update tracker
		strncpy(last_seen_config, last_active_config, MAX_DPATH);
	}

	// Calculate footer height dynamically
	const ImGuiStyle& style = ImGui::GetStyle();
	const float input_row_h = std::max(TEXTFIELD_HEIGHT, ImGui::GetTextLineHeight()) + style.ItemSpacing.y;
	// 3 input rows + 2 Spacings + Separator + Buttons, plus extra padding to avoid scrollbar
	const float footer_h = (input_row_h * 3) + (style.ItemSpacing.y * 2) + 1.0f + BUTTON_HEIGHT + style.WindowPadding.y + 10.0f;

	ImGui::Indent(4.0f);
	ImGui::Spacing();
	ImGui::BeginChild("ConfigList", ImVec2(ImGui::GetContentRegionAvail().x - 2.0f, -footer_h));
	ImGui::Spacing();
	ImGui::Indent(4.0f);

	for (int i = 0; i < ConfigFilesList.size(); ++i)
	{
		if (search_text[0] != '\0' && strcasestr(ConfigFilesList[i]->Name, search_text) == nullptr)
			continue;

		char label[MAX_DPATH * 2];
		if (strlen(ConfigFilesList[i]->Description) > 0)
			snprintf(label, sizeof(label), "%s (%s)", ConfigFilesList[i]->Name, ConfigFilesList[i]->Description);
		else
			snprintf(label, sizeof(label), "%s", ConfigFilesList[i]->Name);

		const bool is_selected = (selected == i);
		if (is_selected)
		{
			const ImVec4 col_act = rgb_to_vec4(gui_theme.selector_active.r, gui_theme.selector_active.g, gui_theme.selector_active.b);
			ImGui::PushStyleColor(ImGuiCol_Header, col_act);
			ImGui::PushStyleColor(ImGuiCol_HeaderHovered, lighten(col_act, 0.05f));
			ImGui::PushStyleColor(ImGuiCol_HeaderActive, lighten(col_act, 0.10f));
		}

		if (ImGui::Selectable(label, is_selected, ImGuiSelectableFlags_AllowDoubleClick))
		{
			selected = i;
			strncpy(name, ConfigFilesList[i]->Name, MAX_DPATH);
			strncpy(desc, ConfigFilesList[i]->Description, MAX_DPATH);

			if (ImGui::IsMouseDoubleClicked(0))
			{
				target_cfgfile_load(&changed_prefs, ConfigFilesList[selected]->FullPath, CONFIG_TYPE_DEFAULT, 0);
				strncpy(last_active_config, ConfigFilesList[selected]->Name, MAX_DPATH);
				uae_reset(1, 1);
				gui_running = false;
			}
		}

		if (is_selected)
		{
			ImGui::PopStyleColor(3);
		}
	}
	ImGui::Unindent(4.0f);
	ImGui::EndChild();
	// Draw bevel outside child
	const ImVec2 min = ImGui::GetItemRectMin();
	const ImVec2 max = ImGui::GetItemRectMax();
	AmigaBevel(ImVec2(min.x - 1, min.y - 1), ImVec2(max.x + 1, max.y + 1), false);

	// Define a fixed width for labels to align input fields
	const float label_width = BUTTON_WIDTH * 1.2f;

	ImGui::AlignTextToFramePadding();
	ImGui::Text("Search:");
	ImGui::SameLine(label_width);
	AmigaInputText("##Search", search_text, sizeof(search_text));
	ImGui::SameLine();
	if (search_text[0] == '\0') ImGui::BeginDisabled();
	if (AmigaButton("X"))
		search_text[0] = '\0';
	if (search_text[0] == '\0') ImGui::EndDisabled();

	ImGui::AlignTextToFramePadding();
	ImGui::Text("Name:");
	ImGui::SameLine(label_width);
	AmigaInputText("##Name", name, MAX_DPATH);

	ImGui::AlignTextToFramePadding();
	ImGui::Text("Description:");
	ImGui::SameLine(label_width);
	AmigaInputText("##Description", desc, MAX_DPATH);

	ImGui::Spacing();

	if (AmigaButton(ICON_FA_UPLOAD " Load", ImVec2(BUTTON_WIDTH, BUTTON_HEIGHT)))
	{
		if (selected != -1)
		{
			target_cfgfile_load(&changed_prefs, ConfigFilesList[selected]->FullPath, CONFIG_TYPE_DEFAULT, 0);
			strncpy(last_active_config, ConfigFilesList[selected]->Name, MAX_DPATH);
			gui_config_mark_clean();
		}
	}
	ImGui::SameLine();
	if (strlen(name) == 0) ImGui::BeginDisabled();
	if (AmigaButton(ICON_FA_FLOPPY_DISK " Save", ImVec2(BUTTON_WIDTH, BUTTON_HEIGHT)))
	{
		char filename[MAX_DPATH];
		char config_path[MAX_DPATH];
		get_configuration_path(config_path, MAX_DPATH);
		snprintf(filename, MAX_DPATH, "%s%s.uae", config_path, name);
		snprintf(changed_prefs.description, 256, "%s", desc);
		if (cfgfile_save(&changed_prefs, filename, 0))
		{
			write_log("Config save: SUCCESS\n");
			snprintf(last_active_config, MAX_DPATH, "%s", name);
			gui_config_mark_clean();
			ReadConfigFileList();
			// Re-select the saved file
			for (int i = 0; i < ConfigFilesList.size(); ++i) {
				if (strcmp(ConfigFilesList[i]->Name, name) == 0) {
					selected = i;
					break;
				}
			}
		}
		else
		{
			write_log("Config save: FAILED for '%s'\n", filename);
		}
	}
	if (strlen(name) == 0) ImGui::EndDisabled();
	ImGui::SameLine();
	if (AmigaButton(ICON_FA_FLOPPY_DISK " Save As...", ImVec2(BUTTON_WIDTH, BUTTON_HEIGHT)))
	{
		std::string config_dir = get_configuration_path();
		OpenFileDialogKey("CONFIG_SAVE_AS", "Save Configuration As", "UAE Config (*.uae){.uae}", config_dir, true);
	}
	{
		std::string save_as_path;
		if (ConsumeFileDialogResultKey("CONFIG_SAVE_AS", save_as_path))
		{
			if (!save_as_path.empty())
			{
				if (save_as_path.size() < 4 ||
					strcasecmp(save_as_path.c_str() + save_as_path.size() - 4, ".uae") != 0)
				{
					save_as_path += ".uae";
				}
				snprintf(changed_prefs.description, 256, "%s", desc);
				if (cfgfile_save(&changed_prefs, save_as_path.c_str(), 0))
				{
					write_log("Config save as: SUCCESS '%s'\n", save_as_path.c_str());
					ReadConfigFileList();
					char saved_name[MAX_DPATH];
					extract_filename(save_as_path.c_str(), saved_name);
					remove_file_extension(saved_name);
					snprintf(last_active_config, MAX_DPATH, "%s", saved_name);
					gui_config_mark_clean();
					for (int i = 0; i < static_cast<int>(ConfigFilesList.size()); ++i)
					{
						if (strcmp(ConfigFilesList[i]->Name, saved_name) == 0)
						{
							selected = i;
							break;
						}
					}
				}
				else
				{
					write_log("Config save as: FAILED for '%s'\n", save_as_path.c_str());
				}
			}
		}
	}
	ImGui::SameLine();
	if (selected == -1) ImGui::BeginDisabled();
	if (AmigaButton(ICON_FA_TRASH_CAN " Delete", ImVec2(BUTTON_WIDTH, BUTTON_HEIGHT)))
	{
		if (selected != -1)
			ImGui::OpenPopup("Delete Configuration");
	}
	if (selected == -1) ImGui::EndDisabled();

	if (ImGui::BeginPopupModal("Delete Configuration", NULL, ImGuiWindowFlags_AlwaysAutoResize))
	{
		ImGui::Text("Do you want to delete '%s'?", ConfigFilesList[selected]->Name);
		ImGui::Separator();

		if (AmigaButton(ICON_FA_CHECK " Yes", ImVec2(BUTTON_WIDTH, BUTTON_HEIGHT)))
		{
			remove(ConfigFilesList[selected]->FullPath);
			ReadConfigFileList();
			selected = -1;
			name[0] = '\0';
			desc[0] = '\0';
			ImGui::CloseCurrentPopup();
		}
		ImGui::SetItemDefaultFocus();
		ImGui::SameLine();
		if (AmigaButton(ICON_FA_XMARK " No", ImVec2(BUTTON_WIDTH, BUTTON_HEIGHT)))
		{
			ImGui::CloseCurrentPopup();
		}
		ImGui::EndPopup();
	}
}
