package webhook

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"strconv"
)

// Webhook содержит информацию о вебхуке
type Webhook struct {
	URL    string
	Name   string
	Avatar string
}

// Embed структура для отправки сообщений с эмбедами в Discord
type Embed struct {
	Color       int     `json:"color,omitempty"` // Discord API ожидает int
	Title       string  `json:"title,omitempty"`
	Description string  `json:"description,omitempty"`
	Footer      Footer  `json:"footer,omitempty"`
	Author      Author  `json:"author,omitempty"`
	Fields      []Field `json:"fields,omitempty"`
	Image       Image   `json:"image,omitempty"` // Для изображения в эмбеде
}

// Footer структура для футера эмбеда
type Footer struct {
	Text string `json:"text,omitempty"`
}

// Author структура для автора эмбеда
type Author struct {
	Name     string `json:"name,omitempty"`
	IconURL  string `json:"icon_url,omitempty" ` // URL для иконки автора
	IconPath string // Локальный путь до изображения, если указан
}

// Field структура для полей эмбеда
type Field struct {
	Name  string `json:"name,omitempty"`
	Value string `json:"value,omitempty"`
}

// Image структура для изображения в эмбеде
type Image struct {
	URL   string `json:"url,omitempty"`
	Proxy string `json:"proxy_url,omitempty"` // URL для прокси
}

// Message структура для сообщения
type Message struct {
	Content string  `json:"content,omitempty"`
	Embeds  []Embed `json:"embeds,omitempty"`
}

// Register регистрирует новый вебхук
func Register(url string) *Webhook {
	return &Webhook{URL: url}
}

// SendMessage отправляет обычное текстовое сообщение
func (w *Webhook) SendMessage(message string) error {
	msg := Message{Content: message}
	return w.send(msg)
}

// SendEmbed отправляет эмбед
func (w *Webhook) SendEmbed(embed Embed) error {
	msg := Message{Embeds: []Embed{embed}}
	return w.send(msg)
}

// SendPhoto отправляет изображение
func (w *Webhook) SendPhoto(photoPath string) error {
	return w.sendFile(photoPath, nil)
}

// SendPhotoAndMessage отправляет сообщение с изображением
func (w *Webhook) SendPhotoAndMessage(message, photoPath string) error {
	msg := Message{Content: message}
	return w.sendFile(photoPath, &msg)
}

// SetAvatar устанавливает аватар вебхука
func (w *Webhook) SetAvatar(avatar string) {
	w.Avatar = avatar
}

// SetName устанавливает имя вебхука
func (w *Webhook) SetName(name string) {
	w.Name = name
}

// send отправляет сообщение или эмбед в Discord
func (w *Webhook) send(msg Message) error {
	data, err := json.Marshal(msg)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", w.URL, bytes.NewBuffer(data))
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("Ошибка: код %d, ответ: %s", resp.StatusCode, string(body))
	}

	return nil
}

// sendFile отправляет файл с сообщением или эмбедами
func (w *Webhook) sendFile(photoPath string, msg *Message) error {
	var buf bytes.Buffer
	writer := multipart.NewWriter(&buf)

	if msg != nil {
		data, err := json.Marshal(msg)
		if err != nil {
			return err
		}
		part, err := writer.CreateFormField("payload_json")
		if err != nil {
			return err
		}
		part.Write(data)
	}

	filePart, err := writer.CreateFormFile("file", photoPath)
	if err != nil {
		return err
	}

	file, err := os.Open(photoPath)
	if err != nil {
		return err
	}
	defer file.Close()

	if _, err := io.Copy(filePart, file); err != nil {
		return err
	}

	writer.Close()

	req, err := http.NewRequest("POST", w.URL, &buf)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", writer.FormDataContentType())
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	return nil
}

// HexToIntColor преобразует строку HEX в int для цвета Discord
func HexToIntColor(hexColor string) int {
	// Удаляем символ #
	hexColor = hexColor[1:]

	// Преобразуем в int
	colorInt, err := strconv.ParseInt(hexColor, 16, 32)
	if err != nil {
		return 0 // Возвращаем черный цвет по умолчанию в случае ошибки
	}

	return int(colorInt)
}



panic: Ошибка: код 405, ответ: {"message": "405: Method Not Allowed", "code": 0}

goroutine 1 [running]:
main.main()
        D:/JBProjects/GOLAND/NewsIndiscord/main.go:26 +0x187

package main

import (
	"NewsIndiscord/webhook"
)

func main() {
	webh := webhook.Register("https://canary.discord.com/api/webhooks/Ваш_вебхук_URL")

	embed := webhook.Embed{
		Color:       webhook.HexToIntColor("#e07171"),
		Title:       "Заголовок",
		Description: "Описание эмбеда",
		Footer:      webhook.Footer{Text: "Footer text"},
		Author: webhook.Author{
			Name:     "Автор",
			IconPath: "sdelaydela.jpg", // Указать локальный путь к картинке для иконки автор
		},
		Image: webhook.Image{
			URL: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ97R2x4X7j0IaFYB2z7GPpIXVJeHwXU4YAxQ&s", // Указать локальный путь к изображению
		},
	}

	err := webh.SendEmbed(embed)
	if err != nil {
		panic(err)
	}
}