package data

import (
	"actatempus_backend/internal/domain/data"
	"actatempus_backend/internal/infrastructure/data/db"
	"context"
	"log"
)

// PrismaDatabase provides access to various data sources and manages the Prisma client.
type PrismaDatabase struct {
	client       *db.PrismaClient
	users        data.UserDataSource
	timeEntries  data.TimeEntryDataSource
	projectTasks data.ProjectTaskDataSource
	projects     data.ProjectDataSource
}

// NewPrismaDatabase initializes the Prisma client and the data sources.
func NewPrismaDatabase() (*PrismaDatabase, error) {
	// Create a new Prisma client
	client := db.NewClient()

	// Test the connection to ensure the client is working
	if err := client.Connect(); err != nil {
		return nil, err
	}

	// Initialize the database and data sources
	db := &PrismaDatabase{
		client:       client,
		users:        NewPrismaUserDataSource(client),
		timeEntries:  NewPrismaTimeEntryDataSource(client),
		projectTasks: NewPrismaProjectTaskDataSource(client),
		projects:     NewPrismaProjectDataSource(client),
	}

	log.Println("Database initialized")
	return db, nil
}

// Users returns the User data source.
func (db *PrismaDatabase) Users() data.UserDataSource {
	return db.users
}

// TimeEntries returns the TimeEntry data source.
func (db *PrismaDatabase) TimeEntries() data.TimeEntryDataSource {
	return db.timeEntries
}

// ProjectTasks returns the ProjectTask data source.
func (db *PrismaDatabase) ProjectTasks() data.ProjectTaskDataSource {
	return db.projectTasks
}

// Projects returns the Project data source.
func (db *PrismaDatabase) Projects() data.ProjectDataSource {
	return db.projects
}

// Close releases the Prisma client connection.
func (db *PrismaDatabase) Close(ctx context.Context) error {
	log.Println("Closing database connection")
	return db.client.Disconnect()
}
