package queries

import (
	"fmt"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/validator"

	"github.com/go-pg/pg/v10/orm"
	"github.com/pkg/errors"
)

type IssuesInterface interface {
	Insert(issue *common.Issue) (orm.Result, error)
	Delete(id int) (orm.Result, error)
	SelectByID(id int) (*common.Issue, error)
	Search(filter *common.IssueSearch, paging *PageQueryOptions) ([]common.Issue, error)
	Count() (int, error)
}

type Issues struct {
	QueryBase
}

func (c *Issues) load(query *orm.Query) error {
	err := query.Relation("IssueImages").Select()
	return errors.WithStack(err)
}

func (c *Issues) Insert(issue *common.Issue) (orm.Result, error) {
	return c.insert(issue)
}

func (c *Issues) Search(filter *common.IssueSearch, paging *PageQueryOptions) ([]common.Issue, error) {
	issues := []common.Issue{}
	query := c.GetDBConn().Model(&issues)

	c.searchFilter(query, filter)
	c.pageQuery(query, paging)

	err := query.Select()

	return issues, errors.WithStack(err)
}

func (c *Issues) SelectByID(id int) (*common.Issue, error) {

	if id <= 0 {
		return nil, &validator.FieldError{
			ErrorMsg: "id cannot be less than 0",
		}
	}
	issue := common.Issue{}
	query := c.GetDBConn().Model(&issue)

	query.Where("issue.id = ?", id)
	err := c.load(query)

	return &issue, err
}

func (c *Issues) Delete(id int) (orm.Result, error) {

	if id <= 0 {
		return nil, &validator.FieldError{
			ErrorMsg: "id has to be a positive integer",
		}
	}

	total := ORMResults{}
	issueImage := common.IssueImage{}
	issueImagesQuery := c.GetDBConn().Model(&issueImage)
	res, err := issueImagesQuery.Where("issue_id = ?", id).Delete()
	if err != nil {
		return nil, errors.WithStack(err)
	}
	total.AddResult(res)

	issue := common.Issue{}
	query := c.GetDBConn().Model(&issue)
	res, err = query.Where("issue.id = ?", id).Delete()
	if err != nil {
		return nil, errors.WithStack(err)
	}
	total.AddResult(res)

	return &total, nil

}

func (c *Issues) Count() (int, error) {
	issue := common.Issue{}
	query := c.GetDBConn().Model(&issue)
	return c.countWithStack(query.Count())
}

func (c *Issues) searchFilter(query *orm.Query, filter *common.IssueSearch) {
	if filter.Search != "" {
		query.Where("vin ILIKE ? OR title ILIKE ? OR driver_id ILIKE ?", fmt.Sprintf("%%%s%%", filter.Search), fmt.Sprintf("%%%s%%", filter.Search), fmt.Sprintf("%%%s%%", filter.Search))
	}
}
