package organization

import (
	"context"
	"fmt"
	"strings"
	"time"
)

const (
	feishuAutoJoinStatusSuccess                  = "success"
	feishuAutoJoinStatusNoMatch                  = "no_match"
	feishuAutoJoinStatusAmbiguousMatch           = "ambiguous_match"
	feishuAutoJoinStatusDirectoryUserNotImported = "directory_user_not_imported"
	feishuAutoJoinStatusDirectoryMemberInactive  = "directory_member_inactive"
	feishuAutoJoinStatusConflictingMember        = "conflicting_member"
	feishuAutoJoinStatusLookupError              = "lookup_error"

	feishuAutoJoinSubjectTypeEmail  = "email"
	feishuAutoJoinSubjectTypeMobile = "mobile"
)

type feishuAutoJoinStatusInput struct {
	Status      string
	SubjectType string
	SubjectHint string
	Message     string
	AttemptedAt time.Time
}

func (txs TxStore) recordFeishuAutoJoinStatus(ctx context.Context, organizationID string, input feishuAutoJoinStatusInput) error {
	organizationID = strings.TrimSpace(organizationID)
	if organizationID == "" {
		return fmt.Errorf("organization id is required")
	}

	attemptedAt := input.AttemptedAt.UTC()
	if _, err := txs.db.Exec(ctx, `
UPDATE organization_settings
SET feishu_last_auto_join_status = $2,
    feishu_last_auto_join_subject_type = $3,
    feishu_last_auto_join_subject_hint = $4,
    feishu_last_auto_join_message = $5,
    feishu_last_auto_join_attempted_at = $6,
    updated_at = $6
WHERE organization_id = $1
`, organizationID, strings.TrimSpace(input.Status), strings.TrimSpace(input.SubjectType), strings.TrimSpace(input.SubjectHint), strings.TrimSpace(input.Message), attemptedAt); err != nil {
		return fmt.Errorf("record feishu auto join status: %w", err)
	}
	return nil
}

func redactFeishuAutoJoinEmailHint(email string) string {
	resolvedEmail := strings.ToLower(strings.TrimSpace(email))
	if resolvedEmail == "" {
		return ""
	}

	localPart, domainPart, found := strings.Cut(resolvedEmail, "@")
	if !found || strings.TrimSpace(domainPart) == "" {
		return redactFeishuAutoJoinHintToken(localPart)
	}
	return redactFeishuAutoJoinHintToken(localPart) + "@" + domainPart
}

func redactFeishuAutoJoinHintToken(value string) string {
	trimmed := strings.TrimSpace(value)
	if trimmed == "" {
		return ""
	}

	runes := []rune(trimmed)
	switch len(runes) {
	case 0:
		return ""
	case 1:
		return "*"
	case 2:
		return string(runes[0]) + "*"
	default:
		visiblePrefixLength := 1
		if len(runes) > 4 {
			visiblePrefixLength = 2
		}
		return string(runes[:visiblePrefixLength]) + strings.Repeat("*", len(runes)-visiblePrefixLength)
	}
}
