package store

// import (
// 	"context"
// 	"fmt"
// 	"strings"
// 	"time"

// 	"github.com/google/uuid"

// 	"git.warky.dev/wdevs/amcs/internal/generatedmodels"
// 	ext "git.warky.dev/wdevs/amcs/internal/types"
// )

// func (db *DB) AddProfessionalContact(ctx context.Context, c ext.ProfessionalContact) (ext.ProfessionalContact, error) {
// 	if c.Tags == nil {
// 		c.Tags = []string{}
// 	}

// 	row := db.pool.QueryRow(ctx, `
// 		insert into professional_contacts (name, company, title, email, phone, linkedin_url, how_we_met, tags, notes, follow_up_date)
// 		values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
// 		returning id, created_at, updated_at
// 	`, c.Name, nullStr(c.Company), nullStr(c.Title), nullStr(c.Email), nullStr(c.Phone),
// 		nullStr(c.LinkedInURL), nullStr(c.HowWeMet), c.Tags, nullStr(c.Notes), c.FollowUpDate)

// 	created := c
// 	var model generatedmodels.ModelPublicProfessionalContacts
// 	if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
// 		return ext.ProfessionalContact{}, fmt.Errorf("insert contact: %w", err)
// 	}
// 	created.ID = model.ID.UUID()
// 	created.CreatedAt = model.CreatedAt.Time()
// 	created.UpdatedAt = model.UpdatedAt.Time()
// 	return created, nil
// }

// func (db *DB) SearchContacts(ctx context.Context, query string, tags []string) ([]ext.ProfessionalContact, error) {
// 	args := []any{}
// 	conditions := []string{}

// 	if q := strings.TrimSpace(query); q != "" {
// 		args = append(args, "%"+q+"%")
// 		idx := len(args)
// 		conditions = append(conditions, fmt.Sprintf(
// 			"(name ILIKE $%[1]d OR company ILIKE $%[1]d OR title ILIKE $%[1]d OR notes ILIKE $%[1]d)", idx))
// 	}
// 	if len(tags) > 0 {
// 		args = append(args, tags)
// 		conditions = append(conditions, fmt.Sprintf("tags @> $%d", len(args)))
// 	}

// 	q := `select id, name, company, title, email, phone, linkedin_url, how_we_met, tags::text[], notes, last_contacted, follow_up_date, created_at, updated_at from professional_contacts`
// 	if len(conditions) > 0 {
// 		q += " where " + strings.Join(conditions, " and ")
// 	}
// 	q += " order by name"

// 	rows, err := db.pool.Query(ctx, q, args...)
// 	if err != nil {
// 		return nil, fmt.Errorf("search contacts: %w", err)
// 	}
// 	defer rows.Close()

// 	return scanContacts(rows)
// }

// func (db *DB) GetContact(ctx context.Context, id uuid.UUID) (ext.ProfessionalContact, error) {
// 	row := db.pool.QueryRow(ctx, `
// 		select id, name, company, title, email, phone, linkedin_url, how_we_met, tags::text[], notes, last_contacted, follow_up_date, created_at, updated_at
// 		from professional_contacts where id = $1
// 	`, id)

// 	var model generatedmodels.ModelPublicProfessionalContacts
// 	var tags []string
// 	if err := row.Scan(&model.ID, &model.Name, &model.Company, &model.Title, &model.Email, &model.Phone,
// 		&model.LinkedinURL, &model.HowWeMet, &tags, &model.Notes, &model.LastContacted, &model.FollowUpDate,
// 		&model.CreatedAt, &model.UpdatedAt); err != nil {
// 		return ext.ProfessionalContact{}, fmt.Errorf("get contact: %w", err)
// 	}
// 	c := professionalContactFromModel(model, tags)
// 	return c, nil
// }

// func (db *DB) LogInteraction(ctx context.Context, interaction ext.ContactInteraction) (ext.ContactInteraction, error) {
// 	occurredAt := interaction.OccurredAt
// 	if occurredAt.IsZero() {
// 		occurredAt = time.Now()
// 	}

// 	row := db.pool.QueryRow(ctx, `
// 		insert into contact_interactions (contact_id, interaction_type, occurred_at, summary, follow_up_needed, follow_up_notes)
// 		values ($1, $2, $3, $4, $5, $6)
// 		returning id, created_at
// 	`, interaction.ContactID, interaction.InteractionType, occurredAt, interaction.Summary,
// 		interaction.FollowUpNeeded, nullStr(interaction.FollowUpNotes))

// 	created := interaction
// 	created.OccurredAt = occurredAt
// 	var model generatedmodels.ModelPublicContactInteractions
// 	if err := row.Scan(&model.ID, &model.CreatedAt); err != nil {
// 		return ext.ContactInteraction{}, fmt.Errorf("insert interaction: %w", err)
// 	}
// 	created.ID = model.ID.UUID()
// 	created.CreatedAt = model.CreatedAt.Time()
// 	return created, nil
// }

// func (db *DB) GetContactHistory(ctx context.Context, contactID uuid.UUID) (ext.ContactHistory, error) {
// 	contact, err := db.GetContact(ctx, contactID)
// 	if err != nil {
// 		return ext.ContactHistory{}, err
// 	}

