package main

import (
	"fmt"
	"strings"

	"github.com/gesellix/bose-soundtouch/pkg/models"
	"github.com/urfave/cli/v2"
)

// getNowPlaying handles getting the current playback status
func getNowPlaying(c *cli.Context) error {
	clientConfig := GetClientConfig(c)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		return err
	}

	PrintDeviceHeader("Getting current playback status", clientConfig.Host, clientConfig.Port)

	nowPlaying, err := client.GetNowPlaying()
	if err != nil {
		return fmt.Errorf("failed to get now playing: %w", err)
	}

	fmt.Printf("Now Playing:\n")
	fmt.Printf("  Device ID: %s\n", nowPlaying.DeviceID)

	if nowPlaying.IsEmpty() {
		fmt.Printf("  Status: No content playing\n")
		return nil
	}

	printBasicPlaybackInfo(nowPlaying)
	printTrackInfo(nowPlaying)
	printTimeInfo(nowPlaying)
	printStreamInfo(nowPlaying)
	printContentDetails(nowPlaying, c.Bool("verbose"))
	printPlaybackStatus(nowPlaying)

	return nil
}

// printBasicPlaybackInfo prints basic source and status information
func printBasicPlaybackInfo(nowPlaying *models.NowPlaying) {
	fmt.Printf("  Source: %s\n", nowPlaying.Source)

	if nowPlaying.SourceAccount != "" {
		fmt.Printf("  Source Account: %s\n", nowPlaying.SourceAccount)
	}

	fmt.Printf("  Status: %s\n", nowPlaying.PlayStatus.String())
}

// printTrackInfo prints track, artist, and album information
func printTrackInfo(nowPlaying *models.NowPlaying) {
	if nowPlaying.Track != "" {
		fmt.Printf("  Track: %s\n", nowPlaying.Track)
	}

	if nowPlaying.Artist != "" {
		fmt.Printf("  Artist: %s\n", nowPlaying.Artist)
	}

	if nowPlaying.Album != "" {
		fmt.Printf("  Album: %s\n", nowPlaying.Album)
	}
}

// printTimeInfo prints duration and position information
func printTimeInfo(nowPlaying *models.NowPlaying) {
	if !nowPlaying.HasTimeInfo() {
		return
	}

	fmt.Printf("  Duration: %s\n", nowPlaying.FormatDuration())

	if nowPlaying.Position != nil {
		fmt.Printf("  Position: %s\n", nowPlaying.FormatPosition())
	}
}

// printStreamInfo prints stream type information
func printStreamInfo(nowPlaying *models.NowPlaying) {
	if nowPlaying.StreamType != "" {
		fmt.Printf("  Stream Type: %s\n", nowPlaying.StreamType)
	}
}

// printContentDetails prints detailed content information when verbose or location is available
func printContentDetails(nowPlaying *models.NowPlaying, verbose bool) {
	if nowPlaying.ContentItem == nil {
		return
	}

	showDetails := verbose || nowPlaying.ContentItem.Location != ""
	if !showDetails {
		return
	}

	fmt.Printf("\nContent Details:\n")
	printContentLocation(nowPlaying.ContentItem)
	printVerboseContentInfo(nowPlaying, verbose)

	if verbose {
		printVerbosePlaybackDetails(nowPlaying)
	}
}

// printContentLocation prints the content location
func printContentLocation(contentItem *models.ContentItem) {
	if contentItem.Location != "" {
		fmt.Printf("  Location: %s\n", contentItem.Location)
	}
}

// printVerboseContentInfo prints verbose content information
func printVerboseContentInfo(nowPlaying *models.NowPlaying, verbose bool) {
	if !verbose || nowPlaying.ContentItem == nil {
		return
	}

	if nowPlaying.ContentItem.Type != "" {
		fmt.Printf("  Content Type: %s\n", nowPlaying.ContentItem.Type)
	}

	if nowPlaying.ContentItem.ItemName != "" && nowPlaying.ContentItem.ItemName != nowPlaying.Track {
		fmt.Printf("  Item Name: %s\n", nowPlaying.ContentItem.ItemName)
	}

	if nowPlaying.ContentItem.ContainerArt != "" {
		fmt.Printf("  Container Art: %s\n", nowPlaying.ContentItem.ContainerArt)
	}

	fmt.Printf("  Presetable: %t\n", nowPlaying.ContentItem.IsPresetable)
}

// printVerbosePlaybackDetails prints detailed playback information in verbose mode
func printVerbosePlaybackDetails(nowPlaying *models.NowPlaying) {
	fmt.Printf("\nPlayback Details:\n")

	// Shuffle and repeat settings
	if nowPlaying.ShuffleSetting != "" {
		fmt.Printf("  Shuffle: %s\n", nowPlaying.ShuffleSetting.String())
	}

	if nowPlaying.RepeatSetting != "" {
		fmt.Printf("  Repeat: %s\n", nowPlaying.RepeatSetting.String())
	}

	// Track ID
	if nowPlaying.TrackID != "" {
		fmt.Printf("  Track ID: %s\n", nowPlaying.TrackID)
	}

	// Art details
	if nowPlaying.Art != nil {
		fmt.Printf("  Art Image Status: %s\n", nowPlaying.Art.ArtImageStatus)

		if nowPlaying.Art.URL != "" {
			fmt.Printf("  Art URL: %s\n", nowPlaying.Art.URL)
		}
	}

	// Capabilities
	fmt.Printf("\nCapabilities:\n")
	fmt.Printf("  Skip Enabled: %t\n", nowPlaying.CanSkip())
	fmt.Printf("  Skip Previous Enabled: %t\n", nowPlaying.CanSkipPrevious())
	fmt.Printf("  Favorite Enabled: %t\n", nowPlaying.CanFavorite())
	fmt.Printf("  Seek Supported: %t\n", nowPlaying.IsSeekSupported())
}

