import { AboutLogResponse, InfoRequest, JsonRedditObjects, JsonStatus, Listing, } from '@devvit/protos';
import { Empty } from '@devvit/protos/types/google/protobuf/empty.js';
import { StringValue } from '@devvit/protos/types/google/protobuf/wrappers.js';
import { Header } from '@devvit/shared-types/Header.js';
import { assertNonNull } from '@devvit/shared-types/NonNull.js';
import { RedditAPI } from './RedditAPI.js';
export class Moderation extends RedditAPI {
    async _getSubredditNameFromMetadata(metadata) {
        const appSubredditId = metadata?.[Header.Subreddit]?.values?.[0];
        assertNonNull(appSubredditId, 'No Subreddit ID in Metadata');
        const appSubredditResponse = await this._info(InfoRequest.fromJSON({ thingIds: [appSubredditId] }), metadata);
        const subredditName = appSubredditResponse.data?.children[0]?.data?.displayName;
        assertNonNull(subredditName, 'Subreddit not found');
        return subredditName;
    }
    async _info(request, metadata) {
        const response = await this._fetch('Info', request, metadata);
        return Listing.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async validateSubreddit(subreddit, metadata) {
        assertNonNull(subreddit, 'subreddit value cannot be undefined');
        const subredditName = await this._getSubredditNameFromMetadata(metadata);
        if (subreddit.toLocaleLowerCase() !== subredditName.toLocaleLowerCase()) {
            throw new Error(`this action is only allowed inside the current subreddit: r/${subredditName}`);
        }
        return true;
    }
    async validateContent(id, metadata) {
        const listing = await this._info(InfoRequest.fromJSON({ thingIds: [id] }), metadata);
        const subredditId = listing.data?.children[0]?.data?.subredditId;
        if (!subredditId) {
            throw new Error(`could not determine parent subreddit of content with ID: ${id}`);
        }
        const validSubredditId = metadata?.[Header.Subreddit]?.values?.[0];
        assertNonNull(validSubredditId, 'No Subreddit ID in Metadata');
        if (validSubredditId.toLocaleLowerCase() !== subredditId.toLocaleLowerCase()) {
            throw new Error(`this action is only allowed inside the current subreddit: ${validSubredditId}`);
        }
        return true;
    }
    async AboutLog(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('AboutLog', request, metadata);
        return AboutLogResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async AboutLocation(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('AboutLocation', request, metadata);
        return Listing.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async AboutReports(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('AboutReports', request, metadata);
        return Listing.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async AboutSpam(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('AboutSpam', request, metadata);
        return Listing.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async AboutModqueue(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('AboutModqueue', request, metadata);
        return Listing.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async AboutUnmoderated(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('AboutUnmoderated', request, metadata);
        return Listing.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async AboutEdited(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('AboutEdited', request, metadata);
        return Listing.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async AcceptModeratorInvite(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('AcceptModeratorInvite', request, metadata);
        return JsonStatus.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async Approve(request, metadata) {
        await this.validateContent(request.id, metadata);
        await this._fetch('Approve', request, metadata);
        return Empty.fromPartial({});
    }
    async Distinguish(request, metadata) {
        await this.validateContent(request.id, metadata);
        const response = await this._fetch('Distinguish', request, metadata);
        return JsonRedditObjects.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async IgnoreReports(request, metadata) {
        await this.validateContent(request.id, metadata);
        await this._fetch('IgnoreReports', request, metadata);
        return Empty.fromPartial({});
    }
    async LeaveContributor(request, metadata) {
        await this._fetch('LeaveContributor', request, metadata);
        return Empty.fromPartial({});
    }
    async LeaveModerator(request, metadata) {
        await this._fetch('LeaveModerator', request, metadata);
        return Empty.fromPartial({});
    }
    async MuteMessageAuthor(request, metadata) {
        await this._fetch('MuteMessageAuthor', request, metadata);
        return Empty.fromPartial({});
    }
    async Remove(request, metadata) {
        await this.validateContent(request.id, metadata);
        await this._fetch('Remove', request, metadata);
        return Empty.fromPartial({});
    }
    async ShowComment(request, metadata) {
        await this.validateContent(request.id, metadata);
        await this._fetch('ShowComment', request, metadata);
        return Empty.fromPartial({});
    }
    async SnoozeReports(request, metadata) {
        await this.validateContent(request.id, metadata);
        await this._fetch('SnoozeReports', request, metadata);
        return Empty.fromPartial({});
    }
    async UnignoreReports(request, metadata) {
        await this.validateContent(request.id, metadata);
        await this._fetch('UnignoreReports', request, metadata);
        return Empty.fromPartial({});
    }
    async UnmuteMessageAuthor(request, metadata) {
        await this._fetch('UnmuteMessageAuthor', request, metadata);
        return Empty.fromPartial({});
    }
    async UnsnoozeReports(request, metadata) {
        await this.validateContent(request.id, metadata);
        await this._fetch('UnsnoozeReports', request, metadata);
        return Empty.fromPartial({});
    }
    async UpdateCrowdControlLevel(request, metadata) {
        await this.validateContent(request.id, metadata);
        await this._fetch('UpdateCrowdControlLevel', request, metadata);
        return Empty.fromPartial({});
    }
    async Stylesheet(request, metadata) {
        await this.validateSubreddit(request.subreddit, metadata);
        const response = await this._fetch('UpdateCrowdControlLevel', request, metadata);
        return StringValue.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
}
