package tui

import (
	"runtime"

	"github.com/charmbracelet/bubbles/list"

	"gitgud.io/mike/mpv-manager/pkg/config"
	"gitgud.io/mike/mpv-manager/pkg/constants"
	"gitgud.io/mike/mpv-manager/pkg/platform"
)

func (m *Model) setupConfigOptionsList() {
	items := []list.Item{}

	installedApps := config.GetInstalledApps()
	hasMPVApp := hasMPVInstallMethod(installedApps)

	if runtime.GOOS == "windows" {
		hasMPVBinary := false
		for _, app := range installedApps {
			if app.InstallMethod == "mpv-binary" || app.InstallMethod == "mpv-binary-v3" {
				hasMPVBinary = true
				break
			}
		}

		if hasMPVBinary {
			items = append(items, menuItem{
				id:          "file-associations",
				title:       "🔗 Configure File Associations",
				description: "Set up double-click video file opening",
				recommended: false,
			})
		}
	}

	// Add Screenshot Settings option (always available)
	items = append(items, menuItem{
		id:          "screenshot-settings",
		title:       "📷 Screenshot Settings",
		description: "Configure screenshot format and options",
		recommended: false,
	})

	// Add Change MPV UI option if an MPV app is installed
	if hasMPVApp {
		items = append(items, menuItem{
			id:          "change-mpv-ui",
			title:       "🎨 Change MPV UI",
			description: "Switch between ModernZ, UOSC, or default MPV interface",
			recommended: false,
		})
	}

	// Add Save Position on Quit option (always available)
	items = append(items, menuItem{
		id:          "save-position-on-quit",
		title:       "💾 Save Position on Quit",
		description: getSavePositionOnQuitDescription(),
		recommended: false,
	})

	// Add Change Hardware Acceleration option
	items = append(items, menuItem{
		id:          "change-hwdec",
		title:       "⚡ Change Hardware Acceleration",
		description: "Select hardware decoding method for MPV",
		recommended: false,
	})

	// Add Reset Config option
	items = append(items, menuItem{
		id:          "reset-config",
		title:       "🔄 Reset MPV Config to Recommended",
		description: "Restore mpv.conf to latest recommended configuration",
		recommended: false,
	})

	// Add Restore Config option
	items = append(items, menuItem{
		id:          "restore-config",
		title:       "↩️ Restore MPV Config",
		description: "Restore from a backup configuration",
		recommended: false,
	})

	m.configOptionsList = m.createStyledList("MPV Configuration Options", items)
}

func (m *Model) setupHWAOptionsList() {
	p := m.platformInfo
	var brand string

	if m.platformInfo != nil {
		if m.platformInfo.GPUInfo != nil {
			brand = m.platformInfo.GPUInfo.Brand
		}
	}

	hwaOptions := platform.GetHWAOptions(p.OSType, brand)

	// Get the recommended HWA decoder based on platform and GPU
	recommendedHWA := platform.GetRecommendedHWADecoder(p.OSType, brand)

	items := []list.Item{
		hwaOptionItem{
			id:          "auto",
			title:       "auto",
			description: platform.GetHwaDescription("auto"),
			recommended: recommendedHWA == "auto",
		},
	}

	for _, opt := range hwaOptions {
		if opt != "auto" {
			items = append(items, hwaOptionItem{
				id:          opt,
				title:       opt,
				description: platform.GetHwaDescription(opt),
				recommended: opt == recommendedHWA,
			})
		}
	}

	// Add "no" option at the end for all platforms
	items = append(items, hwaOptionItem{
		id:          "no",
		title:       "no",
		description: platform.GetHwaDescription("no"),
		recommended: false,
	})

	m.hwaOptionsList = m.createStyledList("Hardware Acceleration", items)
}

