// SPDX-License-Identifier: AGPL-3.0-or-later

import type {ListGuildAuditLogsRequest} from '@fluxer/schema/src/domains/admin/AdminGuildSchemas';
import {createGuildID, createUserID} from '../../BrandedTypes';
import type {IChannelRepository} from '../../channel/IChannelRepository';
import type {IGuildDiscoveryRepository} from '../../guild/repositories/GuildDiscoveryRepository';
import type {IGuildRepositoryAggregate} from '../../guild/repositories/IGuildRepositoryAggregate';
import type {GuildService} from '../../guild/services/GuildService';
import type {EntityAssetService} from '../../infrastructure/EntityAssetService';
import type {IGatewayService} from '../../infrastructure/IGatewayService';
import type {InviteRepository} from '../../invite/InviteRepository';
import {createRequestCache} from '../../middleware/RequestCacheMiddleware';
import type {IUserRepository} from '../../user/IUserRepository';
import type {AdminAuditService} from './AdminAuditService';
import {AdminGuildBulkService} from './guild/AdminGuildBulkService';
import {AdminGuildLookupService} from './guild/AdminGuildLookupService';
import {AdminGuildManagementService} from './guild/AdminGuildManagementService';
import {AdminGuildMembershipService} from './guild/AdminGuildMembershipService';
import {AdminGuildUpdatePropagator} from './guild/AdminGuildUpdatePropagator';
import {AdminGuildUpdateService} from './guild/AdminGuildUpdateService';
import {AdminGuildVanityService} from './guild/AdminGuildVanityService';

interface AdminGuildServiceDeps {
	guildRepository: IGuildRepositoryAggregate;
	userRepository: IUserRepository;
	channelRepository: IChannelRepository;
	inviteRepository: InviteRepository;
	guildService: GuildService;
	gatewayService: IGatewayService;
	entityAssetService: EntityAssetService;
	auditService: AdminAuditService;
	discoveryRepository: IGuildDiscoveryRepository;
}

export class AdminGuildService {
	readonly lookupService: AdminGuildLookupService;
	readonly updateService: AdminGuildUpdateService;
	readonly vanityService: AdminGuildVanityService;
	readonly membershipService: AdminGuildMembershipService;
	readonly bulkService: AdminGuildBulkService;
	readonly managementService: AdminGuildManagementService;
	private readonly updatePropagator: AdminGuildUpdatePropagator;
	private readonly guildService: GuildService;

	constructor(deps: AdminGuildServiceDeps) {
		this.guildService = deps.guildService;
		this.updatePropagator = new AdminGuildUpdatePropagator({
			gatewayService: deps.gatewayService,
			discoveryRepository: deps.discoveryRepository,
		});
		this.lookupService = new AdminGuildLookupService({
			guildRepository: deps.guildRepository,
			userRepository: deps.userRepository,
			channelRepository: deps.channelRepository,
			gatewayService: deps.gatewayService,
		});
		this.updateService = new AdminGuildUpdateService({
			guildRepository: deps.guildRepository,
			entityAssetService: deps.entityAssetService,
			auditService: deps.auditService,
			updatePropagator: this.updatePropagator,
		});
		this.vanityService = new AdminGuildVanityService({
			guildRepository: deps.guildRepository,
			inviteRepository: deps.inviteRepository,
			auditService: deps.auditService,
			updatePropagator: this.updatePropagator,
		});
		this.membershipService = new AdminGuildMembershipService({
			userRepository: deps.userRepository,
			guildService: deps.guildService,
			auditService: deps.auditService,
		});
		this.bulkService = new AdminGuildBulkService({
			guildUpdateService: this.updateService,
			auditService: deps.auditService,
		});
		this.managementService = new AdminGuildManagementService({
			guildRepository: deps.guildRepository,
			gatewayService: deps.gatewayService,
			guildService: deps.guildService,
			auditService: deps.auditService,
		});
	}

	async listGuildAuditLogs(data: ListGuildAuditLogsRequest) {
		return this.guildService.fetchGuildAuditLogs({
			guildId: createGuildID(data.guild_id),
			requestCache: createRequestCache(),
			limit: data.limit,
			beforeLogId: data.before,
			afterLogId: data.after,
			filterUserId: data.user_id ? createUserID(data.user_id) : undefined,
			actionType: data.action_type,
		});
	}
}
