package discovery

import (
	"strings"
)

// suggestableProfilesSQL filters profiles that only have a bare email address.
const suggestableProfilesSQL = `
	  AND (
	    EXISTS (
	      SELECT 1 FROM contact_discovered_signatures s
	      WHERE s.profile_id = p.id
	    )
	    OR (
	      COALESCE(trim(p.display_name), '') != ''
	      AND p.display_name NOT ILIKE '%@%'
	      AND lower(trim(p.display_name)) != lower(split_part(p.primary_email, '@', 1))
	    )
	    OR (
	      p.enriched_data IS NOT NULL
	      AND (
	        nullif(trim(p.enriched_data->>'first_name'), '') IS NOT NULL
	        OR nullif(trim(p.enriched_data->>'last_name'), '') IS NOT NULL
	        OR nullif(trim(p.enriched_data->>'company'), '') IS NOT NULL
	        OR nullif(trim(p.enriched_data->>'department'), '') IS NOT NULL
	        OR nullif(trim(p.enriched_data->>'job_title'), '') IS NOT NULL
	        OR nullif(trim(p.enriched_data->>'website'), '') IS NOT NULL
	        OR nullif(trim(p.enriched_data->>'notes'), '') IS NOT NULL
	        OR jsonb_array_length(COALESCE(p.enriched_data->'social_profiles', '[]'::jsonb)) > 0
	        OR jsonb_array_length(COALESCE(p.enriched_data->'phones', '[]'::jsonb)) > 0
	        OR jsonb_array_length(COALESCE(p.enriched_data->'addresses', '[]'::jsonb)) > 0
	      )
	    )
	    OR EXISTS (
	      SELECT 1
	      FROM jsonb_array_elements(COALESCE(p.all_emails, '[]'::jsonb)) AS e
	      WHERE nullif(trim(e->>'display_name'), '') IS NOT NULL
	        AND (e->>'display_name') NOT ILIKE '%@%'
	        AND lower(trim(e->>'display_name')) != lower(split_part(COALESCE(e->>'email', ''), '@', 1))
	    )
	  )`

func hasMeaningfulDisplayName(name, email string) bool {
	name = strings.TrimSpace(name)
	if name == "" || strings.Contains(name, "@") {
		return false
	}
	local := emailLocalPart(email)
	if local == "" {
		return true
	}
	return strings.ToLower(name) != local
}

func emailLocalPart(email string) string {
	email = strings.TrimSpace(email)
	at := strings.LastIndex(email, "@")
	if at <= 0 {
		return strings.ToLower(email)
	}
	return strings.ToLower(email[:at])
}

func enrichedDataHasValueBeyondEmail(data *EnrichedContactData) bool {
	if data == nil {
		return false
	}
	if strings.TrimSpace(data.FirstName) != "" ||
		strings.TrimSpace(data.LastName) != "" ||
		strings.TrimSpace(data.Company) != "" ||
		strings.TrimSpace(data.Department) != "" ||
		strings.TrimSpace(data.JobTitle) != "" ||
		strings.TrimSpace(data.Website) != "" ||
		strings.TrimSpace(data.Notes) != "" {
		return true
	}
	for _, sp := range data.SocialProfiles {
		if strings.TrimSpace(sp.Value) != "" {
			return true
		}
	}
	for _, p := range data.Phones {
		if strings.TrimSpace(p.Value) != "" {
			return true
		}
	}
	for _, a := range data.Addresses {
		if strings.TrimSpace(a.Street) != "" ||
			strings.TrimSpace(a.City) != "" ||
			strings.TrimSpace(a.Region) != "" ||
			strings.TrimSpace(a.PostalCode) != "" ||
			strings.TrimSpace(a.Country) != "" {
			return true
		}
	}
	return false
}

// ProfileHasValueBeyondEmail reports whether a profile has contact info beyond a bare email.
func ProfileHasValueBeyondEmail(p Profile) bool {
	if len(p.Signatures) > 0 {
		return true
	}
	if enrichedDataHasValueBeyondEmail(p.EnrichedData) {
		return true
	}
	if hasMeaningfulDisplayName(p.DisplayName, p.PrimaryEmail) {
		return true
	}
	for _, e := range p.AllEmails {
		if hasMeaningfulDisplayName(e.DisplayName, e.Email) {
			return true
		}
	}
	return false
}

func profileGroupHasValueBeyondEmail(group ProfileGroup) bool {
	for _, p := range group.Profiles {
		if ProfileHasValueBeyondEmail(p) {
			return true
		}
	}
	return ProfileHasValueBeyondEmail(group.Profile)
}

func profileHasNoReplyEmail(p Profile) bool {
	if isNoReplyEmail(p.PrimaryEmail) {
		return true
	}
	for _, e := range p.AllEmails {
		if isNoReplyEmail(e.Email) {
			return true
		}
	}
	if p.EnrichedData != nil {
		for _, e := range p.EnrichedData.Emails {
			if isNoReplyEmail(e.Value) {
				return true
			}
		}
	}
	return false
}

func profileGroupHasNoReplyEmail(group ProfileGroup) bool {
	for _, p := range group.Profiles {
		if profileHasNoReplyEmail(p) {
			return true
		}
	}
	return profileHasNoReplyEmail(group.Profile)
}

func filterSuggestableGroups(groups []ProfileGroup) []ProfileGroup {
	if len(groups) == 0 {
		return groups
	}
	out := make([]ProfileGroup, 0, len(groups))
	for _, g := range groups {
		if profileGroupHasNoReplyEmail(g) {
			continue
		}
		if profileGroupHasValueBeyondEmail(g) {
			out = append(out, g)
		}
	}
	return out
}
