package infra

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

var validParseModes = map[string]bool{
	"":            true,
	"Markdown":    true,
	"MarkdownV2":  true,
	"HTML":        true,
}

// NotifyTelegram envía un mensaje a un chat de Telegram via Bot API.
// botToken: token del bot sin prefijo "bot". chatID: ID numérico o @channelname.
// parseMode: "" (plain), "Markdown", "MarkdownV2" o "HTML".
// Textos superiores a 4096 chars se truncan a 4093 + "...".
func NotifyTelegram(botToken string, chatID string, text string, parseMode string) error {
	if !validParseModes[parseMode] {
		return fmt.Errorf("notify_telegram: invalid parseMode %q (must be \"\", \"Markdown\", \"MarkdownV2\" or \"HTML\")", parseMode)
	}

	const maxLen = 4096
	if len(text) > maxLen {
		text = text[:4093] + "..."
	}

	payload := map[string]any{
		"chat_id": chatID,
		"text":    text,
	}
	if parseMode != "" {
		payload["parse_mode"] = parseMode
	}

	data, err := json.Marshal(payload)
	if err != nil {
		return fmt.Errorf("notify_telegram: marshal payload: %w", err)
	}

	url := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", botToken)
	client := &http.Client{Timeout: 10 * time.Second}

	req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data))
	if err != nil {
		return fmt.Errorf("notify_telegram: build request: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("notify_telegram: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("notify_telegram: read response: %w", err)
	}

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("notify_telegram: telegram api: status=%d body=%s", resp.StatusCode, body)
	}

	var result struct {
		OK          bool   `json:"ok"`
		Description string `json:"description"`
	}
	if err := json.Unmarshal(body, &result); err != nil {
		return fmt.Errorf("notify_telegram: parse response: %w", err)
	}
	if !result.OK {
		return fmt.Errorf("notify_telegram: telegram: %s", result.Description)
	}

	return nil
}
