package training

import (
	"context"

	"github.com/google/uuid"
)

// ComputeRequiredModules returns all required training modules for a user
// based on their assigned roles. Deduplicates modules across roles.
func ComputeRequiredModules(ctx context.Context, store *Store, tenantID uuid.UUID, roleCodes []string) ([]TrainingModule, error) {
	seen := make(map[uuid.UUID]bool)
	var modules []TrainingModule

	for _, role := range roleCodes {
		entries, err := store.GetMatrixForRole(ctx, tenantID, role)
		if err != nil {
			return nil, err
		}

		for _, entry := range entries {
			if seen[entry.ModuleID] {
				continue
			}
			seen[entry.ModuleID] = true

			module, err := store.GetModule(ctx, entry.ModuleID)
			if err != nil {
				return nil, err
			}
			if module != nil && module.IsActive {
				modules = append(modules, *module)
			}
		}
	}

	if modules == nil {
		modules = []TrainingModule{}
	}

	return modules, nil
}

// GetComplianceGaps finds modules that are required but not completed for a user
func GetComplianceGaps(ctx context.Context, store *Store, tenantID uuid.UUID, userID uuid.UUID, roleCodes []string) ([]ComplianceGap, error) {
	var gaps []ComplianceGap

	for _, role := range roleCodes {
		entries, err := store.GetMatrixForRole(ctx, tenantID, role)
		if err != nil {
			return nil, err
		}

		for _, entry := range entries {
			// Check if there's an active, completed assignment for this module
			assignments, _, err := store.ListAssignments(ctx, tenantID, &AssignmentFilters{
				ModuleID: &entry.ModuleID,
				UserID:   &userID,
				Limit:    1,
			})
			if err != nil {
				return nil, err
			}

			gap := ComplianceGap{
				ModuleID:       entry.ModuleID,
				ModuleCode:     entry.ModuleCode,
				ModuleTitle:    entry.ModuleTitle,
				RoleCode:       role,
				IsMandatory:    entry.IsMandatory,
			}

			// Determine regulation area from module
			module, err := store.GetModule(ctx, entry.ModuleID)
			if err != nil {
				return nil, err
			}
			if module != nil {
				gap.RegulationArea = module.RegulationArea
			}

			if len(assignments) == 0 {
				gap.Status = "missing"
				gaps = append(gaps, gap)
			} else {
				a := assignments[0]
				gap.AssignmentID = &a.ID
				gap.Deadline = &a.Deadline

				switch a.Status {
				case AssignmentStatusCompleted:
					// No gap
					continue
				case AssignmentStatusOverdue, AssignmentStatusExpired:
					gap.Status = string(a.Status)
					gaps = append(gaps, gap)
				default:
					// Check if overdue
					if a.Deadline.Before(timeNow()) {
						gap.Status = "overdue"
						gaps = append(gaps, gap)
					}
				}
			}
		}
	}

	if gaps == nil {
		gaps = []ComplianceGap{}
	}

	return gaps, nil
}

// BuildMatrixResponse builds the full CTM response grouped by role
func BuildMatrixResponse(entries []TrainingMatrixEntry) *MatrixResponse {
	resp := &MatrixResponse{
		Entries: make(map[string][]TrainingMatrixEntry),
		Roles:   RoleLabels,
	}

	for _, entry := range entries {
		resp.Entries[entry.RoleCode] = append(resp.Entries[entry.RoleCode], entry)
	}

	return resp
}
