package activity

import (
	"strings"
	"system-altrak/internal/domain"
)

const (
	ModuleKeyUnknown         = "unknown"
	ModuleKeyAuthentication  = "authentication"
	ModuleKeyAuditLog        = "audit_log"
	ModuleKeyPOStatus        = "po_status"
	ModuleKeyCustomerProfile = "customer_profile"
	ModuleKeyIOMManagement   = "iom_management"
	ModuleKeyISRManagement   = "isr_management"
	ModuleKeyUserAccounts    = "user_accounts"
	ModuleKeyCreditLimit     = "credit_limit"
	ModuleKeyServiceJobIOM   = "service_job_iom"

	ResourceKeyOperationalRecord  = "operational_record"
	ResourceKeyCustomerProfile    = "customer_profile"
	ResourceKeyMemorandum         = "memorandum"
	ResourceKeyCreditLimit        = "credit_limit"
	ResourceKeyServiceJobIOM      = "service_job_iom"
	ResourceKeyServiceRequisition = "service_requisition"
	ResourceKeyUserAccount        = "user_account"
)

type moduleDescriptor struct {
	Key   string
	Label string
}

var moduleDescriptors = []moduleDescriptor{
	{Key: ModuleKeyPOStatus, Label: "PO Status"},
	{Key: ModuleKeyCustomerProfile, Label: "Customer Profile"},
	{Key: ModuleKeyIOMManagement, Label: "IOM Management"},
	{Key: ModuleKeyISRManagement, Label: "ISR Management"},
	{Key: ModuleKeyUserAccounts, Label: "User Account"},
	{Key: ModuleKeyAuthentication, Label: "Authentication"},
	{Key: ModuleKeyCreditLimit, Label: "Credit Limit"},
	{Key: ModuleKeyServiceJobIOM, Label: "Service Job IOM"},
	{Key: ModuleKeyAuditLog, Label: "Audit Log"},
	{Key: ModuleKeyUnknown, Label: "Unknown"},
}

func resolveModuleKeyText(raw string) string {
	normalized := strings.ToLower(strings.TrimSpace(raw))
	if normalized == "" {
		return ModuleKeyUnknown
	}

	normalized = strings.ReplaceAll(normalized, "-", "_")
	normalized = strings.ReplaceAll(normalized, " ", "_")

	switch normalized {
	case "auth", "authentication", "login", "logout", "refresh", "session":
		return ModuleKeyAuthentication
	case "audit", "audit_log", "activity", "activity_log", "activities":
		return ModuleKeyAuditLog
	case "po_status", "pso", "po", "docs", "pso_status":
		return ModuleKeyPOStatus
	case "customer_profile", "customerprofile":
		return ModuleKeyCustomerProfile
	case "iom_management", "iom":
		return ModuleKeyIOMManagement
	case "isr_management", "isr", "sr", "service_requisition":
		return ModuleKeyISRManagement
	case "user_accounts", "user_mgmt", "users", "admin_users", "user":
		return ModuleKeyUserAccounts
	case "credit_limit", "creditlimit":
		return ModuleKeyCreditLimit
	case "service_job_iom", "sjr":
		return ModuleKeyServiceJobIOM
	}

	if strings.Contains(normalized, "/login") || strings.Contains(normalized, "/logout") || strings.Contains(normalized, "/refresh") || strings.Contains(normalized, "/session") {
		return ModuleKeyAuthentication
	}
	if strings.Contains(normalized, "/activities") || strings.Contains(normalized, "/activity") {
		return ModuleKeyAuditLog
	}
	if strings.Contains(normalized, "/admin/users") {
		return ModuleKeyUserAccounts
	}
	if strings.Contains(normalized, "/customer-profile") {
		return ModuleKeyCustomerProfile
	}
	if strings.Contains(normalized, "/service-job-iom") {
		return ModuleKeyServiceJobIOM
	}
	if strings.Contains(normalized, "/credit-limit") {
		return ModuleKeyCreditLimit
	}
	if strings.Contains(normalized, "/iom") {
		return ModuleKeyIOMManagement
	}
	if strings.Contains(normalized, "/sr") {
		return ModuleKeyISRManagement
	}
	if strings.Contains(normalized, "/pso") || strings.Contains(normalized, "/po") || strings.Contains(normalized, "/docs") || strings.Contains(normalized, "/import/po-status") || strings.Contains(normalized, "/export/po") {
		return ModuleKeyPOStatus
	}

	return ModuleKeyUnknown
}

