import { Resource } from "../resource.js";
import { logger } from "../util/logger.js";
import { SentryApi } from "./api.js";
/**
 * Create and manage Sentry teams
 *
 * @example
 * // Create a basic Sentry team:
 * const team = await Team("my-team", {
 *   name: "My Team",
 *   organization: "my-org"
 * });
 *
 * @example
 * // Create a team with a custom slug:
 * const team = await Team("custom-team", {
 *   name: "Custom Team",
 *   organization: "my-org",
 *   slug: "custom-team-slug"
 * });
 *
 * @example
 * // Create or adopt an existing team with the same slug:
 * const team = await Team("existing-team", {
 *   name: "Existing Team",
 *   organization: "my-org",
 *   adopt: true
 * });
 */
export const Team = Resource("sentry::Team", async function (id, props) {
    const api = new SentryApi({ authToken: props.authToken });
    // it's possible that `this.output.name` is undefined because a previous version
    // of alchemy had a bug where it didn't set the name on the output
    // so, we try to find the key by ID and use the name from the API response
    const lookupName = async () => {
        if (!this.output) {
            return undefined;
        }
        else if (this.output?.name) {
            return this.output.name;
        }
        const name = await getTeamName(api, props.organization, this.output.id);
        if (name) {
            this.output.name = name;
        }
        return name;
    };
    const teamName = props.name ?? (await lookupName()) ?? this.scope.createPhysicalName(id);
    if (this.phase === "update" && this.output.name !== teamName) {
        // TODO(sam): can we rename without destroying?
        // -> no: https://docs.sentry.io/api/teams/update-a-team/
        this.replace();
    }
    if (this.phase === "delete") {
        try {
            if (this.output?.id) {
                const response = await api.delete(`/teams/${props.organization}/${this.output.slug || this.output.id}/`);
                if (!response.ok && response.status !== 404) {
                    logger.error("Error deleting team:", response.statusText);
                }
            }
        }
        catch (error) {
            logger.error("Error deleting team:", error);
        }
        return this.destroy();
    }
    else {
        try {
            let response;
            if (this.phase === "update" && this.output?.id) {
                response = await api.put(`/teams/${props.organization}/${this.output.slug || this.output.id}/`, props);
            }
            else {
                try {
                    response = await api.post(`/organizations/${props.organization}/teams/`, props);
                }
                catch (error) {
                    // Check if this is a "team already exists" error and adopt is enabled
                    if ((props.adopt ?? this.scope.adopt) &&
                        error instanceof Error &&
                        error.message.includes("already exists")) {
                        logger.log(`Team '${props.slug || teamName}' already exists, adopting it`);
                        // Find the existing team by slug
                        const existingTeam = await findTeamBySlug(api, props.organization, props.slug || teamName);
                        if (!existingTeam) {
                            throw new Error(`Failed to find existing team '${props.slug || teamName}' for adoption`);
                        }
                        response = await api.get(`/organizations/${props.organization}/teams/${existingTeam.slug}/`);
                    }
                    else {
                        throw error;
                    }
                }
            }
            if (!response.ok) {
                throw new Error(`API error: ${response.statusText} ${await response.text()}`);
            }
            const data = (await response.json());
            return {
                ...props,
                id: data.id,
                name: teamName,
                dateCreated: data.dateCreated,
                isMember: data.isMember,
                teamRole: data.teamRole,
                flags: data.flags,
                access: data.access,
                hasAccess: data.hasAccess,
                isPending: data.isPending,
                memberCount: data.memberCount,
                avatar: data.avatar,
            };
        }
        catch (error) {
            logger.error("Error creating/updating team:", error);
            throw error;
        }
    }
});
/**
 * Find a team by slug
 */
async function findTeamBySlug(api, organization, slug) {
    const response = await api.get(`/teams/${organization}/${slug}/`);
    if (!response.ok) {
        throw new Error(`API error: ${response.statusText}`);
    }
    const teams = (await response.json());
    const team = teams.find((t) => t.slug === slug);
    return team ? { id: team.id, slug: team.slug } : null;
}
async function getTeamName(api, organization, slug) {
    const response = await api.get(`/teams/${organization}/${slug}/`);
    if (!response.ok) {
        throw new Error(`API error: ${response.statusText}`);
    }
    return (await response.json()).name;
}
//# sourceMappingURL=team.js.map