package httpapi

import (
	"fmt"
	"strconv"
	"strings"

	"productier/apps/backend/internal/store"
)

const (
	defaultActivityLimit = 8
	maxActivityLimit     = 40
)

var activityTypes = map[string]struct{}{
	"task":     {},
	"board":    {},
	"calendar": {},
	"note":     {},
	"focus":    {},
	"mail":     {},
	"invite":   {},
	"system":   {},
}

type activityListParams struct {
	Limit int
	Type  string
	Query string
}

func parseActivityListParams(limitRaw string, typeRaw string, queryRaw string) (activityListParams, error) {
	params := activityListParams{
		Limit: defaultActivityLimit,
		Type:  strings.TrimSpace(strings.ToLower(typeRaw)),
		Query: strings.TrimSpace(strings.ToLower(queryRaw)),
	}

	if strings.TrimSpace(limitRaw) != "" {
		parsed, err := strconv.Atoi(limitRaw)
		if err != nil {
			return activityListParams{}, fmt.Errorf("invalid limit: expected integer between 1 and %d", maxActivityLimit)
		}
		if parsed < 1 || parsed > maxActivityLimit {
			return activityListParams{}, fmt.Errorf("invalid limit: expected integer between 1 and %d", maxActivityLimit)
		}
		params.Limit = parsed
	}

	if params.Type != "" {
		if _, ok := activityTypes[params.Type]; !ok {
			return activityListParams{}, fmt.Errorf("invalid activity type")
		}
	}

	return params, nil
}

func filterActivityEntries(entries []store.ActivityEntry, params activityListParams) []store.ActivityEntry {
	if len(entries) == 0 || params.Limit == 0 {
		return []store.ActivityEntry{}
	}

	filtered := make([]store.ActivityEntry, 0, params.Limit)
	for _, entry := range entries {
		if params.Type != "" && classifyActivityEntry(entry) != params.Type {
			continue
		}
		if params.Query != "" {
			title := strings.ToLower(entry.Title)
			detail := strings.ToLower(entry.Detail)
			if !strings.Contains(title, params.Query) && !strings.Contains(detail, params.Query) {
				continue
			}
		}
		filtered = append(filtered, entry)
		if len(filtered) == params.Limit {
			break
		}
	}

	return filtered
}

func classifyActivityEntry(entry store.ActivityEntry) string {
	text := strings.ToLower(strings.TrimSpace(entry.Title + " " + entry.Detail))

	switch {
	case strings.Contains(text, "invite"):
		return "invite"
	case strings.Contains(text, "board"):
		return "board"
	case strings.Contains(text, "mail"), strings.Contains(text, "inbox"), strings.Contains(text, "smtp"), strings.Contains(text, "imap"):
		return "mail"
	case strings.Contains(text, "calendar"), strings.Contains(text, "event"):
		return "calendar"
	case strings.Contains(text, "note"):
		return "note"
	case strings.Contains(text, "focus"), strings.Contains(text, "pomodoro"):
		return "focus"
	case strings.Contains(text, "task"):
		return "task"
	default:
		return "system"
	}
}
