package discovery

import (
	"context"
	"encoding/json"
	"fmt"
	"strings"

	"github.com/ultisuite/ulti-backend/internal/llm"
	"github.com/ultisuite/ulti-backend/internal/websearch"
)

const improveContactSystemPrompt = `Tu es un assistant qui nettoie, structure et enrichit une fiche contact existante.
Réponds UNIQUEMENT en JSON valide, sans markdown ni texte autour.
Corrige les problèmes de formatage : URLs avec slash final, accents/casse des noms, téléphones, adresses mal remplies ou incomplètes, champs vides inutiles.
Réorganise les informations de façon cohérente. Ne supprime pas d'emails ou téléphones valides.
Tu peux compléter poste, entreprise, site web, réseaux sociaux ou notes à partir des résultats de recherche en ligne fournis, uniquement si tu es raisonnablement confiant qu'ils concernent cette personne (profils LinkedIn, pages entreprise, etc.). En cas de doute ou d'homonymie, n'ajoute rien de nouveau.
Quand des résultats de recherche mentionnent des profils LinkedIn ou d'autres réseaux sociaux pertinents, ajoute-les dans social_profiles avec l'URL complète. Ne mets pas LinkedIn dans website : website = site personnel ou entreprise, social_profiles = profils sociaux.
Format attendu:
{
  "first_name": "",
  "last_name": "",
  "company": "",
  "department": "",
  "job_title": "",
  "emails": [{"value": "", "label": "work|home|other"}],
  "phones": [{"value": "", "label": "work|mobile|home|other"}],
  "addresses": [{"street": "", "city": "", "region": "", "postal_code": "", "country": "", "label": "work|home"}],
  "website": "",
  "social_profiles": [{"value": "https://...", "label": "linkedin|twitter|facebook|instagram|github|other"}],
  "notes": ""
}`

type ImproveContactInput struct {
	FirstName  string           `json:"first_name"`
	LastName   string           `json:"last_name"`
	MiddleName string           `json:"middle_name,omitempty"`
	Company    string           `json:"company,omitempty"`
	Department string           `json:"department,omitempty"`
	JobTitle   string           `json:"job_title,omitempty"`
	Website    string           `json:"website,omitempty"`
	Notes      string           `json:"notes,omitempty"`
	Emails     []FieldWithLabel `json:"emails,omitempty"`
	Phones         []FieldWithLabel `json:"phones,omitempty"`
	Addresses      []AddressField   `json:"addresses,omitempty"`
	SocialProfiles []FieldWithLabel `json:"social_profiles,omitempty"`
	Birthday       string           `json:"birthday,omitempty"`
	RawVCard   string           `json:"raw_vcard,omitempty"`
}

func contactCityFromAddresses(addresses []AddressField) string {
	for _, a := range addresses {
		if city := strings.TrimSpace(a.City); city != "" {
			return city
		}
	}
	return ""
}

func buildImproveContactPrompt(input ImproveContactInput, searchSection string) string {
	var b strings.Builder
	b.WriteString("Fiche contact actuelle:\n")
	payload, _ := json.MarshalIndent(input, "", "  ")
	b.Write(payload)
	if searchSection != "" {
		b.WriteString("\n\n")
		b.WriteString(searchSection)
		b.WriteString("\n\nÀ partir de ces résultats, complète social_profiles (LinkedIn en priorité, puis X/Twitter, Facebook, Instagram, GitHub) lorsque l'URL correspond clairement à cette personne.")
	}
	b.WriteString("\n\nPropose une version nettoyée, mieux structurée et enrichie si les sources le permettent.")
	return b.String()
}

func (s *Service) fetchContactSearchResults(ctx context.Context, externalUserID string, input ImproveContactInput) string {
	if s.websearch == nil {
		return ""
	}
	searchSettings, err := s.loadSearchSettings(ctx, externalUserID)
	if err != nil || !searchSettingsConfigured(searchSettings) {
		return ""
	}
	provider, err := websearch.ResolveProvider(searchSettings)
	if err != nil {
		return ""
	}
	query := websearch.BuildContactSearchQuery(
		input.FirstName,
		input.LastName,
		input.MiddleName,
		input.Company,
		input.JobTitle,
		contactCityFromAddresses(input.Addresses),
	)
	if query == "" {
		return ""
	}
	results, err := s.websearch.Search(ctx, provider, query, 5)
	if err != nil {
		s.logger.Warn("contact improve web search failed", "error", err)
		return ""
	}
	return websearch.FormatResultsForPrompt(results)
}

func (s *Service) ImproveContact(ctx context.Context, externalUserID string, input ImproveContactInput) (*EnrichedContactData, error) {
	if s.llm == nil {
		return nil, ErrLLMNotConfigured
	}
	llmSettings, err := s.loadLLMSettings(ctx, externalUserID)
	if err != nil || !llmSettingsHasProvider(llmSettings) {
		return nil, ErrLLMNotConfigured
	}
	provider, model, err := llm.ResolveProvider(llmSettings, "")
	if err != nil {
		return nil, err
	}

	improveCtx, cancel := context.WithTimeout(ctx, llmEnrichTimeout)
	defer cancel()

	searchSection := s.fetchContactSearchResults(improveCtx, externalUserID, input)
	prompt := buildImproveContactPrompt(input, searchSection)
	raw, err := s.llm.Complete(improveCtx, provider, model, improveContactSystemPrompt, prompt)
	if err != nil {
		return nil, err
	}
	data, err := parseEnrichedData(raw)
	if err != nil {
		return nil, fmt.Errorf("parse improved contact: %w", err)
	}
	return data, nil
}
