package team

import (
	"context"
	"fmt"

	"github.com/tidbcloud/AgentTeam/internal/coredb"
	"github.com/tidbcloud/AgentTeam/internal/store/model"
)

func requireActiveWorkspaceMember(ctx context.Context, queryer coredb.QueryRower, workspaceID string, memberID string, wantType string) error {
	var memberType string
	if err := queryer.QueryRow(ctx, `
SELECT type
FROM members
WHERE workspace_id = $1 AND id = $2 AND status = 'active'
`, trim(workspaceID), trim(memberID)).Scan(&memberType); err != nil {
		if coredb.IsNotFound(err) {
			return notFound("workspace member not found")
		}
		return fmt.Errorf("load workspace member: %w", err)
	}
	memberType = trim(memberType)
	if expected := trim(wantType); expected != "" && memberType != expected {
		return badRequest("team member actor type does not match workspace member type")
	}
	return nil
}

func requireOwnedAgentWorkspaceMember(ctx context.Context, queryer coredb.QueryRower, workspaceID string, memberID string, userID string) error {
	if err := requireActiveWorkspaceMember(ctx, queryer, workspaceID, memberID, ActorKindAgent); err != nil {
		return err
	}

	var ownerUserID string
	if err := queryer.QueryRow(ctx, `
SELECT mac.created_by_user_id
FROM agents a
JOIN machines mac
  ON mac.workspace_id = a.workspace_id
 AND mac.id = a.machine_id
WHERE a.workspace_id = $1
  AND a.member_id = $2
  AND a.status <> 'archived'
  AND mac.status = 'active'
`, trim(workspaceID), trim(memberID)).Scan(&ownerUserID); err != nil {
		if coredb.IsNotFound(err) {
			return notFound("agent not found")
		}
		return fmt.Errorf("load team member agent owner: %w", err)
	}
	if trim(ownerUserID) != trim(userID) {
		return forbidden("only your own agents can be added to a team")
	}
	return nil
}

func validateUserAddedTeamMemberParams(ctx context.Context, queryer coredb.QueryRower, workspaceID string, userID string, members []AddTeamMemberParams) error {
	for _, member := range members {
		if err := validateUserAddedTeamActor(ctx, queryer, workspaceID, userID, member.ActorKind, member.ActorID); err != nil {
			return err
		}
	}
	return nil
}

func validateUserAddedTeamActor(ctx context.Context, queryer coredb.QueryRower, workspaceID string, userID string, actorKind string, actorID string) error {
	actorID = trim(actorID)
	if actorID == "" {
		return nil
	}
	if trim(actorKind) != ActorKindAgent {
		return badRequest("team members can only be added from your agents")
	}
	return requireOwnedAgentWorkspaceMember(ctx, queryer, workspaceID, actorID, userID)
}

func validateUserUpdatedTeamMemberParams(member model.WorkspaceTeamMember, params UpdateTeamMemberParams) error {
	if member.ActorKind == ActorKindAgent {
		return nil
	}
	if params.Role != nil || params.RoleLabel != nil || params.RoleOverlayPrompt != nil || params.WakeOnTeamMention != nil || params.SortOrder != nil {
		return badRequest("only agent team members can be edited")
	}
	return nil
}

func validateUserTeamTemplateMemberParams(ctx context.Context, queryer coredb.QueryRower, workspaceID string, userID string, members []CreateTeamTemplateMemberParams) error {
	for _, member := range members {
		if trim(member.ActorKind) != ActorKindAgent {
			return badRequest("team template members can only be your agents")
		}
		if trim(member.ActorID) == "" {
			continue
		}
		if err := validateUserAddedTeamActor(ctx, queryer, workspaceID, userID, member.ActorKind, member.ActorID); err != nil {
			return err
		}
	}
	return nil
}

func validateTeamActor(ctx context.Context, queryer coredb.Queryer, workspaceID string, currentTeamID string, actorKind string, actorID string) error {
	switch actorKind {
	case ActorKindAgent:
		return requireActiveWorkspaceMember(ctx, queryer, workspaceID, actorID, actorKind)
	default:
		return badRequest("team members can only be agents")
	}
}
