package imap

import (
	"strings"

	"github.com/emersion/go-imap/v2"
)

var folderDisplayNames = map[string]string{
	"inbox":   "Inbox",
	"sent":    "Sent",
	"drafts":  "Drafts",
	"trash":   "Trash",
	"archive": "Archive",
	"spam":    "Spam",
}

var folderNameHeuristics = map[string]string{
	"inbox":             "inbox",
	"sent":              "sent",
	"sent items":        "sent",
	"sent messages":     "sent",
	"[gmail]/sent mail": "sent",
	"inbox.sent":        "sent",
	"drafts":            "drafts",
	"[gmail]/drafts":    "drafts",
	"trash":             "trash",
	"deleted":           "trash",
	"[gmail]/trash":     "trash",
	"archive":           "archive",
	"all mail":          "archive",
	"[gmail]/all mail":  "archive",
	"junk":              "spam",
	"spam":              "spam",
	"[gmail]/spam":      "spam",
}

// DetectFolderType classifies an IMAP mailbox for sync using SPECIAL-USE
// attributes when present, otherwise name heuristics. NoSelect mailboxes
// return "" so callers can skip sync.
func DetectFolderType(mailbox string, attrs []imap.MailboxAttr) string {
	for _, attr := range attrs {
		if attr == imap.MailboxAttrNoSelect {
			return ""
		}
	}

	if folderType := folderTypeFromAttrs(attrs); folderType != "" {
		return folderType
	}

	return folderTypeFromName(mailbox)
}

// DisplayName returns a user-facing folder label from the detected type,
// or the last path segment of mailbox when type is custom or unknown.
func DisplayName(mailbox, folderType string) string {
	folderType = strings.ToLower(strings.TrimSpace(folderType))
	if name, ok := folderDisplayNames[folderType]; ok {
		return name
	}
	return mailboxLeaf(mailbox)
}

func folderTypeFromAttrs(attrs []imap.MailboxAttr) string {
	for _, attr := range attrs {
		switch attr {
		case imap.MailboxAttrSent:
			return "sent"
		case imap.MailboxAttrDrafts:
			return "drafts"
		case imap.MailboxAttrTrash:
			return "trash"
		case imap.MailboxAttrArchive:
			return "archive"
		case imap.MailboxAttrJunk:
			return "spam"
		}
	}
	return ""
}

func folderTypeFromName(mailbox string) string {
	full := strings.ToLower(strings.TrimSpace(mailbox))
	if folderType, ok := folderNameHeuristics[full]; ok {
		return folderType
	}

	leaf := strings.ToLower(mailboxLeaf(mailbox))
	if folderType, ok := folderNameHeuristics[leaf]; ok {
		return folderType
	}

	return "custom"
}

func mailboxLeaf(mailbox string) string {
	mailbox = strings.TrimSpace(mailbox)
	if mailbox == "" {
		return ""
	}

	leaf := mailbox
	for _, sep := range []string{"/", "."} {
		if idx := strings.LastIndex(leaf, sep); idx >= 0 && idx < len(leaf)-len(sep) {
			leaf = leaf[idx+len(sep):]
		}
	}
	return leaf
}

// FolderDerivedLabels returns Ultimail labels inferred from IMAP mailbox path/name.
func FolderDerivedLabels(mailbox string) []string {
	if strings.ToLower(mailboxLeaf(mailbox)) == "important" {
		return []string{"important"}
	}
	return nil
}