// printPlaybackStatus prints special status messages
func printPlaybackStatus(nowPlaying *models.NowPlaying) {
	if nowPlaying.PlayStatus == models.PlayStatusBuffering {
		fmt.Printf("\nNote: Content is buffering\n")
	}
}

// playCommand handles play command
func playCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		return err
	}

	PrintDeviceHeader("Sending play command", clientConfig.Host, clientConfig.Port)

	err = client.SendKeyPressOnly(models.KeyPlay)
	if err != nil {
		return fmt.Errorf("failed to send play command: %w", err)
	}

	PrintSuccess("Play command sent")

	return nil
}

// pauseCommand handles pause command
func pauseCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		return err
	}

	PrintDeviceHeader("Sending pause command", clientConfig.Host, clientConfig.Port)

	err = client.SendKeyPressOnly(models.KeyPause)
	if err != nil {
		return fmt.Errorf("failed to send pause command: %w", err)
	}

	PrintSuccess("Pause command sent")

	return nil
}

// stopCommand handles stop command
func stopCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		return err
	}

	PrintDeviceHeader("Sending stop command", clientConfig.Host, clientConfig.Port)

	err = client.SendKeyPressOnly(models.KeyStop)
	if err != nil {
		return fmt.Errorf("failed to send stop command: %w", err)
	}

	PrintSuccess("Stop command sent")

	return nil
}

// nextCommand handles next track command
func nextCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		return err
	}

	PrintDeviceHeader("Sending next track command", clientConfig.Host, clientConfig.Port)

	err = client.SendKeyPressOnly(models.KeyNextTrack)
	if err != nil {
		return fmt.Errorf("failed to send next track command: %w", err)
	}

	PrintSuccess("Next track command sent")

	return nil
}

// prevCommand handles previous track command
func prevCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		return err
	}

	PrintDeviceHeader("Sending previous track command", clientConfig.Host, clientConfig.Port)

	err = client.SendKeyPressOnly(models.KeyPrevTrack)
	if err != nil {
		return fmt.Errorf("failed to send previous track command: %w", err)
	}

	PrintSuccess("Previous track command sent")

	return nil
}

// sendKey sends a generic key command
func sendKey(c *cli.Context) error {
	key := c.String("key")
	clientConfig := GetClientConfig(c)
	PrintDeviceHeader(fmt.Sprintf("Sending %s key command", key), clientConfig.Host, clientConfig.Port)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to create client: %v", err))
		return err
	}

	err = client.SendKey(strings.ToUpper(key))
	if err != nil {
		PrintError(fmt.Sprintf("Failed to send key command: %v", err))
		return err
	}

	PrintSuccess(fmt.Sprintf("%s key command sent", key))

	return nil
}

// powerCommand sends the POWER key command
func powerCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)
	PrintDeviceHeader("Sending POWER key command", clientConfig.Host, clientConfig.Port)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to create client: %v", err))
		return err
	}

	err = client.SendKey(models.KeyPower)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to send power command: %v", err))
		return err
	}

	PrintSuccess("Power command sent")

	return nil
}

// muteCommand sends the MUTE key command
func muteCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)
	PrintDeviceHeader("Sending MUTE key command", clientConfig.Host, clientConfig.Port)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to create client: %v", err))
		return err
	}

	err = client.SendKey(models.KeyMute)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to send mute command: %v", err))
		return err
	}

	PrintSuccess("Mute command sent")

	return nil
}

// thumbsUpCommand sends the THUMBS_UP key command
func thumbsUpCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)
	PrintDeviceHeader("Sending THUMBS_UP key command", clientConfig.Host, clientConfig.Port)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to create client: %v", err))
		return err
	}

	err = client.SendKey(models.KeyThumbsUp)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to send thumbs up command: %v", err))
		return err
	}

	PrintSuccess("Thumbs up command sent")

	return nil
}

// thumbsDownCommand sends the THUMBS_DOWN key command
func thumbsDownCommand(c *cli.Context) error {
	clientConfig := GetClientConfig(c)
	PrintDeviceHeader("Sending THUMBS_DOWN key command", clientConfig.Host, clientConfig.Port)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to create client: %v", err))
		return err
	}

	err = client.SendKey(models.KeyThumbsDown)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to send thumbs down command: %v", err))
		return err
	}

	PrintSuccess("Thumbs down command sent")

	return nil
}

// volumeUpKey sends the VOLUME_UP key command
func volumeUpKey(c *cli.Context) error {
	clientConfig := GetClientConfig(c)
	PrintDeviceHeader("Sending VOLUME_UP key command", clientConfig.Host, clientConfig.Port)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to create client: %v", err))
		return err
	}

	err = client.VolumeUp()
	if err != nil {
		PrintError(fmt.Sprintf("Failed to send volume up command: %v", err))
		return err
	}

	PrintSuccess("Volume up command sent")

	return nil
}

// volumeDownKey sends the VOLUME_DOWN key command
func volumeDownKey(c *cli.Context) error {
	clientConfig := GetClientConfig(c)
	PrintDeviceHeader("Sending VOLUME_DOWN key command", clientConfig.Host, clientConfig.Port)

	client, err := CreateSoundTouchClient(clientConfig)
	if err != nil {
		PrintError(fmt.Sprintf("Failed to create client: %v", err))
		return err
	}

	err = client.VolumeDown()
	if err != nil {
		PrintError(fmt.Sprintf("Failed to send volume down command: %v", err))
		return err
	}

	PrintSuccess("Volume down command sent")

	return nil
}
