package services

import (
	"errors"
	"fmt"
	"gauth-central/internal/database"
	"gauth-central/internal/models"
	"gauth-central/pkg/utils"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

type ContactService struct{}

func NewContactService() *ContactService {
	return &ContactService{}
}

func (s *ContactService) CreateContact(name, email, subject, message, ip string, userID *string) (*models.Contact, error) {
	var userUUID *uuid.UUID
	if userID != nil {
		parsedUUID, err := uuid.Parse(*userID)
		if err == nil {
			userUUID = &parsedUUID
		}
	}

	contact := models.Contact{
		Name:    name,
		Email:   email,
		Subject: subject,
		Message: message,
		IP:      ip,
		UserID:  userUUID,
	}

	if err := database.DB.Create(&contact).Error; err != nil {
		return nil, err
	}

	// Send email asynchronously (like Celery task)
	go func() {
		// In a real production app, you might want to use a proper task queue here
		// For now, we'll just use a goroutine
		err := utils.SendContactEmail(contact.Name, contact.Email, contact.Subject, contact.Message, contact.IP)
		if err != nil {
			fmt.Printf("Failed to send contact email: %v\n", err)
		}
	}()

	return &contact, nil
}

// GetAllContacts retrieves all contact messages with pagination
func (s *ContactService) GetAllContacts(page, limit int) ([]models.Contact, int64, error) {
	var contacts []models.Contact
	var total int64

	offset := (page - 1) * limit

	if err := database.DB.Model(&models.Contact{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	if err := database.DB.Preload("User").Order("created_at desc").Limit(limit).Offset(offset).Find(&contacts).Error; err != nil {
		return nil, 0, err
	}

	return contacts, total, nil
}

// GetContactByID retrieves a single contact message by ID
func (s *ContactService) GetContactByID(id string) (*models.Contact, error) {
	var contact models.Contact
	if err := database.DB.Preload("User").Where("id = ?", id).First(&contact).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("contact not found")
		}
		return nil, err
	}
	return &contact, nil
}

// DeleteContact deletes a contact message by ID
func (s *ContactService) DeleteContact(id string) error {
	result := database.DB.Delete(&models.Contact{}, "id = ?", id)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return errors.New("contact not found")
	}
	return nil
}
