package main

import (
	"encoding/json"
	"fmt"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/AlecAivazis/survey/v2"
	"github.com/charmbracelet/glamour"
)

func main() {
	var err error
	if len(os.Args) > 2 {
		fmt.Println("expected zero or one arguments")
	}
	if len(os.Args) > 1 {
		arg := os.Args[1]
		switch arg {
		case "-r", "--random":
			err = visitRandomUser()
		default:
			err = visitUsername(os.Args[1])
		}
	} else {
		err = visitPrompt()
	}

	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err)
		os.Exit(1)
	}
}

func visitRandomUser() error {
	usernames, err := getUsernames()
	if err != nil {
		return err
	}

	return visitUser(usernames[rand.Intn(len(usernames))])
}

func visitUsername(username string) error {
	usernames, err := getUsernames()
	if err != nil {
		return err
	}

	for _, name := range usernames {
		if name == username {
			return visitUser(username)
		}
	}

	return fmt.Errorf("no such user: %s", username)
}

func visitPrompt() error {
	usernames, err := getUsernames()
	if err != nil {
		return err
	}
	username := ""
	prompt := &survey.Select{
		Message: "Choose a townie to visit!",
		Options: usernames,
	}
	survey.AskOne(prompt, &username)
	return visitUser(username)
}

func visitUser(username string) error {
	files, err := os.ReadDir(filepath.Join("/home", username))
	if err != nil {
		return fmt.Errorf("user is not accepting visitors (could not read user's home directory: %w)", err)
	}

	for _, file := range files {
		if !isReadme(file.Name()) {
			continue
		}

		path := filepath.Join("/home", username, file.Name())

		data, err := os.ReadFile(path)
		if err != nil {
			break
		}

		if isMarkdown(file.Name()) {
			r, _ := glamour.NewTermRenderer(glamour.WithAutoStyle())
			out, err := r.RenderBytes(data)
			if err == nil {
				fmt.Println(string(out))
				return nil
			}
		}

		fmt.Println(string(data))

		return nil
	}

	// TODO handle .plan and .project files

	fmt.Println("TODO non-readme fallback")

	return nil
}

func isReadme(filename string) bool {
	fn := strings.ToLower(filename)
	return strings.HasPrefix(fn, "readme") || strings.HasPrefix(fn, "welcome")
}

func isMarkdown(filename string) bool {
	fn := strings.ToLower(filename)
	return strings.HasSuffix(fn, ".md") || strings.HasSuffix(fn, ".markdown")
}

func getUsernames() ([]string, error) {
	cmd := exec.Command("/bin/bash", "-c", "town stats | jq -r '.users|map(.username)'")
	output, err := cmd.Output()
	if err != nil {
		return nil, err
	}
	usernames := []string{}
	err = json.Unmarshal(output, &usernames)

	if err != nil {
		return nil, err
	}

	return usernames, nil
}
