package gui

import "core:fmt"
import "core:strconv"
import "core:strings"
import rl "vendor:raylib"
import "../adapters"
import "../core"
import "../shared"
import "../ui"

action_generate_local_script :: proc(controller: ^ui.App_Controller, pages: int) -> string {
	story := controller.state.story_idea
	if len(story) == 0 {
		story = "A local GUI adventure"
	}
	script := build_local_script(story, pages)
	core.dispose_script(&controller.state.script)
	controller.state.script = script
	controller.state.characters = controller.state.script.characters
	controller.active_screen = .Script
	controller.state.workflow.current_step = .Script_Review
	return "Generated local script"
}

action_generate_deepseek_script :: proc(controller: ^ui.App_Controller, pages: int) -> string {
	cfg := shared.load_config()
	if len(cfg.deepseek_api_key) == 0 {
		return "DeepSeek key missing (set DEEPSEEK_API_KEY)"
	}
	opts := adapters.Generate_Script_Options{
		story_idea = controller.state.story_idea,
		genre = controller.state.story_genre,
		art_style = controller.state.art_style,
		num_pages = pages,
		audience = controller.state.target_audience,
	}
	script, gerr := adapters.generate_comic_script_stub(cfg, opts)
	if !shared.is_ok(gerr) {
		return fmt.aprintf("DeepSeek script failed: %s", gerr.message)
	}
	core.dispose_script(&controller.state.script)
	controller.state.script = script
	controller.state.characters = controller.state.script.characters
	controller.active_screen = .Script
	controller.state.workflow.current_step = .Script_Review
	return "Generated DeepSeek script"
}

action_generate_local_panels :: proc(controller: ^ui.App_Controller) -> string {
	panels := collect_script_panels(controller.state.script)
	defer delete(panels)
	if len(panels) == 0 {
		return "No script panels available"
	}
	images, ierr := build_local_panel_images(panels)
	if !shared.is_ok(ierr) {
		return ierr.message
	}
	for _, img in controller.state.panel_images {
		delete(img.url)
		delete(img.prompt)
	}
	delete(controller.state.panel_images)
	controller.state.panel_images = images
	controller.active_screen = .Panels
	return "Generated local panels"
}

action_regenerate_panel :: proc(controller: ^ui.App_Controller, panel_id: string) -> string {
	panels := collect_script_panels(controller.state.script)
	defer delete(panels)
	
	target_panel: core.Panel
	found := false
	for p in panels {
		if p.panel_id == panel_id {
			target_panel = p
			found = true
			break
		}
	}
	if !found {
		return "Panel not found in script"
	}

	single := make([]core.Panel, 1)
	single[0] = target_panel
	defer delete(single)

	images, ierr := build_local_panel_images(single)
	if !shared.is_ok(ierr) {
		if controller.state.panel_errors == nil {
			controller.state.panel_errors = make(map[string]string)
		}
		controller.state.panel_errors[panel_id] = strings.clone(ierr.message)
		return "Panel generation failed"
	}

	if img, has := images[panel_id]; has {
		if old, exists := controller.state.panel_images[panel_id]; exists {
			delete(old.url)
			delete(old.prompt)
		}
		if controller.state.panel_images == nil {
			controller.state.panel_images = make(map[string]core.Panel_Image)
		}
		controller.state.panel_images[panel_id] = img
		
		if err_msg, err_exists := controller.state.panel_errors[panel_id]; err_exists {
			delete(err_msg)
			delete_key(&controller.state.panel_errors, panel_id)
		}
	}
	delete(images) // free the map shell returned by build_local_panel_images

	return "Regenerated panel"
}

action_layout_auto :: proc(controller: ^ui.App_Controller) -> string {
	panels := collect_script_panels(controller.state.script)
	defer delete(panels)
	if len(panels) == 0 {
		return "No script panels for layout"
	}
	core.dispose_page_layouts(&controller.state.page_layouts)
	controller.state.page_layouts = core.auto_layout_pages(panels, controller.state.page_size, controller.state.story_genre, "")
	controller.active_screen = .Layout
	controller.state.workflow.current_step = .Layout
	return "Auto layout generated"
}