// 	rows, err := db.pool.Query(ctx, `
// 		select id, contact_id, interaction_type, occurred_at, summary, follow_up_needed, follow_up_notes, created_at
// 		from contact_interactions where contact_id = $1 order by occurred_at desc
// 	`, contactID)
// 	if err != nil {
// 		return ext.ContactHistory{}, fmt.Errorf("get interactions: %w", err)
// 	}
// 	defer rows.Close()

// 	var interactions []ext.ContactInteraction
// 	for rows.Next() {
// 		var model generatedmodels.ModelPublicContactInteractions
// 		if err := rows.Scan(&model.ID, &model.ContactID, &model.InteractionType, &model.OccurredAt, &model.Summary,
// 			&model.FollowUpNeeded, &model.FollowUpNotes, &model.CreatedAt); err != nil {
// 			return ext.ContactHistory{}, fmt.Errorf("scan interaction: %w", err)
// 		}
// 		interactions = append(interactions, contactInteractionFromModel(model))
// 	}
// 	if err := rows.Err(); err != nil {
// 		return ext.ContactHistory{}, err
// 	}

// 	oppRows, err := db.pool.Query(ctx, `
// 		select id, contact_id, title, description, stage, value, expected_close_date, notes, created_at, updated_at
// 		from opportunities where contact_id = $1 order by created_at desc
// 	`, contactID)
// 	if err != nil {
// 		return ext.ContactHistory{}, fmt.Errorf("get opportunities: %w", err)
// 	}
// 	defer oppRows.Close()

// 	var opportunities []ext.Opportunity
// 	for oppRows.Next() {
// 		var model generatedmodels.ModelPublicOpportunities
// 		if err := oppRows.Scan(&model.ID, &model.ContactID, &model.Title, &model.Description, &model.Stage, &model.Value,
// 			&model.ExpectedCloseDate, &model.Notes, &model.CreatedAt, &model.UpdatedAt); err != nil {
// 			return ext.ContactHistory{}, fmt.Errorf("scan opportunity: %w", err)
// 		}
// 		opportunities = append(opportunities, opportunityFromModel(model))
// 	}
// 	if err := oppRows.Err(); err != nil {
// 		return ext.ContactHistory{}, err
// 	}

// 	return ext.ContactHistory{
// 		Contact:       contact,
// 		Interactions:  interactions,
// 		Opportunities: opportunities,
// 	}, nil
// }

// func (db *DB) CreateOpportunity(ctx context.Context, o ext.Opportunity) (ext.Opportunity, error) {
// 	row := db.pool.QueryRow(ctx, `
// 		insert into opportunities (contact_id, title, description, stage, value, expected_close_date, notes)
// 		values ($1, $2, $3, $4, $5, $6, $7)
// 		returning id, created_at, updated_at
// 	`, o.ContactID, o.Title, nullStr(o.Description), o.Stage, o.Value, o.ExpectedCloseDate, nullStr(o.Notes))

// 	created := o
// 	var model generatedmodels.ModelPublicOpportunities
// 	if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
// 		return ext.Opportunity{}, fmt.Errorf("insert opportunity: %w", err)
// 	}
// 	created.ID = model.ID.UUID()
// 	created.CreatedAt = model.CreatedAt.Time()
// 	created.UpdatedAt = model.UpdatedAt.Time()
// 	return created, nil
// }

// func (db *DB) GetFollowUpsDue(ctx context.Context, daysAhead int) ([]ext.ProfessionalContact, error) {
// 	if daysAhead <= 0 {
// 		daysAhead = 7
// 	}
// 	cutoff := time.Now().AddDate(0, 0, daysAhead)

// 	rows, err := db.pool.Query(ctx, `
// 		select id, name, company, title, email, phone, linkedin_url, how_we_met, tags::text[], notes, last_contacted, follow_up_date, created_at, updated_at
// 		from professional_contacts
// 		where follow_up_date <= $1
// 		order by follow_up_date asc
// 	`, cutoff)
// 	if err != nil {
// 		return nil, fmt.Errorf("get follow-ups: %w", err)
// 	}
// 	defer rows.Close()

// 	return scanContacts(rows)
// }

// func (db *DB) AppendThoughtToContactNotes(ctx context.Context, contactID uuid.UUID, thoughtContent string) error {
// 	_, err := db.pool.Exec(ctx, `
// 		update professional_contacts
// 		set notes = coalesce(notes, '') || $2
// 		where id = $1
// 	`, contactID, thoughtContent)
// 	if err != nil {
// 		return fmt.Errorf("append thought to contact: %w", err)
// 	}
// 	return nil
// }

// func scanContacts(rows interface {
// 	Next() bool
// 	Scan(...any) error
// 	Err() error
// 	Close()
// }) ([]ext.ProfessionalContact, error) {
// 	defer rows.Close()
// 	var contacts []ext.ProfessionalContact
// 	for rows.Next() {
// 		var model generatedmodels.ModelPublicProfessionalContacts
// 		var tags []string
// 		if err := rows.Scan(&model.ID, &model.Name, &model.Company, &model.Title, &model.Email, &model.Phone,
// 			&model.LinkedinURL, &model.HowWeMet, &tags, &model.Notes, &model.LastContacted, &model.FollowUpDate,
// 			&model.CreatedAt, &model.UpdatedAt); err != nil {
// 			return nil, fmt.Errorf("scan contact: %w", err)
// 		}
// 		contacts = append(contacts, professionalContactFromModel(model, tags))
// 	}
// 	return contacts, rows.Err()
// }
