package platform

import (
	"context"
	"fmt"
	"time"

	"source.gleipnir.technology/Gleipnir/nidus-sync/db"
	modelcomms "source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/comms/model"
	querycomms "source.gleipnir.technology/Gleipnir/nidus-sync/db/query/comms"
	"source.gleipnir.technology/Gleipnir/nidus-sync/platform/types"
)

func ContactsForOrganization(ctx context.Context, org_id int32) (results []types.Contact, err error) {
	txn := db.PGInstance.PGXPool
	rows, err := querycomms.ContactsFromOrganizationID(ctx, txn, int64(org_id))
	if err != nil {
		return results, fmt.Errorf("contacts from organization id: %w", err)
	}
	contact_ids := make([]int64, len(rows))
	for i, row := range rows {
		contact_ids[i] = int64(row.ID)
	}
	contact_emails_by_contact_id, err := querycomms.ContactEmailByContactIDs(ctx, txn, contact_ids)
	if err != nil {
		return results, fmt.Errorf("by contact ids: %w", err)
	}
	contact_phones_by_contact_id, err := querycomms.ContactPhoneByContactIDs(ctx, txn, contact_ids)
	if err != nil {
		return results, fmt.Errorf("by contact ids: %w", err)
	}
	e164s := make([]string, 0)
	for _, v := range contact_phones_by_contact_id {
		for _, p := range v {
			e164s = append(e164s, p.E164)
		}
	}
	phones, err := querycomms.PhonesFromE164s(ctx, txn, e164s)
	if err != nil {
		return results, fmt.Errorf("phones from e164: %w", err)
	}
	phones_by_e164 := make(map[string]modelcomms.Phone, len(phones))
	for _, p := range phones {
		phones_by_e164[p.E164] = p
	}
	results = make([]types.Contact, 0)
	for _, row := range rows {
		// Exclude the magic Nidus contact
		if row.ID == 1 {
			continue
		}
		contact_emails := contact_emails_by_contact_id[int64(row.ID)]
		emails := make([]string, len(contact_emails))
		for i, e := range contact_emails {
			emails[i] = e.Address
		}
		contact_phones := contact_phones_by_contact_id[int64(row.ID)]
		phones := make([]types.Phone, len(contact_phones))
		for i, p := range contact_phones {
			phone := phones_by_e164[p.E164]
			status := "unconfirmed"
			if phone.StopMessageID != nil {
				status = "stopped"
			} else if phone.ConfirmedMessageID != nil {
				status = "confirmed"
			}
			phones[i] = types.Phone{
				CanSMS: phone.CanSms,
				E164:   phone.E164,
				Status: status,
			}
		}
		if row.Name != "" || len(contact_phones) > 0 || len(contact_emails) > 0 {
			results = append(results, types.Contact{
				Emails: emails,
				ID:     row.ID,
				Name:   row.Name,
				Phones: phones,
			})
		}
	}
	return results, nil
}
func ContactEmptyForOrganization(ctx context.Context, txn db.Ex, org_id int32) (modelcomms.Contact, error) {
	contact, err := querycomms.ContactEmptyForOrganization(ctx, txn, int64(org_id))
	if err != nil {
		return modelcomms.Contact{}, fmt.Errorf("querycomms: %w", err)
	}
	if contact != nil {
		return *contact, nil
	}
	return querycomms.ContactInsert(ctx, txn, modelcomms.Contact{
		Created:        time.Now(),
		Name:           "",
		OrganizationID: org_id,
	})
}
