package comms

import (
	"context"

	"github.com/Gleipnir-Technology/jet/postgres"
	"source.gleipnir.technology/Gleipnir/nidus-sync/db"
	"source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/comms/model"
	"source.gleipnir.technology/Gleipnir/nidus-sync/db/gen/nidus-sync/comms/table"
)

func PhoneInsertIfNotExists(ctx context.Context, txn db.Ex, m model.Phone) (model.Phone, error) {
	inserted := postgres.CTE("inserted")
	insert := table.Phone.INSERT(
		table.Phone.AllColumns,
	).MODEL(m).
		ON_CONFLICT(table.Phone.E164).DO_NOTHING().
		RETURNING(table.Phone.AllColumns)

	statement := postgres.WITH(inserted.AS(insert))(
		postgres.SELECT(inserted.AllColumns()).
			FROM(inserted).
			UNION_ALL(
				postgres.SELECT(table.Phone.AllColumns).
					FROM(table.Phone).
					WHERE(postgres.AND(
						table.Phone.E164.EQ(postgres.String(m.E164)),
						postgres.NOT(postgres.EXISTS(
							postgres.SELECT(postgres.STAR).FROM(inserted),
						)),
					)),
			),
	)
	return db.ExecuteOneTx[model.Phone](ctx, txn, statement)
}
func PhoneFromE164(ctx context.Context, txn db.Ex, e164 string) (model.Phone, error) {
	statement := table.Phone.SELECT(
		table.Phone.AllColumns,
	).FROM(table.Phone).
		WHERE(table.Phone.E164.EQ(postgres.String(e164)))
	return db.ExecuteOneTx[model.Phone](ctx, txn, statement)
}
func PhonesFromE164s(ctx context.Context, txn db.Ex, e164s []string) ([]model.Phone, error) {
	if len(e164s) == 0 {
		return []model.Phone{}, nil
	}
	sql_ids := make([]postgres.Expression, len(e164s))
	for i, e164 := range e164s {
		sql_ids[i] = postgres.String(e164)
	}
	statement := table.Phone.SELECT(
		table.Phone.AllColumns,
	).FROM(table.Phone).
		WHERE(table.Phone.E164.IN(sql_ids...))
	return db.ExecuteManyTx[model.Phone](ctx, txn, statement)
}
func PhoneUpdateConfirmedMessageID(ctx context.Context, txn db.Ex, e164 string, message_id *int32) error {
	statement := table.Phone.UPDATE().
		SET(table.Phone.ConfirmedMessageID.SET(postgres.IntExp(postgres.NULL))).
		WHERE(table.Phone.E164.EQ(postgres.String(e164)))
	return db.ExecuteNoneTx(ctx, txn, statement)
}
func PhoneUpdateStopMessageID(ctx context.Context, txn db.Ex, e164 string, message_id *int32) error {
	/*
		m := model.Phone{}
		m.StopMessageID = message_id
		statement := table.Phone.UPDATE(
			table.Phone.StopMessageID,
		).MODEL(m).
			WHERE(table.Phone.E164.EQ(postgres.String(e164)))
	*/
	statement := table.Phone.UPDATE().
		SET(table.Phone.StopMessageID.SET(postgres.IntExp(postgres.NULL))).
		WHERE(table.Phone.E164.EQ(postgres.String(e164)))
	return db.ExecuteNoneTx(ctx, txn, statement)
}
