package store

import "testing"

func TestStateUpdateMemberRejectsLastActiveOwnerChange(t *testing.T) {
	state := NewSeededState("test")
	owner := findMemberByRole(t, state, "owner")

	nextRole := "member"
	if _, err := state.UpdateMember(owner.ID, UpdateMemberInput{Role: &nextRole}); err == nil {
		t.Fatalf("expected last active owner demotion to fail")
	}

	nextStatus := "removed"
	if _, err := state.UpdateMember(owner.ID, UpdateMemberInput{Status: &nextStatus}); err == nil {
		t.Fatalf("expected last active owner deactivation to fail")
	}
}

func TestStateUpdateMemberAllowsOwnerChangeWhenAnotherOwnerExists(t *testing.T) {
	state := NewSeededState("test")
	owner := findMemberByRole(t, state, "owner")

	state.Members = append(state.Members, Member{
		ID:            "member-owner-2",
		WorkspaceSlug: owner.WorkspaceSlug,
		Name:          "Backup Owner",
		Email:         "backup-owner@productier.app",
		Role:          "owner",
		Status:        "active",
	})

	nextRole := "admin"
	updated, err := state.UpdateMember(owner.ID, UpdateMemberInput{Role: &nextRole})
	if err != nil {
		t.Fatalf("expected owner demotion to succeed with another active owner: %v", err)
	}
	if updated.Role != "admin" {
		t.Fatalf("expected updated role admin, got %s", updated.Role)
	}
}

func TestStateRevokeInviteRules(t *testing.T) {
	state := NewSeededState("test")
	if len(state.Invites) == 0 {
		t.Fatalf("seed state has no invites")
	}
	invite := state.Invites[0]

	if err := state.RevokeInvite(invite.ID); err != nil {
		t.Fatalf("expected pending invite revoke to succeed: %v", err)
	}
	if _, err := state.GetInviteByID(invite.ID); err == nil {
		t.Fatalf("expected revoked invite to be absent")
	}
}

func TestStateRevokeInviteRejectedWhenAccepted(t *testing.T) {
	state := NewSeededState("test")
	if len(state.Invites) == 0 {
		t.Fatalf("seed state has no invites")
	}
	invite := state.Invites[0]

	if _, err := state.AcceptInvite(invite.Token, AcceptInviteInput{Name: "Taylor", Email: invite.Email}); err != nil {
		t.Fatalf("accept invite setup failed: %v", err)
	}
	if err := state.RevokeInvite(invite.ID); err == nil {
		t.Fatalf("expected revoke of accepted invite to fail")
	}
}

func findMemberByRole(t *testing.T, state *State, role string) Member {
	t.Helper()
	for _, member := range state.Members {
		if member.Role == role && member.Status == "active" {
			return member
		}
	}
	t.Fatalf("no active member with role %s", role)
	return Member{}
}
