package core

import (
	"database/sql"
	"errors"
	"fmt"

	_ "github.com/mattn/go-sqlite3"
)

func AddSource(db *DB, name string) error {
	_, err := db.Exec(`
		insert into sources (name)
		values (?)
	`, name)

	return err
}

func GetSources(db *DB) ([]string, error) {
	rows, err := db.Query(`
		select name
		from sources
	`)
	if err != nil {
		return nil, err
	}
	var names []string
	for rows.Next() {
		var name string
		if err = rows.Scan(&name); err != nil {
			return nil, err
		}
		names = append(names, name)
	}
	return names, nil
}

func DeleteSource(db *DB, name string) error {
	_, err := db.Exec(`
		delete from sources
		where name = ?
	`, name)

	return err
}

func AddItem(
	db *DB,
	source string,
	id string,
	title string,
	author string,
	body string,
	link string,
	time int,
) error {
	_, err := db.Exec(`
		insert into items (source, id, active, title, author, body, link, time)
		values (?, ?, ?, ?, ?, ?, ?, ?)
	`, source, id, true, title, author, body, link, time)

	return err
}

// Deactivate an item, returning its previous active state.
func DeactivateItem(db *DB, source string, id string) (bool, error) {
	row := db.QueryRow(`
		select active
		from items
		where source = ? and id = ?
	`, source, id)
	var active bool
	err := row.Scan(&active)
	if err != nil && errors.Is(err, sql.ErrNoRows) {
		return false, fmt.Errorf("item %s/%s not found", source, id)
	}

	_, err = db.Exec(`
		update items
		set active = 0
		where source = ? and id = ?
	`, source, id)
	if err != nil {
		return false, err
	}
	return active, nil
}

func GetAllActiveItems(db *DB) ([]Item, error) {
	rows, err := db.Query(`
		select
			source, id, created, active, title, author, body, link, time
		from items
		where active <> 0
	`)
	if err != nil {
		return nil, err
	}
	var items []Item
	for rows.Next() {
		var item Item
		err = rows.Scan(&item.Source, &item.Id, &item.Created, &item.Active, &item.Title, &item.Author, &item.Body, &item.Link, &item.Time)
		if err != nil {
			return nil, err
		}
		items = append(items, item)
	}
	return items, nil
}

func GetActiveItemsForSource(db *DB, source string) ([]Item, error) {
	rows, err := db.Query(`
		select
			source, id, created, active, title, author, body, link, time
		from items
		where
			source = ?
		and active <> 0
	`, source)
	if err != nil {
		return nil, err
	}
	var items []Item
	for rows.Next() {
		var item Item
		err = rows.Scan(&item.Source, &item.Id, &item.Created, &item.Active, &item.Title, &item.Author, &item.Body, &item.Link, &item.Time)
		if err != nil {
			return nil, err
		}
		items = append(items, item)
	}
	return items, nil
}