// Just a program to display information about twitch.
// Token can be found at https://dev.twitch.tv/console
// Also can be obtained at the console I beleive, but twitch-cli token also
// gives a valid token.

package main

import (
	"auth"
	"context"
	"fmt"
	"os"

	"github.com/charmbracelet/log"
	"github.com/nicklaw5/helix/v2"
)

var authCtx, authCancel = context.WithCancel(context.Background())
var helixOptions helix.Options
var defaultUserID string

func init() {
	config, err := read_config()
	if err != nil {
		fmt.Printf("Error with config: %v\n", err)
		fmt.Println("Use the init subcommand to initialize a config file.")
	} else {
		helixOptions.ClientID = config.ClientID
		helixOptions.ClientSecret = config.ClientSecret
		defaultUserID = config.UserID
	}

	maybeSet := func(out *string, env string) {
		val, isSet := os.LookupEnv(env)
		if isSet {
			*out = val
		}
	}

	// Override any argument if a corresponding environment variable is set.
	maybeSet(&helixOptions.ClientID, "TWITCH_CLIENT_ID")
	// maybeSet(&helixOptions.AppAccessToken, "TWITCH_APP_TOKEN")
	maybeSet(&helixOptions.ClientSecret, "TWITCH_CLIENT_SECRET")
}

func printHelp() {
	fmt.Println("Print help about commands here.")
}

// Note:
// Currently everything is intended to just have all the scopes possible for
// us to need to be requested..
func main() {
	ctx := context.Background()

	runAuth := func() *helix.Client {
		client, err := helix.NewClient(&helixOptions)
		if err != nil {
			panic(err)
		}

		// Ask for all scopes up front.  Not handling scope renegotiation at the
		// moment.
		a, err := auth.New(&ctx, client, []string{"user:read:follows"})
		if err != nil {
			log.Info("Need to reauth")
		}

		if !a.HaveAuth {
			ch, err := a.StartAuth("", []string{"user:read:follows"})
			if err != nil {
				panic(err)
			}

			<-ch
		}

		return client
	}

	if len(os.Args) < 2 {
		printHelp()
		panic("Insufficient arguments.")
	}

	switch os.Args[1] {
	case "category":
		{
			client := runAuth()
			categories(client, os.Args[2:])
		}
	case "search":
		{
			client := runAuth()
			search(client, os.Args[2:])
		}
	case "live":
		{
			// TODO: FlagSet
			client := runAuth()
			// Always assume config has ID for now.
			err := getFollowedLive(client, defaultUserID)
			if err != nil {
				panic("Couldn't get followed streams.")
			}
		}
	case "games":
		{
			// TODO: FlagSet
			// XXX: Handle a list of game search terms maybe.
			client := runAuth()
			if err := printGames(client, []string{os.Args[2]}); err != nil {
				panic("Couldn't list games")
			}
		}
	case "init":
		{
			newConfig, err := setupAuth()
			if err != nil {
				panic("Something went wrong with init.")
			}
			helixOptions.ClientID = newConfig.ClientID
			helixOptions.ClientSecret = newConfig.ClientSecret

			client := runAuth()
			users, err := getUsersByName(client, []string{newConfig.UserName})
			if err != nil {
				log.Fatalf("Couldn't look up user '%v': %v\n", newConfig.UserName, err)
			}
			newConfig.UserID = users[0].ID

			// Hopefully the config is safe to write.
			write_config(newConfig)
		}
	case "user":
		{
			// TODO: FlagSet
			client := runAuth()
			users, err := getUsersByName(client, []string{os.Args[2]})
			if err != nil {
				panic("Something went wrong with user fetch.")
			}
			for _, user := range users {
				fmt.Printf("%+v\n", user)
			}
		}
	default:
		printHelp()
	}

}