action_regenerate_page_layout :: proc(controller: ^ui.App_Controller, page_num: int) -> string {
	if page_num < 0 || page_num >= len(controller.state.page_layouts) {
		return "Invalid layout page"
	}

	layout := &controller.state.page_layouts[page_num]
	panel_count := len(layout.panels)
	if panel_count == 0 {
		return "Page has no panels"
	}

	// For a simple visible regenerate effect, pick a random pattern that fits
	pattern_ids := []string{
		"single-splash", "grid-2x2", "grid-3x3", "dynamic-action",
		"manga-spread", "dialogue-heavy", "cinematic-widescreen",
	}
	
	// Just pick the next valid pattern in the list (or wrap around)
	start_idx := 0
	for id, i in pattern_ids {
		if id == layout.pattern_id {
			start_idx = i
			break
		}
	}
	
	new_pattern_id := layout.pattern_id
	for i in 1..=len(pattern_ids) {
		idx := (start_idx + i) % len(pattern_ids)
		candidate := pattern_ids[idx]
		if core.pattern_max_panels(candidate) >= panel_count {
			new_pattern_id = candidate
			break
		}
	}

	pattern := core.get_layout_pattern_by_id(new_pattern_id)
	layout.pattern_id = new_pattern_id
	for i in 0..<panel_count {
		cell_index := i
		if cell_index >= len(pattern.cells) {
			cell_index = len(pattern.cells) - 1
		}
		layout.panels[i].layout_cell = pattern.cells[cell_index]
	}

	return "Layout page regenerated"
}

export_format_name :: proc(f: core.Export_Format) -> string {
	switch f {
	case .PDF: return "PDF"
	case .PNG: return "PNG"
	case .CBZ: return "CBZ"
	}
	return "PDF"
}

parse_pages_or_default :: proc(s: string, def: int) -> int {
	v, ok := strconv.parse_int(strings.trim_space(s))
	if !ok || v <= 0 {
		return def
	}
	return v
}

parse_autosave_interval :: proc(s: string, def: int) -> int {
	v, ok := strconv.parse_int(strings.trim_space(s))
	if !ok {
		return def
	}
	if v < 5 {
		return 5
	}
	if v > 300 {
		return 300
	}
	return v
}

set_autosave_interval_text :: proc(dst: ^string, seconds: int) -> string {
	v := seconds
	if v < 5 {
		v = 5
	}
	if v > 300 {
		v = 300
	}
	dst^ = fmt.aprintf("%d", v)
	return fmt.aprintf("Autosave interval: %ds", v)
}

yn :: proc(v: bool) -> string {
	if v {
		return "yes"
	}
	return "no"
}

toggle_summary_show :: proc(active_screen: ui.App_Screen, opts: ^Summary_View_Options) -> string {
	#partial switch active_screen {
	case .Script:
		opts.script_show_all = !opts.script_show_all
		return fmt.aprintf("Script summary show-all: %s", yn(opts.script_show_all))
	case .Layout:
		opts.layout_show_all = !opts.layout_show_all
		return fmt.aprintf("Layout summary show-all: %s", yn(opts.layout_show_all))
	}
	return "Summary show toggle unavailable on this screen"
}

toggle_summary_sort :: proc(active_screen: ui.App_Screen, opts: ^Summary_View_Options) -> string {
	#partial switch active_screen {
	case .Script:
		opts.script_desc = !opts.script_desc
		sort_name := "asc"
		if opts.script_desc {
			sort_name = "desc"
		}
		return fmt.aprintf("Script summary sort: %s", sort_name)
	case .Layout:
		opts.layout_desc = !opts.layout_desc
		sort_name := "asc"
		if opts.layout_desc {
			sort_name = "desc"
		}
		return fmt.aprintf("Layout summary sort: %s", sort_name)
	}
	return "Summary sort toggle unavailable on this screen"
}

toggle_summary_show_if_supported :: proc(active_screen: ui.App_Screen, opts: ^Summary_View_Options) -> string {
	if active_screen == .Script || active_screen == .Layout {
		return toggle_summary_show(active_screen, opts)
	}
	return ""
}

toggle_summary_sort_if_supported :: proc(active_screen: ui.App_Screen, opts: ^Summary_View_Options) -> string {
	if active_screen == .Script || active_screen == .Layout {
		return toggle_summary_sort(active_screen, opts)
	}
	return ""
}

