package datamysql

import (
	"database/sql"

	"bitbucket.org/nemt/nemt-portal-api/domain/entity"
	"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)

type planRepo struct {
	conn executor
}

func newPlanRepo(conn executor) *planRepo {
	return &planRepo{
		conn: conn,
	}
}

func (c *planRepo) getQuery() string {
	const query = `SELECT 
										a.plan_id,
										a.plan_uuid,
										a.plan_name,
										a.plan_internal_id,
										a.plan_internal_status,
										a.plan_entity_id,
										a.entity_id,
										a.payer_id,
										a.payer_name,
										a.active,
										a.created,
										a.updated,
										b.plan_prefix_id,
										b.plan_prefix_uuid,
										b.alpha_prefix
								FROM
										tab_plan a
												INNER JOIN
										tab_plan_alpha_prefix b ON a.plan_id = b.plan_id	`

	return query
}

func (c *planRepo) parseSet(rows *sql.Rows, err error) ([]entity.Plan, error) {
	if err != nil {
		return nil, errors.Wrap(err)
	}
	result := make([]entity.Plan, 0)
	for rows.Next() {
		entity, err := c.parseEntity(rows)
		if err != nil {
			return nil, errors.Wrap(err)
		}
		result = append(result, entity)
	}
	return result, nil
}

func (c *planRepo) parseEntity(row scanner) (retVal entity.Plan, err error) {
	err = row.Scan(
		&retVal.ID, &retVal.UUID, &retVal.Name, &retVal.InternalID, &retVal.Status, &retVal.PlanEntityID, &retVal.EntityID, &retVal.PayerID, &retVal.PayerName,
		&retVal.Active, &retVal.Created, &retVal.Updated, &retVal.PrefixID, &retVal.PrefixUUID, &retVal.AlphaPrefix)

	return retVal, errors.Wrap(err)
}

func (c *planRepo) GetByAlphaPrefix(alphaPrefix string) (entity.Plan, error) {
	return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE b.alpha_prefix = ? ", alphaPrefix))
}

func (c *planRepo) GetByUUID(planUUID string) ([]entity.Plan, error) {
	return c.parseSet(c.conn.Query(c.getQuery()+" WHERE a.plan_uuid = ? ", planUUID))
}

func (c *planRepo) GetByID(planID int64) ([]entity.Plan, error) {
	return c.parseSet(c.conn.Query(c.getQuery()+" WHERE a.plan_id = ? ", planID))
}

func (c *planRepo) GetByPrefixUUID(prefixUUID string) (entity.Plan, error) {
	return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE b.plan_prefix_uuid = ? ", prefixUUID))
}
