package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/go-telegram-bot-api/telegram-bot-api"
	"github.com/kelseyhightower/envconfig"
)

type Config struct {
	WundergroundAPIKey    string `envconfig:"WUNDERGROUND_API_KEY"`
	WundergroundStationID string `envconfig:"WUNDERGROUND_STATION_ID"`
	TelegramBotToken      string `envconfig:"TELEGRAM_BOT_TOKEN"`
	TelegramChatID        int64  `envconfig:"TELEGRAM_CHAT_ID"`
}

// Define a struct to hold the weather data
type WeatherData struct {
	Observations []struct {
		Metric struct {
			Temp     float64 `json:"temp"`
			WindSpeed float64 `json:"windSpeed"`
			WindGust  float64 `json:"windGust"`
			Humidity int     `json:"humidity"`
		} `json:"metric"`
	} `json:"observations"`
}

func main() {
	var config Config
	err := envconfig.Process("", &config)
	if err != nil {
		log.Fatal(err)
	}

	// Create a new Telegram bot
	bot, err := tgbotapi.NewBotAPI(config.TelegramBotToken)
	if err != nil {
		log.Fatal(err)
	}
	bot.Debug = true

	// Set up the update configuration
	u := tgbotapi.NewUpdate(0)
	u.Timeout = 60

	// Get updates from the bot
	updates, err := bot.GetUpdatesChan(u)

	// Handle updates
	for update := range updates {
		if update.CallbackQuery != nil {
			// Handle button click
			handleCallback(bot, update.CallbackQuery, config)
		} 	
		if update.Message != nil && update.Message.IsCommand() {
			// Handle commands
			handleCommand(bot, update.Message, config)
		}
	}
}

func handleCommand(bot *tgbotapi.BotAPI, message *tgbotapi.Message, config Config) {
	switch message.Command() {
	case "weather":
		sendWeatherData(bot, config)
	default:
		msg := tgbotapi.NewMessage(message.Chat.ID, "Invalid command. Try /weather.")
		bot.Send(msg)
	}
}

func sendWeatherData(bot *tgbotapi.BotAPI, config Config) {
	// Get weather data from Wunderground by station ID
	wundergroundURL := fmt.Sprintf("https://api.weather.com/v2/pws/observations/current?stationId=%s&format=json&units=m&apiKey=%s", config.WundergroundStationID, config.WundergroundAPIKey)
	resp, err := http.Get(wundergroundURL)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	// Parse weather data from JSON to struct
	var weatherData WeatherData
	err = json.Unmarshal(body, &weatherData)
	if err != nil {
		log.Fatal(err)
	}

	// Extract temperature, wind, and humidity data from struct
	temp := weatherData.Observations[0].Metric.Temp
	windSpeed := weatherData.Observations[0].Metric.WindSpeed
	windGust := weatherData.Observations[0].Metric.WindGust
	humidity := weatherData.Observations[0].Metric.Humidity

	// Send weather data to Telegram chat
	msg := tgbotapi.NewMessage(config.TelegramChatID, "")
	msg.ParseMode = "markdown"
	msg.Text = fmt.Sprintf("*Weather Data for %s*\n\nTemperature: %.1f°C\nWind Speed: %.1f km/h\nWind Gust: %.1f km/h\nHumidity: %d%%", config.WundergroundStationID, temp, windSpeed, windGust, humidity)

	// Create inline keyboard with a button
	keyboard := tgbotapi.NewInlineKeyboardMarkup(
		tgbotapi.NewInlineKeyboardRow(
			tgbotapi.NewInlineKeyboardButtonData("Request Update", "update_request"),
		),
	)
	msg.ReplyMarkup = keyboard

	bot.Send(msg)
}

func handleCallback(bot *tgbotapi.BotAPI, query *tgbotapi.CallbackQuery, config Config) {
	switch query.Data {
	case "update_request":
		// Handle the button click and perform any desired action
		// For example, you can send a confirmation message
		sendWeatherData(bot, config)
	}
}