func (m *Model) setupFileAssociationsList() {
	items := []list.Item{
		menuItem{
			id:          "install-associations",
			title:       "🔗 Install File Associations",
			description: "Set MPV as default for video files",
			recommended: true,
		},
		menuItem{
			id:          "remove-associations",
			title:       "❌ Remove File Associations",
			description: "Remove MPV as default for video files",
			recommended: false,
		},
	}

	m.fileAssociationsList = m.createStyledList("File Associations", items)
}

func (m *Model) getCurrentHWAValue() string {
	values := config.GetConfigValue(constants.ConfigKeyHardwareDecoder)
	if len(values) == 0 {
		return "auto"
	}
	return values[0]
}

func (m *Model) applyHWAOption(option string) error {
	// Save to mpv.conf
	if err := config.SetConfigValue(constants.ConfigKeyHardwareDecoder, []string{option}, false); err != nil {
		return err
	}
	// Also save preference to mpv-manager.json for backup/restore
	if err := config.SetHWADecoderPreference(option); err != nil {
		// Log warning but don't fail
		// The preference is optional, mpv.conf is the source of truth
	}
	return nil
}

func (m *Model) setupScreenshotOptionsList() {
	items := []list.Item{
		screenshotOptionItem{
			id:          "screenshot-format",
			title:       "Screenshot Format",
			description: getCurrentScreenshotValue("format"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-tag-colorspace",
			title:       "Tag Colorspace in Filename",
			description: getCurrentScreenshotValue("tag-colorspace"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-high-bit-depth",
			title:       "High Bit Depth",
			description: getCurrentScreenshotValue("high-bit-depth"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-template",
			title:       "Screenshot Filename Template",
			description: getCurrentScreenshotValue("template"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-directory",
			title:       "Screenshot Directory",
			description: getCurrentScreenshotValue("directory"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-jpeg-quality",
			title:       "JPEG Quality",
			description: getCurrentScreenshotValue("jpeg-quality"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-png-compression",
			title:       "PNG Compression",
			description: getCurrentScreenshotValue("png-compression"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-webp-lossless",
			title:       "WebP Lossless",
			description: getCurrentScreenshotValue("webp-lossless"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-webp-quality",
			title:       "WebP Quality",
			description: getCurrentScreenshotValue("webp-quality"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-jxl-distance",
			title:       "JPEG XL Distance",
			description: getCurrentScreenshotValue("jxl-distance"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-avif-encoder",
			title:       "AVIF Encoder",
			description: getCurrentScreenshotValue("avif-encoder"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-avif-pixfmt",
			title:       "AVIF Pixel Format",
			description: getCurrentScreenshotValue("avif-pixfmt"),
			recommended: false,
		},
		screenshotOptionItem{
			id:          "screenshot-avif-opts",
			title:       "AVIF Encoder Options",
			description: getCurrentScreenshotValue("avif-opts"),
			recommended: false,
		},
	}

	m.screenshotOptionsList = m.createStyledList("Screenshot Settings", items)
}

func getCurrentScreenshotValue(option string) string {
	var key string
	var defaultValue string

	switch option {
	case "format":
		key = constants.ConfigKeyScreenshotFormat
		defaultValue = "png"
	case "tag-colorspace":
		key = constants.ConfigKeyScreenshotTagColorspace
		defaultValue = "yes"
	case "high-bit-depth":
		key = constants.ConfigKeyScreenshotHighBitDepth
		defaultValue = "yes"
	case "template":
		key = constants.ConfigKeyScreenshotTemplate
		defaultValue = "mpv-shot%n"
	case "directory":
		key = constants.ConfigKeyScreenshotDirectory
		defaultValue = ""
	case "jpeg-quality":
		key = constants.ConfigKeyScreenshotJpegQuality
		defaultValue = "90"
	case "png-compression":
		key = constants.ConfigKeyScreenshotPngCompression
		defaultValue = "7"
	case "webp-lossless":
		key = constants.ConfigKeyScreenshotWebpLossless
		defaultValue = "no"
	case "webp-quality":
		key = constants.ConfigKeyScreenshotWebpQuality
		defaultValue = "75"
	case "jxl-distance":
		key = constants.ConfigKeyScreenshotJxlDistance
		defaultValue = "1.0"
	case "avif-encoder":
		key = constants.ConfigKeyScreenshotAvifEncoder
		defaultValue = "libaom-av1"
	case "avif-pixfmt":
		key = constants.ConfigKeyScreenshotAvifPixfmt
		defaultValue = ""
	case "avif-opts":
		key = constants.ConfigKeyScreenshotAvifOpts
		defaultValue = "usage=allintra,crf=0,cpu-used=8"
	}

	values := config.GetConfigValue(key)
	if len(values) == 0 {
		if defaultValue == "" {
			return "Not set"
		}
		return defaultValue + " (default)"
	}
	return values[0]
}

// screenshotOptionItem implements list.Item for screenshot options
type screenshotOptionItem struct {
	id          string
	title       string
	description string
	recommended bool
}

func (s screenshotOptionItem) Title() string {
	return s.title
}

func (s screenshotOptionItem) Description() string {
	return s.description
}

func (s screenshotOptionItem) FilterValue() string {
	return s.title
}

// Screenshot value selection lists
func (m *Model) setupScreenshotFormatList() {
	items := []list.Item{
		screenshotValueItem{id: "png", title: "png", description: "PNG format (lossless)"},
		screenshotValueItem{id: "jpg", title: "jpg", description: "JPEG format (lossy)"},
		screenshotValueItem{id: "jpeg", title: "jpeg", description: "JPEG format (lossy)"},
		screenshotValueItem{id: "webp", title: "webp", description: "WebP format (lossless/lossy)"},
		screenshotValueItem{id: "jxl", title: "jxl", description: "JPEG XL format (lossless/lossy)"},
		screenshotValueItem{id: "avif", title: "avif", description: "AVIF format (lossless/lossy)"},
		screenshotValueItem{id: "none", title: "none", description: "Disable screenshots"},
	}
	m.screenshotValueList = m.createStyledList("Select Screenshot Format", items)
}

func (m *Model) setupScreenshotYesNoList(optionName, title string) {
	items := []list.Item{
		screenshotValueItem{id: "yes", title: "yes", description: "Enabled"},
		screenshotValueItem{id: "no", title: "no", description: "Disabled"},
	}
	m.screenshotValueList = m.createStyledList(title, items)
}

func (m *Model) setupScreenshotNumericList(optionName, title string, values []string) {
	items := []list.Item{}
	for _, v := range values {
		items = append(items, screenshotValueItem{id: v, title: v, description: ""})
	}
	m.screenshotValueList = m.createStyledList(title, items)
}

func (m *Model) setupScreenshotEncoderList() {
	items := []list.Item{
		screenshotValueItem{id: "libaom-av1", title: "libaom-av1", description: "AOMedia AV1 encoder (slow, best quality)"},
		screenshotValueItem{id: "rav1e", title: "rav1e", description: "Rav1e AV1 encoder (balanced)"},
		screenshotValueItem{id: "svt-av1", title: "svt-av1", description: "SVT-AV1 encoder (fast, good quality)"},
	}
	m.screenshotValueList = m.createStyledList("Select AVIF Encoder", items)
}

func (m *Model) setupScreenshotPixelFormatList() {
	items := []list.Item{
		screenshotValueItem{id: "yuv420p", title: "yuv420p", description: "4:2:0 8-bit"},
		screenshotValueItem{id: "yuv422p", title: "yuv422p", description: "4:2:2 8-bit"},
		screenshotValueItem{id: "yuv444p", title: "yuv444p", description: "4:4:4 8-bit"},
		screenshotValueItem{id: "yuv420p10", title: "yuv420p10", description: "4:2:0 10-bit"},
		screenshotValueItem{id: "yuv420p12", title: "yuv420p12", description: "4:2:0 12-bit"},
		screenshotValueItem{id: "yuv422p10", title: "yuv422p10", description: "4:2:2 10-bit"},
		screenshotValueItem{id: "yuv422p12", title: "yuv422p12", description: "4:2:2 12-bit"},
		screenshotValueItem{id: "yuv444p10", title: "yuv444p10", description: "4:4:4 10-bit"},
		screenshotValueItem{id: "yuv444p12", title: "yuv444p12", description: "4:4:4 12-bit"},
	}
	m.screenshotValueList = m.createStyledList("Select Pixel Format", items)
}

// screenshotValueItem implements list.Item for screenshot value selection
type screenshotValueItem struct {
	id          string
	title       string
	description string
}

func (s screenshotValueItem) Title() string {
	return s.title
}

func (s screenshotValueItem) Description() string {
	return s.description
}

func (s screenshotValueItem) FilterValue() string {
	return s.title
}

// Function to get screenshot config key from option ID
func getScreenshotConfigKey(optionID string) string {
	switch optionID {
	case "screenshot-format":
		return constants.ConfigKeyScreenshotFormat
	case "screenshot-tag-colorspace":
		return constants.ConfigKeyScreenshotTagColorspace
	case "screenshot-high-bit-depth":
		return constants.ConfigKeyScreenshotHighBitDepth
	case "screenshot-template":
		return constants.ConfigKeyScreenshotTemplate
	case "screenshot-directory":
		return constants.ConfigKeyScreenshotDirectory
	case "screenshot-jpeg-quality":
		return constants.ConfigKeyScreenshotJpegQuality
	case "screenshot-png-compression":
		return constants.ConfigKeyScreenshotPngCompression
	case "screenshot-webp-lossless":
		return constants.ConfigKeyScreenshotWebpLossless
	case "screenshot-webp-quality":
		return constants.ConfigKeyScreenshotWebpQuality
	case "screenshot-jxl-distance":
		return constants.ConfigKeyScreenshotJxlDistance
	case "screenshot-avif-encoder":
		return constants.ConfigKeyScreenshotAvifEncoder
	case "screenshot-avif-pixfmt":
		return constants.ConfigKeyScreenshotAvifPixfmt
	case "screenshot-avif-opts":
		return constants.ConfigKeyScreenshotAvifOpts
	default:
		return ""
	}
}

// getSavePositionOnQuitDescription returns the current save-position-on-quit setting description
func getSavePositionOnQuitDescription() string {
	values := config.GetConfigValue(constants.ConfigKeySavePositionOnQuit)
	if len(values) == 0 || values[0] == "" {
		return "no (default) - Resume playback position is disabled"
	}
	if values[0] == "yes" {
		return "yes - Remember playback position when you quit"
	}
	return values[0] + " - Resume playback position is disabled"
}

// setupSavePositionOnQuitList creates the yes/no selection list
func (m *Model) setupSavePositionOnQuitList() {
	items := []list.Item{
		screenshotValueItem{id: "no", title: "no", description: "Disabled (default) - Don't remember position"},
		screenshotValueItem{id: "yes", title: "yes", description: "Enabled - Resume where you left off"},
	}
	m.screenshotValueList = m.createStyledList("Save Position on Quit", items)
}

// hasMPVInstallMethod checks if any MPV install method exists in installed apps
// This excludes Celluloid, IINA, MPC-QT, and Infuse which have their own UIs
func hasMPVInstallMethod(apps []config.InstalledApp) bool {
	mpvMethods := []string{
		"mpv-flatpak",
		"mpv-package",
		"mpv-binary",
		"mpv-binary-v3",
		"mpv-app",
		"mpv-brew",
	}

	for _, app := range apps {
		for _, method := range mpvMethods {
			if app.InstallMethod == method {
				return true
			}
		}
	}
	return false
}
