package gui

import clay "clay:."
import "core:fmt"
import "../core"
import rl "vendor:raylib"

// ─── Script Detail Panel (Clay) ────────────────────────────────────
declare_script_detail :: proc(app: ^GUI_App_State) {
	if clay.UI(clay.ID("ScriptDetailCard"))(clay_card_style()) {
		clay_title_text("Script Detail")

		page_count := len(app.controller.state.script.pages)
		if page_count == 0 {
			clay_muted_text("No script pages yet. Run Generate Script Local.")
			return
		}

		idx := clamp_script_cursor(page_count, app.summary_opts.script_page_cursor)
		page := app.controller.state.script.pages[idx]

		if clay.UI(clay.ID("ScriptDetailStatRow"))({
			layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({})}, childGap = 8},
		}) {
			declare_stat_chip("Page", idx + 1)
			declare_stat_chip("Panels", len(page.panels))
		}

		clay_body_text(fmt.tprintf("Page #%d", page.page_number), color = CLAY_ACCENT, size = CLAY_FONT_SIZE_SM)

		if clay.UI(clay.ID("ScriptPanelScroll"))({
			layout = {sizing = {width = clay.SizingGrow({}), height = clay.SizingGrow({})}, layoutDirection = .TopToBottom, childGap = 2},
		}) {
			for pn in page.panels {
				desc := pn.description
				if len(desc) == 0 { desc = "(no description)" }
				if clay.UI(clay.ID(fmt.tprintf("ScriptDetailPanel_%d", pn.panel_number)))({
					layout = {layoutDirection = .TopToBottom, padding = {top = 2, right = 4, bottom = 2, left = 4}},
				}) {
					clay_body_text(fmt.tprintf("P%d: %s", pn.panel_number, desc), color = CLAY_TEXT_SECONDARY, size = CLAY_FONT_SIZE_SM)
					if len(pn.dialogue) > 0 {
						clay_body_text(fmt.tprintf("\"%s\"", pn.dialogue[0].text), color = CLAY_TEXT_TERTIARY, size = CLAY_FONT_SIZE_SM)
					}
				}
			}
		}
	}
}

// ─── Panels Detail Panel (Clay) ────────────────────────────────────