reset_project_session :: proc(controller: ^ui.App_Controller, is_dirty: ^bool, last_autosave_at: ^f64, touch_time: bool) -> string {
	core.dispose_state(&controller.state)
	controller.state = core.new_initial_state()
	controller.active_screen = ui.screen_from_workflow(controller.state.workflow.current_step)
	is_dirty^ = false
	if touch_time {
		last_autosave_at^ = rl.GetTime()
	}
	return "Reset project"
}

open_project_session :: proc(controller: ^ui.App_Controller, project_path, export_path: ^string, export_format: core.Export_Format, is_dirty: ^bool, last_autosave_at: ^f64) -> string {
	normalize_project_path_field(project_path)
	loaded, lerr := adapters.load_project(project_path^)
	if !shared.is_ok(lerr) {
		return lerr.message
	}
	core.dispose_state(&controller.state)
	controller.state = loaded
	controller.active_screen = ui.screen_from_workflow(controller.state.workflow.current_step)
	sync_export_path_to_project_dir(project_path^, export_path, export_format)
	is_dirty^ = false
	last_autosave_at^ = rl.GetTime()
	return fmt.aprintf("Opened project: %s (export -> %s)", project_path^, export_path^)
}

resolve_confirm_action_with_message :: proc(action: Pending_Confirm_Action, controller: ^ui.App_Controller, project_path, export_path: ^string, export_format: core.Export_Format, is_dirty: ^bool, last_autosave_at: ^f64) -> string {
	switch action {
	case .Reset_Project:
		return reset_project_session(controller, is_dirty, last_autosave_at, true)
	case .Open_Project:
		return open_project_session(controller, project_path, export_path, export_format, is_dirty, last_autosave_at)
	case .None:
		return "No pending destructive action"
	}
	return "No pending destructive action"
}

save_project_session_with_message :: proc(project_path: ^string, state: core.Comic_State, is_dirty: ^bool, last_autosave_at, last_save_at: ^f64, success_prefix: string) -> string {
	normalize_project_path_field(project_path)
	err := adapters.save_project(project_path^, state)
	if !shared.is_ok(err) {
		return err.message
	}
	is_dirty^ = false
	last_autosave_at^ = rl.GetTime()
	last_save_at^ = last_autosave_at^
	return fmt.aprintf("%s: %s", success_prefix, project_path^)
}

action_export :: proc(controller: ^ui.App_Controller, export_path: string, export_format: core.Export_Format) -> string {
	opts := adapters.Export_Options{format = export_format, page_size = controller.state.page_size, dpi = 300, quality = 90}
	err := adapters.export_comic_stub(export_path, controller.state.page_layouts, controller.state.panel_images, opts)
	if !shared.is_ok(err) {
		return err.message
	}
	controller.active_screen = .Export
	controller.state.workflow.current_step = .Complete
	controller.state.export_format = export_format
	return fmt.aprintf("Exported %s", export_format_name(export_format))
}

gui_next_hint_with_source :: proc(controller: ui.App_Controller, use_deepseek_script: bool) -> string {
	if len(controller.state.script.pages) == 0 {
		if use_deepseek_script {
			return "generate script"
		}
		return "generate script local"
	}
	if len(controller.state.panel_images) == 0 {
		return "generate panels local"
	}
	if len(controller.state.page_layouts) == 0 {
		return "layout auto"
	}
	return "export pdf"
}

gui_next_hint :: proc(controller: ui.App_Controller) -> string {
	return gui_next_hint_with_source(controller, false)
}

action_run_next :: proc(controller: ^ui.App_Controller, export_path: string, export_format: core.Export_Format, script_pages: int, use_deepseek_script: bool) -> string {
	hint := gui_next_hint_with_source(controller^, use_deepseek_script)
	switch hint {
	case "generate script":
		return action_generate_deepseek_script(controller, script_pages)
	case "generate script local":
		return action_generate_local_script(controller, script_pages)
	case "generate panels local":
		return action_generate_local_panels(controller)
	case "layout auto":
		return action_layout_auto(controller)
	case "export pdf":
		return action_export(controller, export_path, export_format)
	}
	return "No next action"
}

action_run_auto_all_local :: proc(controller: ^ui.App_Controller, export_path: string, export_format: core.Export_Format, script_pages: int, use_deepseek_script: bool) -> string {
	for _ in 0..<4 {
		msg := action_run_next(controller, export_path, export_format, script_pages, use_deepseek_script)
		if controller.active_screen == .Export {
			return fmt.aprintf("Auto-all complete: %s", msg)
		}
	}
	return "Auto-all could not complete"
}

