package notifications

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

// NotificationSender es la interfaz que deben cumplir los sistemas de notificación.
type NotificationSender interface {
	SendNotification(subject, message string) error
}

// WebhookNotifier implementa la notificación vía webhook.
type WebhookNotifier struct {
	WebhookURL string
}

// SendNotification envía notificación a través de webhook.
func (w *WebhookNotifier) SendNotification(subject, message string) error {
	if w.WebhookURL == "" {
		return nil
	}

	payload, err := json.Marshal(map[string]string{
		"subject": subject,
		"message": message,
		"time":    time.Now().Format(time.RFC3339),
	})
	if err != nil {
		return err
	}

	resp, err := http.Post(w.WebhookURL, "application/json", bytes.NewBuffer(payload))
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode >= 400 {
		return fmt.Errorf("webhook error: %s", resp.Status)
	}

	return nil
}

// EmailNotifier simula el envío de notificaciones por correo electrónico.
type EmailNotifier struct {
	SMTPServer string
	SMTPPort   string
	Username   string
	Password   string
	FromEmail  string
	ToEmail    string
}

// SendNotification envía un email a través de un servidor SMTP.
func (e *EmailNotifier) SendNotification(subject, message string) error {
	// Construir los encabezados del mensaje
	header := make(map[string]string)
	header["From"] = e.FromEmail
	header["To"] = e.ToEmail
	header["Subject"] = subject
	header["MIME-Version"] = "1.0"
	header["Content-Type"] = "text/plain; charset=\"utf-8\""

	var msg string
	for k, v := range header {
		msg += fmt.Sprintf("%s: %s\r\n", k, v)
	}
	msg += "\r\n" + message

	// Configurar autenticación SMTP
	auth := smtp.PlainAuth("", e.Username, e.Password, e.SMTPServer)
	addr := fmt.Sprintf("%s:%s", e.SMTPServer, e.SMTPPort)

	// Enviar el email
	err := smtp.SendMail(addr, auth, e.FromEmail, []string{e.ToEmail}, []byte(msg))
	if err != nil {
		return err
	}

	log.Printf("Email enviado correctamente a %s", e.ToEmail)
	return nil
}

// SlackNotifier implementa las notificaciones vía Slack.
type SlackNotifier struct {
	WebhookURL string
}

// SendNotification envía un mensaje a Slack.
func (s *SlackNotifier) SendNotification(subject, message string) error {
	if s.WebhookURL == "" {
		return nil
	}

	payload, err := json.Marshal(map[string]interface{}{
		"text": fmt.Sprintf("*%s*\n%s", subject, message),
	})
	if err != nil {
		return err
	}

	resp, err := http.Post(s.WebhookURL, "application/json", bytes.NewBuffer(payload))
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode >= 400 {
		return fmt.Errorf("slack webhook error: %s", resp.Status)
	}

	return nil
}

// CreateNotificationSender crea el notificador según la configuración.
func CreateNotificationSender(enabled bool, method string, cfg map[string]string) NotificationSender {
	if !enabled {
		return nil
	}

	switch method {
	case "webhook":
		return &WebhookNotifier{
			WebhookURL: cfg["url"],
		}
	case "email":
		return &EmailNotifier{
			SMTPServer: cfg["smtp_server"],
			SMTPPort:   cfg["smtp_port"],
			Username:   cfg["username"],
			Password:   cfg["password"],
			FromEmail:  cfg["from_email"],
			ToEmail:    cfg["to_email"],
		}
	case "slack":
		return &SlackNotifier{
			WebhookURL: cfg["webhook_url"],
		}
	default:
		log.Printf("Método de notificación desconocido: %s", method)
		return nil
	}
}

// package notifications

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

// // NotificationSender define la interfaz para enviar notificaciones.
// type NotificationSender interface {
// 	SendNotification(subject, message string) error
// }

// // WebhookNotifier envía notificaciones mediante webhook.
// type WebhookNotifier struct {
// 	WebhookURL string
// }

// func (w *WebhookNotifier) SendNotification(subject, message string) error {
// 	if w.WebhookURL == "" {
// 		return nil
// 	}

// 	payload, err := json.Marshal(map[string]string{
// 		"subject": subject,
// 		"message": message,
// 		"time":    time.Now().Format(time.RFC3339),
// 	})
// 	if err != nil {
// 		return err
// 	}

// 	resp, err := http.Post(w.WebhookURL, "application/json", bytes.NewBuffer(payload))
// 	if err != nil {
// 		return err
// 	}
// 	defer resp.Body.Close()

// 	if resp.StatusCode >= 400 {
// 		return fmt.Errorf("webhook error: %s", resp.Status)
// 	}

// 	return nil
// }

// // EmailNotifier simula el envío de notificaciones por email.
// type EmailNotifier struct {
// 	SMTPServer string
// 	SMTPPort   string
// 	Username   string
// 	Password   string
// 	FromEmail  string
// 	ToEmail    string
// }

// func (e *EmailNotifier) SendNotification(subject, message string) error {
// 	log.Printf("Simulando envío de email: Asunto: %s, Mensaje: %s", subject, message)
// 	log.Printf("Destinatario: %s, Remitente: %s", e.ToEmail, e.FromEmail)
// 	// Aquí se integraría el cliente SMTP real si fuera necesario
// 	return nil
// }

// // SlackNotifier envía notificaciones a Slack.
// type SlackNotifier struct {
// 	WebhookURL string
// }

// func (s *SlackNotifier) SendNotification(subject, message string) error {
// 	if s.WebhookURL == "" {
// 		return nil
// 	}

// 	payload, err := json.Marshal(map[string]interface{}{
// 		"text": fmt.Sprintf("*%s*\n%s", subject, message),
// 	})
// 	if err != nil {
// 		return err
// 	}

// 	resp, err := http.Post(s.WebhookURL, "application/json", bytes.NewBuffer(payload))
// 	if err != nil {
// 		return err
// 	}
// 	defer resp.Body.Close()

// 	if resp.StatusCode >= 400 {
// 		return fmt.Errorf("slack webhook error: %s", resp.Status)
// 	}

// 	return nil
// }

// // NewNotificationSender crea la instancia del notificador según la configuración.
// func NewNotificationSender(enabled bool, method string, cfg map[string]string) NotificationSender {
// 	if !enabled {
// 		return nil
// 	}

// 	switch method {
// 	case "webhook":
// 		return &WebhookNotifier{WebhookURL: cfg["url"]}
// 	case "email":
// 		return &EmailNotifier{
// 			SMTPServer: cfg["smtp_server"],
// 			SMTPPort:   cfg["smtp_port"],
// 			Username:   cfg["username"],
// 			Password:   cfg["password"],
// 			FromEmail:  cfg["from_email"],
// 			ToEmail:    cfg["to_email"],
// 		}
// 	case "slack":
// 		return &SlackNotifier{WebhookURL: cfg["webhook_url"]}
// 	default:
// 		log.Printf("Método de notificación desconocido: %s", method)
// 		return nil
// 	}
// }