// ─── Panels Detail Panel (Clay) ────────────────────────────────────
declare_panels_detail :: proc(app: ^GUI_App_State) {
	if clay.UI(clay.ID("PanelsDetailCard"))(clay_card_style()) {
		clay_title_text("Panel Results")

		panel_count := count_script_panels(app.controller.state.script)
		if panel_count == 0 {
			clay_muted_text("No script panels yet. Generate Script first.")
			return
		}

		idx := clamp_panel_cursor(panel_count, app.summary_opts.panel_cursor)
		panel, page_num, ok := panel_by_flat_index(app.controller.state.script, idx)
		if !ok {
			clay_muted_text("Panel index out of range.")
			return
		}

		status := "missing"
		status_color: clay.Color = CLAY_WARNING
		_, has_img := app.controller.state.panel_images[panel.panel_id]
		_, has_err := app.controller.state.panel_errors[panel.panel_id]
		if has_err {
			status = "error"
			status_color = CLAY_ERROR
		}
		if has_img {
			status = "ready"
			status_color = CLAY_SUCCESS
		}

		if clay.UI(clay.ID("PanelDetailHeader"))({
			layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({})}, childAlignment = {y = .Center}, childGap = 8},
		}) {
			clay_body_text(fmt.tprintf("Panel %d/%d • page %d # %d", idx+1, panel_count, page_num, panel.panel_number), color = status_color, size = CLAY_FONT_SIZE_SM)
			if has_img {
				declare_button_small("btn_panel_regenerate", "Regenerate")
			} else {
				declare_button_small("btn_panel_regenerate", "Generate")
			}
		}

		clay_muted_text(fmt.tprintf("id: %s", panel.panel_id))
		if has_err {
			err_msg, _ := app.controller.state.panel_errors[panel.panel_id]
			clay_body_text(fmt.tprintf("err: %s", err_msg), color = CLAY_ERROR, size = CLAY_FONT_SIZE_SM)
		} else if has_img {
			img := app.controller.state.panel_images[panel.panel_id]
			clay_muted_text(fmt.tprintf("img: %dx%d seed:%d", img.width, img.height, img.seed))
		} else {
			clay_muted_text("img: not generated")
		}

		desc := panel.description
		if len(desc) == 0 { desc = "(no description)" }
		clay_body_text(fmt.tprintf("desc: %s", desc), color = CLAY_TEXT_SECONDARY, size = CLAY_FONT_SIZE_SM)

		if has_img {
			clay_muted_text(fmt.tprintf("src: %s", panel.panel_id))
		}

		if clay.UI(clay.ID("PanelListScroll"))({
			layout = {sizing = {width = clay.SizingGrow({}), height = clay.SizingGrow({})}, layoutDirection = .TopToBottom, childGap = 1},
		}) {
			visible_rows: int = 8
			if visible_rows > panel_count { visible_rows = panel_count }
			start := idx - visible_rows / 2
			if start < 0 { start = 0 }
			end := start + visible_rows
			if end > panel_count { end = panel_count }
			if end - start < visible_rows {
				start = end - visible_rows
				if start < 0 { start = 0 }
			}

			for i in start..<end {
				row_panel, row_page, row_ok := panel_by_flat_index(app.controller.state.script, i)
				if !row_ok { continue }

				mark := "  "
				row_color: clay.Color = CLAY_TEXT_TERTIARY
				if i == idx {
					mark = "> "
					row_color = CLAY_TEXT_BRIGHT
				}

				ready := "missing"
				ready_color: clay.Color = CLAY_TEXT_TERTIARY
				if _, err_exists := app.controller.state.panel_errors[row_panel.panel_id]; err_exists {
					ready = "error"
					ready_color = CLAY_ERROR
				}
				if _, exists := app.controller.state.panel_images[row_panel.panel_id]; exists {
					ready = "ready"
					ready_color = CLAY_SUCCESS
				}

				if clay.UI(clay.ID(fmt.tprintf("panel_row_%d", i)))({
					layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFixed(20)}, padding = {top = 2, left = 4}, childGap = 4},
					backgroundColor = clay.Color{0, 0, 0, 0},
				}) {
					clay.Text(fmt.tprintf("%s%02d p%d#%d", mark, i+1, row_page, row_panel.panel_number), {fontId = CLAY_FONT_BODY, fontSize = CLAY_FONT_SIZE_SM, textColor = row_color})
					clay.Text(ready, {fontId = CLAY_FONT_BODY, fontSize = CLAY_FONT_SIZE_SM, textColor = ready_color})
				}
			}
		}
	}
}

// ─── Layout Detail Panel (Clay) ────────────────────────────────────