run_script_action :: proc(controller: ^ui.App_Controller, pages_count: int, use_deepseek_script: bool, is_dirty: ^bool) -> string {
	is_dirty^ = true
	if use_deepseek_script {
		return action_generate_deepseek_script(controller, pages_count)
	}
	return action_generate_local_script(controller, pages_count)
}

run_panels_action :: proc(controller: ^ui.App_Controller, can_generate_panels: bool, is_dirty: ^bool) -> string {
	if !can_generate_panels {
		return "Generate script before panels"
	}
	is_dirty^ = true
	return action_generate_local_panels(controller)
}

run_layout_action :: proc(controller: ^ui.App_Controller, can_layout: bool, is_dirty: ^bool) -> string {
	if !can_layout {
		return "Generate panels before layout"
	}
	is_dirty^ = true
	return action_layout_auto(controller)
}

run_export_action :: proc(controller: ^ui.App_Controller, export_path: ^string, export_format: core.Export_Format, can_export: bool, is_dirty: ^bool, last_export_at: ^f64) -> string {
	normalize_export_path_field(export_path, export_format)
	if !can_export {
		return "Export blocked: generate panels + layout first"
	}
	msg := action_export(controller, export_path^, export_format)
	is_dirty^ = true
	if strings.has_prefix(msg, "Exported ") {
		last_export_at^ = rl.GetTime()
	}
	return msg
}

run_next_action :: proc(controller: ^ui.App_Controller, export_path: ^string, export_format: core.Export_Format, pages_count: int, use_deepseek_script: bool, is_dirty: ^bool, last_export_at: ^f64) -> string {
	normalize_export_path_field(export_path, export_format)
	msg := action_run_next(controller, export_path^, export_format, pages_count, use_deepseek_script)
	is_dirty^ = true
	if controller.active_screen == .Export {
		last_export_at^ = rl.GetTime()
	}
	return msg
}

run_auto_all_action :: proc(controller: ^ui.App_Controller, export_path: ^string, export_format: core.Export_Format, pages_count: int, use_deepseek_script: bool, is_dirty: ^bool, last_export_at: ^f64) -> string {
	normalize_export_path_field(export_path, export_format)
	msg := action_run_auto_all_local(controller, export_path^, export_format, pages_count, use_deepseek_script)
	is_dirty^ = true
	if controller.active_screen == .Export {
		last_export_at^ = rl.GetTime()
	}
	return msg
}

run_auto_all_save_action :: proc(controller: ^ui.App_Controller, project_path, export_path: ^string, export_format: core.Export_Format, pages_count: int, use_deepseek_script: bool, is_dirty: ^bool, last_export_at, last_autosave_at, last_save_at: ^f64) -> string {
	normalize_export_path_field(export_path, export_format)
	msg := action_run_auto_all_local(controller, export_path^, export_format, pages_count, use_deepseek_script)
	if controller.active_screen == .Export {
		last_export_at^ = rl.GetTime()
		return save_project_session_with_message(project_path, controller.state, is_dirty, last_autosave_at, last_save_at, "Auto-all + saved")
	}
	return msg
}

set_export_format_with_message :: proc(export_format: ^core.Export_Format, export_path: ^string, next: core.Export_Format, is_dirty: ^bool) -> string {
	export_format^ = next
	export_path^ = export_path_for_format(export_path^, export_format^)
	is_dirty^ = true
	return fmt.aprintf("Export format: %s (%s)", export_format_name(export_format^), export_path^)
}

autosave_tick_with_message :: proc(project_path: ^string, state: core.Comic_State, autosave_enabled: bool, is_dirty: ^bool, last_autosave_at: ^f64, last_save_at: ^f64, autosave_interval_s: f64) -> string {
	if !autosave_enabled || !is_dirty^ {
		return ""
	}
	now := rl.GetTime()
	if now-last_autosave_at^ < autosave_interval_s {
		return ""
	}
	normalize_project_path_field(project_path)
	err := adapters.save_project(project_path^, state)
	last_autosave_at^ = now
	if shared.is_ok(err) {
		is_dirty^ = false
		last_save_at^ = now
		return fmt.aprintf("Autosaved: %s", project_path^)
	}
	return fmt.aprintf("Autosave failed: %s", err.message)
}

