package events

import (
	"encoding/json"
	"time"

	"deployment-manager/internal/model"
)

type EventType string

const (
	EventTypeRepoCreated   EventType = "repo_created"
	EventTypeRepoUpdated   EventType = "repo_updated"
	EventTypeRepoDeleted   EventType = "repo_deleted"
	EventTypeDeployStarted EventType = "deploy_started"
	EventTypeDeploySuccess EventType = "deploy_success"
	EventTypeDeployError   EventType = "deploy_error"
	EventTypeLog           EventType = "log"
)

type Event struct {
	ID        string            `json:"id"`
	Type      EventType         `json:"type"`
	RepoID    int64             `json:"repo_id"`
	Data      map[string]interface{} `json:"data"`
	Timestamp time.Time         `json:"timestamp"`
}

func NewEvent(eventType EventType, repoID int64, data map[string]interface{}) *Event {
	return &Event{
		ID:        generateEventID(),
		Type:      eventType,
		RepoID:    repoID,
		Data:      data,
		Timestamp: time.Now(),
	}
}

func NewRepoEvent(repo *model.Repo, eventType EventType) *Event {
	return NewEvent(eventType, repo.ID, map[string]interface{}{
		"repo": repo,
	})
}

func NewLogEvent(repoID int64, message string) *Event {
	return NewEvent(EventTypeLog, repoID, map[string]interface{}{
		"message": message,
	})
}

func (e *Event) ToJSON() ([]byte, error) {
	return json.Marshal(e)
}

func generateEventID() string {
	return time.Now().Format("20060102150405") + "-" + randomString(8)
}

func randomString(n int) string {
	const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, n)
	for i := range b {
		b[i] = letters[i%len(letters)]
	}
	return string(b)
}