// ─── Layout Detail Panel (Clay) ────────────────────────────────────
declare_layout_detail :: proc(app: ^GUI_App_State) {
	if clay.UI(clay.ID("LayoutDetailCard"))(clay_card_style()) {
		clay_title_text("Layout Detail")

		layout_count := len(app.controller.state.page_layouts)
		if layout_count == 0 {
			clay_muted_text("No layouts yet. Use Layout Auto after panels.")
			return
		}

		idx := clamp_layout_cursor(layout_count, app.summary_opts.layout_page_cursor)
		layout_val := app.controller.state.page_layouts[idx]

		if clay.UI(clay.ID("LayoutDetailHeader"))({
			layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({})}, childAlignment = {y = .Center}, childGap = 8},
		}) {
			clay_body_text(fmt.tprintf("Page %d/%d • %s • %d panels", idx+1, layout_count, layout_val.pattern_id, len(layout_val.panels)), color = CLAY_ACCENT, size = CLAY_FONT_SIZE_SM)
			declare_button_small("btn_layout_regen", "Regen")
		}

		val := validate_layout_page(layout_val, app.controller.state.panel_images)
		coverage_ok := val.coverage_pct >= 80 && val.coverage_pct <= 105
		bindings_ok := val.missing_bindings == 0
		bounds_ok := val.bounds_violations == 0

		if clay.UI(clay.ID("LayoutValidationRow"))({
			layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({})}, childGap = 4},
		}) {
			declare_status_badge("val_coverage", fmt.tprintf("Cov: %.0f%%", val.coverage_pct), coverage_ok)
			declare_status_badge("val_bindings", fmt.tprintf("Bind: %d miss", val.missing_bindings), bindings_ok)
			declare_status_badge("val_bounds", fmt.tprintf("Bounds: %d", val.bounds_violations), bounds_ok)
		}

		clay_muted_text(fmt.tprintf("size: %d x %d", layout_val.width, layout_val.height))

		if clay.UI(clay.ID("LayoutDetailContent"))({
			layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingGrow({})}, childGap = 8},
		}) {
			if clay.UI(clay.ID("LayoutWireframe"))({
				layout = {sizing = {width = clay.SizingPercent(40), height = clay.SizingGrow({})}, layoutDirection = .TopToBottom},
				backgroundColor = CLAY_BG_STRIP,
				cornerRadius = clay.CornerRadiusAll(CLAY_RADIUS_SM),
			}) {
				for i in 0..<len(layout_val.panels) {
					cell := layout_val.panels[i].layout_cell
					w_pct := f32(cell.w * 100); if w_pct > 100 { w_pct = 100 } else if w_pct < 0 { w_pct = 0 }
					h_pct := f32(cell.h * 100); if h_pct > 100 { h_pct = 100 } else if h_pct < 0 { h_pct = 0 }
					if clay.UI(clay.ID(fmt.tprintf("wire_cell_%d", i)))({
						layout = {sizing = {width = clay.SizingPercent(w_pct), height = clay.SizingPercent(h_pct)}, padding = {top = 2, left = 2, right = 2, bottom = 2}},
						backgroundColor = CLAY_ACCENT_SURFACE,
						cornerRadius = clay.CornerRadiusAll(2),
						border = {color = CLAY_ACCENT_MUTED, width = clay.BorderOutside(1)},
					}) {
						if cell.w > 0.15 && cell.h > 0.15 {
							clay.Text(fmt.tprintf("%d", layout_val.panels[i].panel_number), {fontId = CLAY_FONT_BODY, fontSize = CLAY_FONT_SIZE_SM, textColor = CLAY_TEXT_SECONDARY})
						}
					}
				}
			}

			if clay.UI(clay.ID("LayoutPageScroll"))({
				layout = {sizing = {width = clay.SizingGrow({}), height = clay.SizingGrow({})}, layoutDirection = .TopToBottom, childGap = 1},
			}) {
				visible_rows: int = 6
				if visible_rows > layout_count { visible_rows = layout_count }
				start := idx - visible_rows / 2
				if start < 0 { start = 0 }
				end := start + visible_rows
				if end > layout_count { end = layout_count }
				if end - start < visible_rows {
					start = end - visible_rows
					if start < 0 { start = 0 }
				}

				for i in start..<end {
					l := app.controller.state.page_layouts[i]
					row_color: clay.Color = CLAY_TEXT_TERTIARY
					if i == idx { row_color = CLAY_TEXT_BRIGHT }

					if clay.UI(clay.ID(fmt.tprintf("layout_row_%d", i)))({
						layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFixed(20)}, padding = {top = 2, left = 4}},
						backgroundColor = clay.Color{0, 0, 0, 0},
					}) {
						mark := "  "
						if i == idx { mark = "> " }
						clay.Text(fmt.tprintf("%s%02d %s (%d)", mark, l.page_number, l.pattern_id, len(l.panels)), {fontId = CLAY_FONT_BODY, fontSize = CLAY_FONT_SIZE_SM, textColor = row_color})
					}
				}
			}
		}
	}
}

// ─── Bubbles Detail Panel (Clay) ────────────────────────────────────

