package data

import (
	"errors"
	"time"
	"database/sql"

	"party.at/party/internal/validator"
)

type Option struct {
	ID      int64     `json:"id"`
    IssueID int64     `json:"issue_id"`
    Label   string    `json:"label"`
    Created time.Time `json:"created"`
    Version int       `json:"version"`
}

func ValidateOption(v *validator.Validator, option *Option) {
	v.Check(option.Label != "", "options", "option labels must not be empty")
}

type OptionModel struct {
	DB *sql.DB
}

func (m OptionModel) Insert(option *Option) error {
	query := `
INSERT INTO options (issue_id, label)
VALUES ($1, $2)
RETURNING id, created, version`

	args := []interface{}{
		option.IssueID,
		option.Label,
	}

	return m.DB.QueryRow(query, args...).Scan(
		&option.ID,
		&option.Created,
		&option.Version,
	)
}

func (m OptionModel) GetAllForIssue(issueID int64) ([]*Option, error) {
	query := `
SELECT id, issue_id, label, created, version
FROM options
WHERE issue_id = $1
ORDER BY id`

	rows, err := m.DB.Query(query, issueID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var options []*Option
	for rows.Next() {
		var option Option
		err := rows.Scan(&option.ID, &option.IssueID, &option.Label, &option.Created, &option.Version)
		if err != nil {
			return nil, err
		}
		options = append(options, &option)
	}
	return options, rows.Err()
}

func (m OptionModel) Get(id int64) (*Option, error) {
	if id < 1 {
		return nil, ErrRecordNotFound
	}

	query := `
SELECT id, issue_id, label, created, version
FROM options
WHERE id = $1`

	var option Option

	err := m.DB.QueryRow(query, id).Scan(
		&option.ID,
		&option.IssueID,
		&option.Label,
		&option.Created,
		&option.Version,
	)

	if err != nil {
		switch {
		case errors.Is(err, sql.ErrNoRows):
			return nil, ErrRecordNotFound
		default:
			return nil, err
		}
	}

	return &option, nil
}
