package training

import (
	"context"
	"time"

	"github.com/google/uuid"
)

// GetMatrixForRole returns all matrix entries for a given role
func (s *Store) GetMatrixForRole(ctx context.Context, tenantID uuid.UUID, roleCode string) ([]TrainingMatrixEntry, error) {
	rows, err := s.pool.Query(ctx, `
		SELECT
			tm.id, tm.tenant_id, tm.role_code, tm.module_id,
			tm.is_mandatory, tm.priority, tm.created_at,
			m.module_code, m.title
		FROM training_matrix tm
		JOIN training_modules m ON m.id = tm.module_id
		WHERE tm.tenant_id = $1 AND tm.role_code = $2
		ORDER BY tm.priority ASC
	`, tenantID, roleCode)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var entries []TrainingMatrixEntry
	for rows.Next() {
		var entry TrainingMatrixEntry
		err := rows.Scan(
			&entry.ID, &entry.TenantID, &entry.RoleCode, &entry.ModuleID,
			&entry.IsMandatory, &entry.Priority, &entry.CreatedAt,
			&entry.ModuleCode, &entry.ModuleTitle,
		)
		if err != nil {
			return nil, err
		}
		entries = append(entries, entry)
	}

	if entries == nil {
		entries = []TrainingMatrixEntry{}
	}

	return entries, nil
}

// GetMatrixForTenant returns the full CTM for a tenant
func (s *Store) GetMatrixForTenant(ctx context.Context, tenantID uuid.UUID) ([]TrainingMatrixEntry, error) {
	rows, err := s.pool.Query(ctx, `
		SELECT
			tm.id, tm.tenant_id, tm.role_code, tm.module_id,
			tm.is_mandatory, tm.priority, tm.created_at,
			m.module_code, m.title
		FROM training_matrix tm
		JOIN training_modules m ON m.id = tm.module_id
		WHERE tm.tenant_id = $1
		ORDER BY tm.role_code ASC, tm.priority ASC
	`, tenantID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var entries []TrainingMatrixEntry
	for rows.Next() {
		var entry TrainingMatrixEntry
		err := rows.Scan(
			&entry.ID, &entry.TenantID, &entry.RoleCode, &entry.ModuleID,
			&entry.IsMandatory, &entry.Priority, &entry.CreatedAt,
			&entry.ModuleCode, &entry.ModuleTitle,
		)
		if err != nil {
			return nil, err
		}
		entries = append(entries, entry)
	}

	if entries == nil {
		entries = []TrainingMatrixEntry{}
	}

	return entries, nil
}

// SetMatrixEntry creates or updates a CTM entry
func (s *Store) SetMatrixEntry(ctx context.Context, entry *TrainingMatrixEntry) error {
	entry.ID = uuid.New()
	entry.CreatedAt = time.Now().UTC()

	_, err := s.pool.Exec(ctx, `
		INSERT INTO training_matrix (
			id, tenant_id, role_code, module_id, is_mandatory, priority, created_at
		) VALUES ($1, $2, $3, $4, $5, $6, $7)
		ON CONFLICT (tenant_id, role_code, module_id)
		DO UPDATE SET is_mandatory = EXCLUDED.is_mandatory, priority = EXCLUDED.priority
	`,
		entry.ID, entry.TenantID, entry.RoleCode, entry.ModuleID,
		entry.IsMandatory, entry.Priority, entry.CreatedAt,
	)

	return err
}

// DeleteMatrixEntry removes a CTM entry
func (s *Store) DeleteMatrixEntry(ctx context.Context, tenantID uuid.UUID, roleCode string, moduleID uuid.UUID) error {
	_, err := s.pool.Exec(ctx,
		"DELETE FROM training_matrix WHERE tenant_id = $1 AND role_code = $2 AND module_id = $3",
		tenantID, roleCode, moduleID,
	)
	return err
}
