package tui

import (
	"os"
	"path/filepath"
	"testing"

	tea "github.com/charmbracelet/bubbletea"
)

func TestInlineConversionStateMachine(t *testing.T) {
	// Find a test PNG file
	testFile := filepath.Join("..", "..", "..", "public", "logo.png")
	if _, err := os.Stat(testFile); err != nil {
		t.Skipf("test file not found: %s", testFile)
	}

	outDir := t.TempDir()
	m := New([]string{testFile}, outDir)
	m.width = 80
	m.height = 24

	// Verify initial state
	if len(m.files) != 1 {
		t.Fatalf("expected 1 file, got %d", len(m.files))
	}
	if m.state != stateFileList {
		t.Fatalf("expected stateFileList, got %d", m.state)
	}
	if m.files[0].status != "idle" {
		t.Fatalf("expected idle status, got %s", m.files[0].status)
	}

	// Select the file (default is now false)
	m.files[0].selected = true

	t.Logf("File: %s -> %s (selected: %v)", m.files[0].name, m.files[0].targetFormat, m.files[0].selected)

	// Simulate pressing 'c' to start conversion
	newModel, cmd := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'c'}})
	m = newModel.(Model)

	if m.state != stateFileList {
		t.Fatalf("expected to stay on stateFileList during conversion, got %d", m.state)
	}
	if m.totalToConv != 1 {
		t.Fatalf("expected totalToConv=1, got %d", m.totalToConv)
	}
	if m.files[0].status != "converting" {
		t.Fatalf("expected 'converting' status after pressing c, got '%s'", m.files[0].status)
	}

	t.Log("Status correctly set to 'converting' — inline update works!")

	// Execute the conversion command
	if cmd == nil {
		t.Fatal("expected a conversion command, got nil")
	}
	msg := cmd()

	// Process the result
	newModel, _ = m.Update(msg)
	m = newModel.(Model)

	// Should stay on stateFileList after conversion (not stateResults)
	if m.state != stateFileList {
		t.Fatalf("expected stateFileList after conversion, got %d", m.state)
	}
	if m.files[0].status != "done" {
		t.Fatalf("expected 'done' status, got '%s' (error: %s)", m.files[0].status, m.files[0].error)
	}
	if m.converted != 1 {
		t.Fatalf("expected converted=1, got %d", m.converted)
	}

	// Check output file exists
	info, err := os.Stat(m.files[0].outputPath)
	if err != nil {
		t.Fatalf("output file not found: %v", err)
	}

	t.Logf("Conversion complete: %s (%d bytes)", m.files[0].outputPath, info.Size())

	t.Log("State machine verified: idle -> converting -> done (stays on file list)")
}

func TestDeleteOutput(t *testing.T) {
	testFile := filepath.Join("..", "..", "..", "public", "logo.png")
	if _, err := os.Stat(testFile); err != nil {
		t.Skipf("test file not found: %s", testFile)
	}

	outDir := t.TempDir()
	m := New([]string{testFile}, outDir)
	m.width = 80
	m.height = 24

	// Select the file (default is now false)
	m.files[0].selected = true

	// Convert the file
	newModel, cmd := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'c'}})
	m = newModel.(Model)
	msg := cmd()
	newModel, _ = m.Update(msg)
	m = newModel.(Model)

	// Should stay on stateFileList
	if m.state != stateFileList {
		t.Fatalf("expected stateFileList, got %d", m.state)
	}
	if m.files[0].status != "done" {
		t.Fatalf("expected done, got %s", m.files[0].status)
	}

	// Test pressing 'r' to reset the done file back to idle
	newModel, _ = m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'r'}})
	m = newModel.(Model)

	if m.files[0].status != "idle" {
		t.Fatalf("expected 'idle' status after pressing r, got '%s'", m.files[0].status)
	}

	t.Log("Reset works: status reset from done back to 'idle'")
}

func TestViewRendersDuringConversion(t *testing.T) {
	testFile := filepath.Join("..", "..", "..", "public", "logo.png")
	if _, err := os.Stat(testFile); err != nil {
		t.Skipf("test file not found: %s", testFile)
	}

	m := New([]string{testFile}, t.TempDir())
	m.width = 80
	m.height = 24

	// Render initial state
	view := m.View()
	if view == "" {
		t.Fatal("empty view")
	}
	if !containsStr(view, "idle") {
		t.Error("initial view should contain 'idle' status")
	}
	if !containsStr(view, "Select files to convert") {
		t.Error("initial view should contain 'Select files to convert'")
	}

	// Select a file and start conversion
	m.files[0].selected = true

	// Start conversion
	newModel, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'c'}})
	m = newModel.(Model)

	view = m.View()
	if !containsStr(view, "converting") {
		t.Error("view during conversion should contain 'converting' status")
	}
	if !containsStr(view, "Converting 0/1") {
		t.Errorf("view during conversion should show progress, got:\n%s", view)
	}

	t.Log("View renders correctly during conversion")
}

func containsStr(haystack, needle string) bool {
	return len(haystack) > 0 && len(needle) > 0 && contains(haystack, needle)
}

func contains(s, substr string) bool {
	for i := 0; i <= len(s)-len(substr); i++ {
		if s[i:i+len(substr)] == substr {
			return true
		}
	}
	return false
}