func ResolveModuleKeyFromPath(path string) string {
	return resolveModuleKeyText(path)
}

func ResolveModuleKeyFromValues(values ...string) string {
	for _, value := range values {
		if key := resolveModuleKeyText(value); key != ModuleKeyUnknown {
			return key
		}
	}

	return ModuleKeyUnknown
}

func ResolveModuleLabel(moduleKey string) string {
	key := resolveModuleKeyText(moduleKey)
	for _, descriptor := range moduleDescriptors {
		if descriptor.Key == key {
			return descriptor.Label
		}
	}

	return "Unknown"
}

func ResolveActionLabel(method, path string) string {
	normalizedMethod := strings.ToUpper(strings.TrimSpace(method))
	normalizedPath := strings.ToLower(strings.TrimSpace(path))

	switch {
	case normalizedMethod == "POST" && normalizedPath == "/login":
		return "LOGIN"
	case normalizedMethod == "POST" && normalizedPath == "/logout":
		return "LOGOUT"
	case strings.Contains(normalizedPath, "/restore"):
		return "RESTORE"
	case strings.Contains(normalizedPath, "/verify"):
		return "VERIFY"
	case strings.Contains(normalizedPath, "/import"):
		return "IMPORT"
	case strings.Contains(normalizedPath, "/export") || strings.Contains(normalizedPath, "/pdf"):
		return "EXPORT"
	case normalizedMethod == "POST":
		return "CREATE"
	case normalizedMethod == "PUT" || normalizedMethod == "PATCH":
		return "UPDATE"
	case normalizedMethod == "DELETE":
		return "DELETE"
	case normalizedMethod == "GET":
		return "VIEW"
	default:
		if normalizedMethod == "" {
			return "UNKNOWN"
		}
		return normalizedMethod
	}
}

func ResolveActionLabelFromValues(values ...string) string {
	for _, value := range values {
		normalized := strings.ToUpper(strings.TrimSpace(value))
		if normalized == "" {
			continue
		}

		fields := strings.Fields(normalized)
		if len(fields) > 0 {
			candidate := fields[0]
			switch candidate {
			case "LOGIN", "LOGOUT", "CREATE", "UPDATE", "DELETE", "VERIFY", "IMPORT", "EXPORT", "RESTORE", "VIEW":
				return candidate
			}
		}

		if strings.Contains(normalized, "/login") {
			return "LOGIN"
		}
		if strings.Contains(normalized, "/logout") {
			return "LOGOUT"
		}
		if strings.Contains(normalized, "/restore") {
			return "RESTORE"
		}
		if strings.Contains(normalized, "/verify") {
			return "VERIFY"
		}
		if strings.Contains(normalized, "/import") {
			return "IMPORT"
		}
		if strings.Contains(normalized, "/export") || strings.Contains(normalized, "/pdf") {
			return "EXPORT"
		}
	}

	return "UNKNOWN"
}

func ResolveModuleKeyFromLog(log domain.ActivityLog) string {
	return ResolveModuleKeyFromValues(log.Module, log.Action, log.Details)
}

func NormalizeActivityLog(log *domain.ActivityLog) {
	if log == nil {
		return
	}

	rawAction := strings.TrimSpace(log.Action)
	rawDetails := strings.TrimSpace(log.Details)

	log.Module = ResolveModuleKeyFromValues(log.Module, rawAction, rawDetails)
	if log.Module == ModuleKeyUnknown {
		log.Module = ModuleKeyAuditLog
	}

	log.Action = ResolveActionLabelFromValues(rawAction, rawDetails)
	if log.Action == "UNKNOWN" {
		log.Action = ResolveActionLabel(rawAction, rawDetails)
	}

	if rawDetails == "" {
		log.Details = rawAction
	}
}