action_add_bubble :: proc(controller: ^ui.App_Controller, panel_id: string) -> string {
	id := fmt.aprintf("bubble_%s_new", panel_id)
	bubble := core.Speech_Bubble{
		id = id,
		panel_id = panel_id,
		type = .Normal,
		text = "New bubble",
		position = core.Position{x = 0.1, y = 0.1},
		size = core.Size{width = 120, height = 40},
		tail_direction = "bottom",
		tail_target = core.Position{x = 0.5, y = 0.5},
		style = core.DEFAULT_BUBBLE_STYLE,
		speaker_id = "",
	}

	if controller.state.speech_bubbles == nil {
		controller.state.speech_bubbles = make(map[string][]core.Speech_Bubble)
	}

	existing: [dynamic]core.Speech_Bubble
	if slice, ok := controller.state.speech_bubbles[panel_id]; ok {
		for b in slice {
			append(&existing, b)
		}
	}
	append(&existing, bubble)
	controller.state.speech_bubbles[panel_id] = existing[:]

	return "Added bubble"
}

action_delete_bubble :: proc(controller: ^ui.App_Controller, panel_id: string, bubble_idx: int) -> string {
	if controller.state.speech_bubbles == nil {
		return "No bubbles to delete"
	}
	slice, ok := controller.state.speech_bubbles[panel_id]
	if !ok || bubble_idx < 0 || bubble_idx >= len(slice) {
		return "Bubble not found"
	}

	// Remove by shifting elements
	new_slice: [dynamic]core.Speech_Bubble
	for i in 0..<len(slice) {
		if i != bubble_idx {
			append(&new_slice, slice[i])
		}
	}
	if len(new_slice) == 0 {
		delete_key(&controller.state.speech_bubbles, panel_id)
	} else {
		controller.state.speech_bubbles[panel_id] = new_slice[:]
	}

	return "Deleted bubble"
}

action_auto_place_bubbles_for_panel :: proc(controller: ^ui.App_Controller, panel_id: string, layout: core.Page_Layout) -> string {
	// Find the script panel to get dialogue
	script_panel: core.Panel
	found := false
	for page in controller.state.script.pages {
		for p in page.panels {
			if p.panel_id == panel_id {
				script_panel = p
				found = true
				break
			}
		}
		if found { break }
	}
	if !found {
		return "Script panel not found for auto-place"
	}

	// Find the layout cell for this panel to get dimensions
	cell_w: f32 = 1
	cell_h: f32 = 1
	for lp in layout.panels {
		if lp.panel_id == panel_id {
			cell_w = lp.layout_cell.w
			cell_h = lp.layout_cell.h
			break
		}
	}

	panel_w := cell_w * f32(layout.width)
	panel_h := cell_h * f32(layout.height)

	bubbles := core.auto_place_panel_bubbles(script_panel, panel_w, panel_h)
	defer delete(bubbles)

	if len(bubbles) == 0 {
		return "No dialogue to auto-place"
	}

	if controller.state.speech_bubbles == nil {
		controller.state.speech_bubbles = make(map[string][]core.Speech_Bubble)
	}
	controller.state.speech_bubbles[panel_id] = bubbles

	return fmt.tprintf("Auto-placed %d bubbles", len(bubbles))
}

action_update_bubble :: proc(controller: ^ui.App_Controller, panel_id: string, bubble_idx: int, new_type: core.Bubble_Type, new_text: string) -> string {
	if controller.state.speech_bubbles == nil {
		return "No bubbles to update"
	}
	slice, ok := controller.state.speech_bubbles[panel_id]
	if !ok || bubble_idx < 0 || bubble_idx >= len(slice) {
		return "Bubble not found"
	}

	// Copy to dynamic slice, update, then reassign
	new_slice: [dynamic]core.Speech_Bubble
	for i in 0..<len(slice) {
		b := slice[i]
		if i == bubble_idx {
			if new_text != "" {
				b.text = new_text
			}
			b.type = new_type
		}
		append(&new_slice, b)
	}
	controller.state.speech_bubbles[panel_id] = new_slice[:]
	return "Bubble updated"
}

