package channeladmin

import (
	"context"
	"errors"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/store/agent"
	"github.com/tidbcloud/AgentTeam/internal/store/channel"
	"github.com/tidbcloud/AgentTeam/internal/store/plan"
	"github.com/tidbcloud/AgentTeam/internal/store/storeerr"
	"github.com/tidbcloud/AgentTeam/internal/store/workspace"
)

func TestMapCreateErrorKeepsCreateConflictsAndQuotaDistinct(t *testing.T) {
	unknown := errors.New("driver failed")
	cases := []struct {
		name string
		err  error
		want error
	}{
		{name: "slug conflict", err: channel.ChannelSlugConflictError{}, want: ErrSlugConflict},
		{name: "generic conflict", err: storeerr.Conflict("conflict"), want: ErrConflict},
		{name: "quota", err: plan.QuotaExceededError{Metric: plan.MetricChannels, Limit: 10}, want: ErrQuotaExceeded},
		{name: "bad request", err: storeerr.BadRequest("bad"), want: ErrValidation},
		{name: "not found", err: storeerr.NotFound("missing"), want: ErrNotFound},
		{name: "forbidden", err: storeerr.Forbidden("denied"), want: ErrForbidden},
		{name: "unknown", err: unknown, want: unknown},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			mapped := mapCreateError(tc.err)
			require.ErrorIs(t, mapped, tc.want)
			if tc.name == "slug conflict" {
				require.NotErrorIs(t, mapped, ErrVersionConflict)
			}
		})
	}
}

type errorOwnerResolver struct {
	userID string
	err    error
}

func (resolver errorOwnerResolver) AgentManagedByUser(context.Context, string, string) (string, error) {
	return resolver.userID, resolver.err
}

type errorWorkspaceResolver struct {
	err error
}

func (resolver errorWorkspaceResolver) GetWorkspaceForUser(context.Context, string, string) (workspace.Summary, error) {
	return workspace.Summary{}, resolver.err
}

func TestResolveOwnerMapsMissingAndOffboardedDependenciesToClosedError(t *testing.T) {
	agent := agent.AuthenticatedAgent{WorkspaceID: "ws", AgentID: "agt_1"}
	for _, tc := range []struct {
		name       string
		ownerError error
		ownerID    string
		memberErr  error
	}{
		{name: "owner not found", ownerError: storeerr.ErrNotFound},
		{name: "owner forbidden", ownerError: storeerr.ErrForbidden},
		{name: "workspace member not found", ownerID: "usr_1", memberErr: storeerr.ErrNotFound},
		{name: "workspace member offboarded", ownerID: "usr_1", memberErr: storeerr.ErrForbidden},
	} {
		t.Run(tc.name, func(t *testing.T) {
			service := New(Dependencies{
				Owners:     errorOwnerResolver{userID: tc.ownerID, err: tc.ownerError},
				Workspaces: errorWorkspaceResolver{err: tc.memberErr},
			})

			_, err := service.resolveOwner(context.Background(), agent)
			require.ErrorIs(t, err, ErrAgentOwnerMissing)
		})
	}
}