// ─── Bubbles Detail Panel (Clay) ────────────────────────────────────
declare_bubbles_detail :: proc(app: ^GUI_App_State) {
	if clay.UI(clay.ID("BubblesDetailCard"))(clay_card_style()) {
		clay_title_text("Bubble Editor")

		layout_count := len(app.controller.state.page_layouts)
		if layout_count == 0 {
			clay_muted_text("No layouts yet. Run Layout Auto first.")
			return
		}

		page_idx := clamp_layout_cursor(layout_count, app.summary_opts.bubble_page_cursor)
		layout_val := app.controller.state.page_layouts[page_idx]
		panel_count := len(layout_val.panels)

		if panel_count == 0 {
			clay_body_text(fmt.tprintf("Page %d has no panels", layout_val.page_number), color = CLAY_TEXT_SECONDARY, size = CLAY_FONT_SIZE_SM)
			return
		}

		panel_idx := clamp_bubble_cursor(panel_count, app.summary_opts.bubble_panel_cursor)
		panel := layout_val.panels[panel_idx]

		clay_body_text(fmt.tprintf("Page %d/%d • %d panels", page_idx+1, layout_count, panel_count), color = CLAY_ACCENT, size = CLAY_FONT_SIZE_SM)

		if clay.UI(clay.ID("BubblePanelInfo"))({
			layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({})}, childAlignment = {y = .Center}, childGap = 8},
		}) {
			clay_muted_text(fmt.tprintf("Panel %d (id: %s)", panel.panel_number, panel.panel_id))
			declare_button_small("btn_bubble_auto_place", "Auto Place")
		}

		bubbles_for_panel: []core.Speech_Bubble = nil
		if app.controller.state.speech_bubbles != nil {
			if slice, ok := app.controller.state.speech_bubbles[panel.panel_id]; ok {
				bubbles_for_panel = slice
			}
		}
		bubble_count := len(bubbles_for_panel)
		bubble_idx := 0
		if bubble_count > 0 {
			bubble_idx = clamp_bubble_cursor(bubble_count, app.summary_opts.bubble_edit_cursor)
		}

		if clay.UI(clay.ID("BubbleListHeader"))({
			layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({})}, childAlignment = {y = .Center}, childGap = 8},
		}) {
			clay_body_text(fmt.tprintf("Bubbles: %d", bubble_count), color = CLAY_ACCENT, size = CLAY_FONT_SIZE_SM)
			declare_button_small("btn_bubble_add", "Add")
		}

		if clay.UI(clay.ID("BubbleListScroll"))({
			layout = {sizing = {width = clay.SizingGrow({}), height = clay.SizingGrow({})}, layoutDirection = .TopToBottom, childGap = 1},
		}) {
			if bubble_count == 0 {
				clay_muted_text("No bubbles for this panel. Click Add or Auto Place.")
			} else {
				for i in 0..<bubble_count {
					b := bubbles_for_panel[i]
					is_selected: bool = (i == bubble_idx)
					row_color: clay.Color = CLAY_TEXT_TERTIARY
					if is_selected { row_color = CLAY_TEXT_BRIGHT }

					preview := b.text
					if len(preview) > 25 { preview = preview[:25] }
					if len(preview) == 0 { preview = "(empty)" }

					if clay.UI(clay.ID(fmt.tprintf("bubble_row_%d", i)))({
						layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFixed(26)}, padding = {top = 2, left = 4}, childGap = 4, childAlignment = {y = .Center}},
						backgroundColor = clay.Color{0, 0, 0, 0},
					}) {
						mark := "  "
						if is_selected { mark = "> " }
						clay.Text(fmt.tprintf("%s[%s] %s", mark, bubble_type_name(b.type), preview), {fontId = CLAY_FONT_BODY, fontSize = CLAY_FONT_SIZE_SM, textColor = row_color})
						if is_selected {
							declare_button_small(fmt.tprintf("btn_bubble_delete_%d", i), "x")
						}
					}
				}
			}
		}

		if bubble_count > 0 && bubble_idx < bubble_count {
			selected := bubbles_for_panel[bubble_idx]

			if clay.UI(clay.ID("BubbleEditor"))({
				layout = {layoutDirection = .TopToBottom, padding = {top = 4, right = 8, bottom = 4, left = 8}, childGap = 4},
				backgroundColor = CLAY_BG_STRIP,
				cornerRadius = clay.CornerRadiusAll(CLAY_RADIUS_SM),
			}) {
				clay_body_text(fmt.tprintf("Editing: %s", bubble_type_name(selected.type)), color = CLAY_ACCENT, size = CLAY_FONT_SIZE_SM)

				if clay.UI(clay.ID("BubbleTypeRow"))({
					layout = {layoutDirection = .LeftToRight, sizing = {width = clay.SizingGrow({}), height = clay.SizingFit({})}, childGap = 2},
				}) {
					types := []core.Bubble_Type{.Normal, .Thought, .Shout, .Whisper, .Narration, .Sound_Effect}
					for t in types {
						btn_id := fmt.tprintf("btn_btype_%d", int(t))
						if clay.UI(clay.ID(btn_id))({
							layout = {sizing = {width = clay.SizingFit({min = 50, max = 20}), height = clay.SizingFixed(26)}, padding = {top = 2, right = 4, bottom = 2, left = 4}, childAlignment = {x = .Center, y = .Center}},
							backgroundColor = clay_color_for_bubble_type(selected.type == t),
							cornerRadius = clay.CornerRadiusAll(CLAY_RADIUS_SM),
						}) {
							clay.Text(bubble_type_name(t), {fontId = CLAY_FONT_BODY, fontSize = CLAY_FONT_SIZE_SM, textColor = clay_text_color_for_bubble_type(selected.type == t)})
						}
					}
				}

				text_preview := selected.text
				if len(text_preview) > 80 { text_preview = text_preview[:80] }
				clay_muted_text(fmt.tprintf("text: %s", text_preview))
			}
		}
	}
}


