package main

import (
	"os"
	"os/signal"
	"syscall"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	tele "gopkg.in/telebot.v3"

	"git.gensokyo.cafe/kkyy/tgbot_misaka_5882f7/utils"
)

var (
	logger *zap.SugaredLogger
	loglvl zap.AtomicLevel
)

func initLogger() {
	logCfg := zap.NewProductionConfig()
	loglvl = logCfg.Level

	l, err := logCfg.Build()
	if err != nil {
		panic(err)
	}

	logger = l.Sugar()
}

func runBot() {
	logger.Info("Bot initializing...")
	bot, err := initBot()
	if err != nil {
		logger.Fatalw("Failed to initialize bot", "err", err)
	}

	// Announce commands
	if config.TGAnnounceCommands {
		logger.Info("Announcing commands...")

		if err = bot.SetCommands([]tele.Command{
			{Text: "reason", Description: "Think."},
			{Text: "tr", Description: "Translate text"},
			{Text: "kanji", Description: "Help with pronunciation of Kanji"},
			{Text: "xr", Description: "Currency exchange rates"},
			{Text: "year_progress", Description: "Time doesn't wait."},
			{Text: "traffic", Description: "Show traffic usage."},
			{Text: "dig", Description: "Diggy diggy dig."},
		}); err != nil {
			logger.Fatalw("Failed to announce commands", "err", err)
		}
	}

	botFinCh := utils.WaitFor(bot.Start)
	logger.Infow("Bot started", "username", bot.Me.Username)

	go initExchangeRates()

	// listen for shutdown signal
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)

	select {
	case sig := <-sigCh:
		logger.Infow("Received signal", "signal", sig)
		logger.Info("Bot shutdown...")
		bot.Stop()
	case <-botFinCh:
		logger.Warn("Bot terminated")
	}
}

func main() {
	initLogger()
	if err := LoadCfg(); err != nil {
		logger.Fatalw("Failed to load config", "err", err)
	}
	parsedLvl, err := zapcore.ParseLevel(config.LogLevel)
	if err != nil {
		logger.Warnf("Invalid log level %q", config.LogLevel)
	} else {
		loglvl.SetLevel(parsedLvl)
	}
	if err := initMsgCache(); err != nil {
		logger.Fatalw("Failed to initialize message cache", "err", err)
	}

	runBot()
}