package teams_repo

import (
	"context"
	"errors"
	"evening_detective_server/internal/repos"

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

var (
	ErrTeamNotFound = errors.New("Команда не найдена")
)

type TeamsRepo struct {
	pool *pgxpool.Pool
}

func NewTeamsRepo(pool *pgxpool.Pool) *TeamsRepo {
	return &TeamsRepo{
		pool: pool,
	}
}

func (r *TeamsRepo) GetTeamByID(ctx context.Context, id int) (*repos.Team, error) {
	team := &repos.Team{}
	row := r.pool.QueryRow(
		ctx,
		`SELECT 
			id, 
			name, 
			status,
			password,
			game_id
		FROM teams
		WHERE id = $1`,
		id,
	)
	err := row.Scan(
		&team.ID,
		&team.Name,
		&team.Status,
		&team.Password,
		&team.GameId,
	)
	if err != nil {
		if errors.Is(err, pgx.ErrNoRows) {
			return nil, ErrTeamNotFound
		}
		return nil, err
	}

	return team, nil
}

func (r *TeamsRepo) GetTeamsByGameID(
	ctx context.Context,
	gameId int,
) ([]*repos.Team, error) {
	rows, err := r.pool.Query(
		ctx,
		`SELECT 
			id, 
			name, 
			status,
			password
		FROM teams
		WHERE game_id = $1
		ORDER BY created_at DESC`,
		gameId,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var teams []*repos.Team
	for rows.Next() {
		team := &repos.Team{}
		err := rows.Scan(
			&team.ID,
			&team.Name,
			&team.Status,
			&team.Password,
		)
		if err != nil {
			return nil, err
		}
		teams = append(teams, team)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}

	return teams, nil
}

func (r *TeamsRepo) AddTeam(
	ctx context.Context,
	creatorId int,
	gameId int,
	name string,
	password string,
) (int, error) {
	id := 0
	err := r.pool.QueryRow(
		ctx,
		`INSERT INTO teams (name, creator_id, game_id, password)
		VALUES ($1, $2, $3, $4)
		RETURNING id`,
		name,
		creatorId,
		gameId,
		password,
	).Scan(&id)

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

func (r *TeamsRepo) UpdateTeam(ctx context.Context, teamId int, name string) error {
	tag, err := r.pool.Exec(
		ctx,
		`UPDATE teams
		SET 
			name = $1
		WHERE id = $2`,
		name,
		teamId,
	)
	if err != nil {
		return err
	}
	if tag.RowsAffected() == 0 {
		return ErrTeamNotFound
	}
	return nil
}

func (r *TeamsRepo) DeleteTeam(ctx context.Context, teamId int) error {
	tag, err := r.pool.Exec(
		ctx,
		`DELETE FROM teams
		WHERE id = $1`,
		teamId,
	)
	if err != nil {
		return err
	}
	if tag.RowsAffected() == 0 {
		return ErrTeamNotFound
	}
	return nil
}
