package actions_repo

import (
	"context"
	"errors"

	"github.com/jackc/pgx/v5/pgxpool"
)

var (
	ErrActionsNotFound = errors.New("Ход не найден")
)

type ActionsRepo struct {
	pool *pgxpool.Pool
}

func NewActionsRepo(pool *pgxpool.Pool) *ActionsRepo {
	return &ActionsRepo{
		pool: pool,
	}
}

func (r *ActionsRepo) AddAction(ctx context.Context, teamId int, code string) (int, error) {
	id := 0
	err := r.pool.QueryRow(
		ctx,
		`INSERT INTO actions (code, team_id)
		VALUES ($1, $2)
		RETURNING id`,
		code,
		teamId,
	).Scan(&id)

	if err != nil {
		return 0, err
	}
	return id, nil
}

func (r *ActionsRepo) GetActionsByTeamID(ctx context.Context, teamId int) ([]string, error) {
	rows, err := r.pool.Query(
		ctx,
		`SELECT 
			code
		FROM actions
		WHERE team_id = $1
		ORDER BY created_at ASC`,
		teamId,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var codes []string
	for rows.Next() {
		code := ""
		err := rows.Scan(
			&code,
		)
		if err != nil {
			return nil, err
		}
		codes = append(codes, code)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}

	return codes, nil
}

func (r *ActionsRepo) GetActionsCountByTeamIDs(ctx context.Context, teamIds []int) (map[int]int, error) {
	rows, err := r.pool.Query(
		ctx,
		`SELECT 
			team_id, 
			count(*)
		FROM actions
		WHERE team_id = ANY($1)
		GROUP BY team_id`,
		teamIds,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	res := make(map[int]int, len(teamIds))
	for rows.Next() {
		id := 0
		count := 0
		err := rows.Scan(
			&id,
			&count,
		)
		if err != nil {
			return nil, err
		}
		res[id] = count
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}

	return res, nil
}

func (r *ActionsRepo) DeleteLastActionByTeamId(ctx context.Context, teamId int) error {
	tag, err := r.pool.Exec(
		ctx,
		`DELETE FROM actions
		WHERE id IN (
			SELECT id 
			FROM actions 
			WHERE team_id = $1
			ORDER BY created_at DESC 
			LIMIT 1
		)`,
		teamId,
	)
	if err != nil {
		return err
	}
	if tag.RowsAffected() == 0 {
		return ErrActionsNotFound
	}
	return nil
}
