package apperrors

import (
	"errors"
	"fmt"
	"strings"
)

type DeleteConflictError struct {
	RelatedModules []string
}

func (e *DeleteConflictError) Error() string {
	modules := cleanModules(e.RelatedModules)
	if len(modules) == 0 {
		return "cannot delete this data because it is currently used by another module. please remove the relation first"
	}
	return fmt.Sprintf(
		"cannot delete this data because it is currently used by %s. please remove the relation first",
		strings.Join(modules, ", "),
	)
}

func IsDeleteConflict(err error) bool {
	var target *DeleteConflictError
	return errors.As(err, &target)
}

func AsDeleteConflict(err error) (*DeleteConflictError, bool) {
	var target *DeleteConflictError
	if !errors.As(err, &target) {
		return nil, false
	}
	return target, true
}

func NewDeleteConflictError(relatedModules ...string) error {
	return &DeleteConflictError{RelatedModules: cleanModules(relatedModules)}
}

func cleanModules(in []string) []string {
	out := make([]string, 0, len(in))
	seen := map[string]struct{}{}
	for _, module := range in {
		trimmed := strings.TrimSpace(module)
		if trimmed == "" {
			continue
		}
		key := strings.ToLower(trimmed)
		if _, ok := seen[key]; ok {
			continue
		}
		seen[key] = struct{}{}
		out = append(out, trimmed)
	}
	return out
}
