package testutil

import (
	"embed"

	"gogs.dmsc.dev/arp/models"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

//go:embed init_tests.sql
var initSQLFS embed.FS

// SetupTestDB creates an in-memory SQLite database for testing
func SetupTestDB() (*gorm.DB, error) {
	db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
	if err != nil {
		return nil, err
	}

	// Run auto-migration for all models
	err = db.AutoMigrate(
		&models.User{},
		&models.Role{},
		&models.Permission{},
		&models.Service{},
		&models.Task{},
		&models.TaskStatus{},
		&models.Message{},
		&models.Note{},
	)
	if err != nil {
		return nil, err
	}

	return db, nil
}

// BootstrapTestDB initializes the database with initial data from init_tests.sql
func BootstrapTestDB(db *gorm.DB) error {
	// Read the init SQL file
	sqlContent, err := initSQLFS.ReadFile("init_tests.sql")
	if err != nil {
		return err
	}

	// Execute the SQL
	return db.Exec(string(sqlContent)).Error
}

// SetupAndBootstrapTestDB creates an in-memory database and bootstraps it with initial data
func SetupAndBootstrapTestDB() (*gorm.DB, error) {
	db, err := SetupTestDB()
	if err != nil {
		return nil, err
	}

	if err := BootstrapTestDB(db); err != nil {
		return nil, err
	}

	return db, nil
}

// SeedData contains all hardcoded test fixtures
type SeedData struct {
	Permissions  []PermissionFixture
	Roles        []RoleFixture
	Users        []UserFixture
	TaskStatuses []TaskStatusFixture
	Services     []ServiceFixture
	Tasks        []TaskFixture
	Notes        []NoteFixture
	Messages     []MessageFixture
}

// PermissionFixture represents test permission data
type PermissionFixture struct {
	Code        string
	Description string
}

// RoleFixture represents test role data
type RoleFixture struct {
	Name            string
	Description     string
	PermissionCodes []string
}

// UserFixture represents test user data
type UserFixture struct {
	Email     string
	Password  string
	RoleNames []string
}

// TaskStatusFixture represents test task status data
type TaskStatusFixture struct {
	Code  string
	Label string
}

// ServiceFixture represents test service data
type ServiceFixture struct {
	Name              string
	Description       string
	CreatorEmail      string
	ParticipantEmails []string
}

// TaskFixture represents test task data
type TaskFixture struct {
	Title         string
	Content       string
	CreatorEmail  string
	AssigneeEmail string
	StatusCode    string
	Priority      string
}

// NoteFixture represents test note data
type NoteFixture struct {
	Title       string
	Content     string
	UserEmail   string
	ServiceName string
}

// MessageFixture represents test message data
type MessageFixture struct {
	SenderEmail    string
	Content        string
	ReceiverEmails []string
}

// GetSeedData returns the hardcoded seed data for testing
func GetSeedData() SeedData {
	return SeedData{
		Permissions: []PermissionFixture{
			{Code: "user:read", Description: "Read user information"},
			{Code: "user:write", Description: "Create and update users"},
			{Code: "task:read", Description: "Read task information"},
			{Code: "task:write", Description: "Create and update tasks"},
			{Code: "service:read", Description: "Read service information"},
			{Code: "service:write", Description: "Create and update services"},
			{Code: "note:read", Description: "Read notes"},
			{Code: "note:write", Description: "Create and update notes"},
		},
		Roles: []RoleFixture{
			{
				Name:            "admin",
				Description:     "Administrator with full access",
				PermissionCodes: []string{"user:read", "user:write", "task:read", "task:write", "service:read", "service:write", "note:read", "note:write"},
			},
			{
				Name:            "member",
				Description:     "Team member with read access and limited write access",
				PermissionCodes: []string{"user:read", "task:read", "task:write", "service:read", "note:read", "note:write"},
			},
			{
				Name:            "viewer",
				Description:     "Read-only access",
				PermissionCodes: []string{"user:read", "task:read", "service:read", "note:read"},
			},
		},
		Users: []UserFixture{
			// Note: admin@example.com is bootstrapped via init_tests.sql
			{
				Email:     "member1@example.com",
				Password:  "member1-hashed-password",
				RoleNames: []string{"member"},
			},
			{
				Email:     "member2@example.com",
				Password:  "member2-hashed-password",
				RoleNames: []string{"member"},
			},
			{
				Email:     "viewer@example.com",
				Password:  "viewer-hashed-password",
				RoleNames: []string{"viewer"},
			},
		},
		TaskStatuses: []TaskStatusFixture{
			{Code: "open", Label: "Open"},
			{Code: "in_progress", Label: "In Progress"},
			{Code: "review", Label: "Under Review"},
			{Code: "done", Label: "Completed"},
		},
		Services: []ServiceFixture{
			{
				Name:              "Project Alpha",
				Description:       "Main project for alpha development",
				CreatorEmail:      "admin@example.com",
				ParticipantEmails: []string{"admin@example.com", "member1@example.com", "member2@example.com"},
			},
			{
				Name:              "Project Beta",
				Description:       "Secondary project for beta testing",
				CreatorEmail:      "admin@example.com",
				ParticipantEmails: []string{"member1@example.com", "viewer@example.com"},
			},
		},
		Tasks: []TaskFixture{
			{
				Title:         "Setup development environment",
				Content:       "Initialize the development environment with all required tools and dependencies",
				CreatorEmail:  "admin@example.com",
				AssigneeEmail: "member1@example.com",
				StatusCode:    "done",
				Priority:      "high",
			},
			{
				Title:         "Implement user authentication",
				Content:       "Create the authentication module with login, logout, and password reset functionality",
				CreatorEmail:  "admin@example.com",
				AssigneeEmail: "member1@example.com",
				StatusCode:    "in_progress",
				Priority:      "high",
			},
			{
				Title:         "Write API documentation",
				Content:       "Document all API endpoints with request/response examples",
				CreatorEmail:  "member1@example.com",
				AssigneeEmail: "member2@example.com",
				StatusCode:    "review",
				Priority:      "medium",
			},
			{
				Title:         "Setup CI/CD pipeline",
				Content:       "Configure continuous integration and deployment pipeline",
				CreatorEmail:  "admin@example.com",
				AssigneeEmail: "",
				StatusCode:    "open",
				Priority:      "medium",
			},
			{
				Title:         "Performance optimization",
				Content:       "Optimize database queries and implement caching",
				CreatorEmail:  "member2@example.com",
				AssigneeEmail: "",
				StatusCode:    "open",
				Priority:      "low",
			},
		},
		Notes: []NoteFixture{
			{
				Title:       "Architecture decisions",
				Content:     "Document key architectural decisions and their rationale",
				UserEmail:   "admin@example.com",
				ServiceName: "Project Alpha",
			},
			{
				Title:       "Meeting notes - Sprint 1",
				Content:     "Notes from the first sprint planning meeting",
				UserEmail:   "member1@example.com",
				ServiceName: "Project Alpha",
			},
			{
				Title:       "Testing strategy",
				Content:     "Outline the testing approach for the beta release",
				UserEmail:   "member1@example.com",
				ServiceName: "Project Beta",
			},
		},
		Messages: []MessageFixture{
			{
				SenderEmail:    "admin@example.com",
				Content:        "Welcome to the project channel!",
				ReceiverEmails: []string{"member1@example.com"},
			},
			{
				SenderEmail:    "member1@example.com",
				Content:        "Thanks! Excited to get started.",
				ReceiverEmails: []string{"admin@example.com"},
			},
			{
				SenderEmail:    "member1@example.com",
				Content:        "Hey, let us discuss the API documentation.",
				ReceiverEmails: []string{"member2@example.com"},
			},
			{
				SenderEmail:    "member2@example.com",
				Content:        "Sure, I will start drafting it today.",
				ReceiverEmails: []string{"member1@example.com"},
			},
			{
				SenderEmail:    "admin@example.com",
				Content:        "Team announcement: Sprint review tomorrow at 2pm.",
				ReceiverEmails: []string{"member1@example.com", "member2@example.com", "viewer@example.com"},
			},
		},
	}
}
