package main

import (
	"context"
	"encoding/json"
	"strings"

	"github.com/bogosj/tesla"
	"github.com/google/uuid"
	"github.com/rudi9719/loggy"
	"golang.org/x/oauth2"
	"samhofi.us/x/keybase/v2"
	"samhofi.us/x/keybase/v2/types/chat1"
)

var (
	k   = keybase.NewKeybase()
	log = loggy.NewLogger(loggy.LogOpts{
		OutFile:   "teslabot.log",
		KBTeam:    "nightmarehaus.logs",
		KBChann:   "teslabot",
		Level:     5,
		ProgName:  "TeslaBot",
		UseStdout: true,
	})
	commands []BotCommand
)

func main() {
	chat := handleChat
	handlers := keybase.Handlers{
		ChatHandler: &chat,
	}
	setupCommands()
	cmds := keybase.AdvertiseCommandsOptions{
		Alias: "Tesla Bot",
	}
	for _, v := range commands {
		cmds.Advertisements = append(cmds.Advertisements, v.Advert)
	}
	k.AdvertiseCommands(cmds)
	k.Run(handlers, &keybase.RunOptions{})
}

func handleChat(m chat1.MsgSummary) {
	defer log.PanicSafe()
	parts := strings.Split(m.Content.Text.Body, " ")
	command := strings.Replace(parts[0], "!", "", -1)
	for _, v := range commands {
		for _, test := range v.Triggers {
			if command == test {
				go v.Exec(m)
				return
			}
		}
	}
}

func isAuthenticated(m chat1.MsgSummary) bool {
	test, _ := k.KVGet(&m.Channel.Name, "teslabot", "authtok")
	return test.EntryValue != ""
}

func getTeslaClient(m chat1.MsgSummary) *tesla.Client {
	var t *oauth2.Token
	if !isAuthenticated(m) {
		k.SendMessageByConvID(m.ConvID, "You are not authenticated.")
		return nil
	}
	test, _ := k.KVGet(&m.Channel.Name, "teslabot", "authtok")
	err := json.Unmarshal([]byte(test.EntryValue), &t)
	if err != nil {
		tracker := uuid.NewString()
		k.SendMessageByConvID(m.ConvID, "There was an retrieving token from KVStore. Contact @rudi9719 for more information with code %+v", tracker)
		log.LogError("%+v: %+v", tracker, err)
		return nil
	}
	c, err := tesla.NewClient(context.Background(), tesla.WithToken(t))
	if err != nil {
		tracker := uuid.NewString()
		k.SendMessageByConvID(m.ConvID, "There was an error logging in. Contact @rudi9719 for more information with code %+v", tracker)
		log.LogError("%+v: %+v", tracker, err)
		return nil
	}
	return c
}

func getVehicle(m chat1.MsgSummary) *tesla.Vehicle {
	c := getTeslaClient(m)
	if c == nil {
		return nil
	}
	parts := strings.Split(m.Content.Text.Body, " ")
	vehicles, err := c.Vehicles()
	if err != nil {
		tracker := uuid.NewString()
		k.SendMessageByConvID(m.ConvID, "There was an error listing vehicles. Contact @rudi9719 for more information with code %+v", tracker)
		log.LogError("%+v: %+v", tracker, err)
		return nil
	}
	v := vehicles[0]
	if len(parts) == 2 {
		for _, test := range vehicles {
			if parts[1] == test.Vin {
				v = test
			}
			if parts[1] == test.DisplayName {
				v = test
			}
		}
	}
	return v
}