clay_color_for_bubble_type :: proc(active: bool) -> clay.Color {
	if active { return CLAY_ACCENT }
	return CLAY_BTN_DEFAULT
}

clay_text_color_for_bubble_type :: proc(active: bool) -> clay.Color {
	if active { return CLAY_TEXT_BRIGHT }
	return CLAY_TEXT_SECONDARY
}

// ─── Action Log (Clay) ─────────────────────────────────────────────

// ─── Action Log (Clay) ─────────────────────────────────────────────
declare_action_log :: proc(app: ^GUI_App_State) {
	if clay.UI(clay.ID("ActionLogCard"))(clay_card_style()) {
		clay_title_text("Action Log")

		// Button row
		if clay.UI(clay.ID("LogBtnRow"))({layout = clay_row_layout()}) {
			declare_button_small("btn_log_reset", "Reset View")
			declare_button_small("btn_log_report", "Session Report")
			declare_button_small("btn_log_copy", "Copy Log")
			declare_button_small("btn_log_diag", "Diagnostics")
			declare_button_small("btn_log_status_copy", "Copy Status")
			declare_button_small("btn_log_clear", "Clear Log")
			declare_button_small("btn_log_diag_copy", "Copy Diag")
		}

		order_label := "newest"
		if app.log_oldest_first { order_label = "oldest" }
		clay_muted_text(fmt.tprintf("View: %d lines, %s first", app.log_show_lines, order_label))

		// Log entries
		if clay.UI(clay.ID("LogScroll"))({
			layout = {sizing = {width = clay.SizingGrow({}), height = clay.SizingGrow({})}, layoutDirection = .TopToBottom, childGap = 2},
		}) {
			max_lines: int = int(app.log_show_lines)
			if max_lines > app.action_log.count {
				max_lines = app.action_log.count
			}
			if max_lines > len(app.action_log.entries) {
				max_lines = len(app.action_log.entries)
			}
			now := rl.GetTime()
			for line in 0 ..< max_lines {
				idx := 0
				if app.log_oldest_first {
					start_idx := app.action_log.count - max_lines
					idx = (start_idx + line) % len(app.action_log.entries)
					if idx < 0 { idx += len(app.action_log.entries) }
				} else {
					idx = (app.action_log.count - 1 - line) % len(app.action_log.entries)
					if idx < 0 { idx += len(app.action_log.entries) }
				}
				age := now - app.action_log.entry_times[idx]
				entry_text := fmt.tprintf("[%2.0fs] %s", age, app.action_log.entries[idx])
				entry_color := CLAY_TEXT_SECONDARY
				if is_error_message(app.action_log.entries[idx]) { entry_color = CLAY_ERROR }
				else if is_warning_message(app.action_log.entries[idx]) { entry_color = CLAY_WARNING }
				else { entry_color = CLAY_SUCCESS }
				clay_body_text(entry_text, color = entry_color, size = CLAY_FONT_SIZE_SM)
			}
		}
	}
}