package eventstream

import (
	"database/sql"
	"encoding/json"
	"time"

	"tangled.org/core/notifier"
	"tangled.org/core/tid"
)

type Store interface {
	Exec(query string, args ...any) (sql.Result, error)
	Query(query string, args ...any) (*sql.Rows, error)
}

func Insert(s Store, ev Event, n *notifier.Notifier) error {
	if ev.Tid == "" {
		ev.Tid = tid.TID()
	}
	if ev.Created == 0 {
		ev.Created = time.Now().UnixNano()
	}
	if _, err := s.Exec(
		`insert into events (tid, rkey, nsid, event, created) values (?, ?, ?, ?, ?)`,
		ev.Tid,
		ev.Rkey,
		ev.Nsid,
		[]byte(ev.EventJson),
		ev.Created,
	); err != nil {
		return err
	}
	n.NotifyAll()
	return nil
}

func List(s Store, cursorTid string, limit int) ([]Event, error) {
	rows, err := s.Query(`
		select tid, rkey, nsid, event, created
		from events
		where tid > ?
		order by tid asc
		limit ?
	`, cursorTid, limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var out []Event
	for rows.Next() {
		var ev Event
		var eventJsonStr string
		if err := rows.Scan(&ev.Tid, &ev.Rkey, &ev.Nsid, &eventJsonStr, &ev.Created); err != nil {
			return nil, err
		}
		ev.EventJson = json.RawMessage(eventJsonStr)
		out = append(out, ev)
	}

	if err := rows.Err(); err != nil {
		return nil, err
	}

	return out, nil
}