action_generate_character_reference :: proc(controller: ^ui.App_Controller, character_id: string) -> string {
	cfg := shared.load_config()
	if len(cfg.fal_api_key) == 0 {
		return "FAL_API_KEY is missing"
	}

	// Find the character
	target_char: core.Character
	found := false
	for c in controller.state.characters {
		if c.id == character_id {
			target_char = c
			found = true
			break
		}
	}
	if !found {
		return "Character not found"
	}

	url, err := adapters.generate_character_reference_stub(cfg, target_char, controller.state.art_style)
	if !shared.is_ok(err) {
		return err.message
	}

	// Update character with reference image
	new_chars: [dynamic]core.Character
	for c in controller.state.characters {
		new_c := c
		if c.id == character_id {
			new_c.reference_image_url = url
		}
		append(&new_chars, new_c)
	}
	delete(controller.state.characters)
	controller.state.characters = new_chars[:]

	return fmt.tprintf("Generated reference for %s", target_char.name)
}

action_generate_character_sheet :: proc(controller: ^ui.App_Controller, character_id: string) -> string {
	cfg := shared.load_config()
	if len(cfg.fal_api_key) == 0 {
		return "FAL_API_KEY is missing"
	}

	// Find the character
	target_char: core.Character
	found := false
	for c in controller.state.characters {
		if c.id == character_id {
			target_char = c
			found = true
			break
		}
	}
	if !found {
		return "Character not found"
	}

	sheet_urls, err := adapters.generate_character_sheet_stub(cfg, target_char, controller.state.art_style)
	if !shared.is_ok(err) {
		return err.message
	}

	// Update character with sheet URLs
	new_chars: [dynamic]core.Character
	for c in controller.state.characters {
		new_c := c
		if c.id == character_id {
			// Free old sheet URLs
			for u in c.character_sheet_urls {
				delete(u)
			}
			delete(c.character_sheet_urls)
			new_c.character_sheet_urls = sheet_urls
		}
		append(&new_chars, new_c)
	}
	delete(controller.state.characters)
	controller.state.characters = new_chars[:]

	return fmt.tprintf("Generated %d-pose sheet for %s", len(sheet_urls), target_char.name)
}

action_update_bubble_text :: proc(controller: ^ui.App_Controller, bubble_id: string, new_text: string) -> string {
	if controller.state.speech_bubbles == nil {
		return "No bubbles to update"
	}

	for panel_id, slice in controller.state.speech_bubbles {
		for i in 0..<len(slice) {
			if slice[i].id == bubble_id {
				new_slice: [dynamic]core.Speech_Bubble
				for j in 0..<len(slice) {
					b := slice[j]
					if j == i {
						b.text = new_text
					}
					append(&new_slice, b)
				}
				controller.state.speech_bubbles[panel_id] = new_slice[:]
				return "Bubble text updated"
			}
		}
	}
	return "Bubble not found"
}

action_reposition_bubble :: proc(controller: ^ui.App_Controller, bubble_id: string, x, y: f32) -> string {
	if controller.state.speech_bubbles == nil {
		return "No bubbles to reposition"
	}

	for panel_id, slice in controller.state.speech_bubbles {
		for i in 0..<len(slice) {
			if slice[i].id == bubble_id {
				new_slice: [dynamic]core.Speech_Bubble
				for j in 0..<len(slice) {
					b := slice[j]
					if j == i {
						b.position = core.Position{x = x, y = y}
					}
					append(&new_slice, b)
				}
				controller.state.speech_bubbles[panel_id] = new_slice[:]
				return "Bubble repositioned"
			}
		}
	}
	return "Bubble not found"
}

action_reset_bubble_position :: proc(controller: ^ui.App_Controller, bubble_id: string) -> string {
	if controller.state.speech_bubbles == nil {
		return "No bubbles to reset"
	}

	for panel_id, slice in controller.state.speech_bubbles {
		for i in 0..<len(slice) {
			if slice[i].id == bubble_id {
				new_slice: [dynamic]core.Speech_Bubble
				for j in 0..<len(slice) {
					b := slice[j]
					if j == i {
						b.position = core.Position{x = 0, y = 0}
					}
					append(&new_slice, b)
				}
				controller.state.speech_bubbles[panel_id] = new_slice[:]
				return "Bubble position reset"
			}
		}
	}
	return "Bubble not found"
}
