using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Tiku.Api.Contracts;
using Tiku.Application.Auth;
using Tiku.Application.Catalog;
using Tiku.Application.Content;
using Tiku.Application.Security;
using Tiku.Application.TenantAdmin;

namespace Tiku.Api.Controllers;

[ApiController]
[Tags("租户端-运营管理")]
[Produces("application/json")]
[Route("api/tenant")]
public sealed class TenantAdminDirectController(
    ITenantAdminDirectService tenantAdminService,
    IAuthAdministrationService authAdministrationService,
    ICurrentUser currentUser,
    ITenantContext currentTenant) : ControllerBase
{
    [HttpGet("overview")]
    [Authorize(Policy = BackendPermissions.TenantDashboardView)]
    [EndpointSummary("查询租户后台运营概览")]
    [ProducesResponseType<TenantAdminOverviewItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantAdminOverviewItem>> GetOverview(CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetOverviewAsync(ResolveActor(), cancellationToken));
    }

    [HttpGet("classes")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询租户班级")]
    [ProducesResponseType<TenantAdminClassList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantAdminClassList>> GetClasses(
        [FromQuery] TenantAdminClassQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetClassesAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("classes")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("新增或更新租户班级")]
    [ProducesResponseType<ContentManagementResult<TenantAdminClassItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminClassItem>>> UpsertClass(
        UpsertTenantAdminClassDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertClassAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPost("classes/disable")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("停用租户班级")]
    [ProducesResponseType<ContentManagementResult<TenantAdminClassItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminClassItem>>> DisableClass(
        [FromBody] Guid classId,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.DisableClassAsync(ResolveActor(), classId, cancellationToken));
    }

    [HttpGet("classes/members")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询班级成员")]
    [ProducesResponseType<CatalogList<TenantAdminClassMemberItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminClassMemberItem>>> GetClassMembers(
        [FromQuery] TenantAdminClassMemberQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetClassMembersAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("classes/members")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("新增或更新班级成员")]
    [ProducesResponseType<ContentManagementResult<TenantAdminClassMemberItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminClassMemberItem>>> UpsertClassMember(
        UpsertTenantAdminClassMemberDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertClassMemberAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpPost("classes/members/remove")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("移除班级成员")]
    [ProducesResponseType<ContentManagementResult<TenantAdminClassMemberItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminClassMemberItem>>> RemoveClassMember(
        RemoveTenantAdminClassMemberDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.RemoveClassMemberAsync(ResolveActor(), request.ClassMemberId,
            cancellationToken));
    }

    [HttpGet("students")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询租户学生")]
    [ProducesResponseType<TenantAdminStudentList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantAdminStudentList>> GetStudents(
        [FromQuery] TenantAdminStudentQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetStudentsAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("students")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("新增或更新租户学生档案")]
    [ProducesResponseType<ContentManagementResult<TenantAdminStudentItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminStudentItem>>> UpsertStudent(
        UpsertTenantAdminStudentDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertStudentAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPost("students/status")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("更新租户学生状态")]
    [ProducesResponseType<ContentManagementResult<TenantAdminStudentStatusItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminStudentStatusItem>>> UpdateStudentStatus(
        UpdateTenantAdminStudentStatusDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpdateStudentStatusAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpPost("students/import/preview")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("预览学生批量导入")]
    [ProducesResponseType<TenantAdminStudentImportPreview>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantAdminStudentImportPreview>> PreviewStudentImport(
        TenantAdminStudentImportDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.PreviewStudentImportAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpPost("students/import")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("提交学生批量导入")]
    [ProducesResponseType<TenantAdminStudentImportResult>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantAdminStudentImportResult>> ImportStudents(
        TenantAdminStudentImportDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.ImportStudentsAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPost("students/bulk-assign-class")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("批量分班")]
    [ProducesResponseType<TenantAdminBulkOperationResult>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantAdminBulkOperationResult>> BulkAssignClass(
        TenantAdminBulkAssignClassDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.BulkAssignClassAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpPost("students/bulk-status")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("批量调整学生状态")]
    [ProducesResponseType<TenantAdminBulkOperationResult>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantAdminBulkOperationResult>> BulkStudentStatus(
        TenantAdminBulkStatusDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.BulkUpdateStudentStatusAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpGet("students/supervision/rules")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询学习督导规则")]
    [ProducesResponseType<CatalogList<TenantSupervisionRuleItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantSupervisionRuleItem>>> SupervisionRules(
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetSupervisionRulesAsync(ResolveActor(), cancellationToken));
    }

    [HttpPut("students/supervision/rules")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("新增或更新学习督导规则")]
    [ProducesResponseType<ContentManagementResult<TenantSupervisionRuleItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantSupervisionRuleItem>>> UpsertSupervisionRule(
        UpsertTenantSupervisionRuleDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertSupervisionRuleAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpGet("students/supervision/preview")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("预览学习风险学生")]
    [ProducesResponseType<TenantSupervisionPreview>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantSupervisionPreview>> PreviewSupervision(CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.PreviewSupervisionAsync(ResolveActor(), cancellationToken));
    }

    [HttpPost("students/supervision/generate")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("批量生成学习督导跟进任务")]
    [ProducesResponseType<TenantSupervisionGenerateResult>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantSupervisionGenerateResult>> GenerateSupervision(
        TenantSupervisionGenerateDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GenerateSupervisionFollowupsAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpGet("student-followups/report")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询学生跟进统计报表")]
    [ProducesResponseType<TenantFollowupReport>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantFollowupReport>> FollowupReport(CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetFollowupReportAsync(ResolveActor(), cancellationToken));
    }

    [HttpGet("feedbacks/report")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询反馈处理统计报表")]
    [ProducesResponseType<TenantFeedbackReport>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantFeedbackReport>> FeedbackReport(CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetFeedbackReportAsync(ResolveActor(), cancellationToken));
    }

    [HttpGet("points/risk-report")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询积分风险统计报表")]
    [ProducesResponseType<TenantPointRiskReport>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantPointRiskReport>> PointRiskReport(CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetPointRiskReportAsync(ResolveActor(), cancellationToken));
    }

    [HttpGet("student-notes")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询学生备注")]
    [ProducesResponseType<CatalogList<TenantAdminStudentNoteItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminStudentNoteItem>>> GetStudentNotes(
        [FromQuery] TenantAdminStudentActivityQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetStudentNotesAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("student-notes")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("新增或更新学生备注")]
    [ProducesResponseType<ContentManagementResult<TenantAdminStudentNoteItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminStudentNoteItem>>> UpsertStudentNote(
        UpsertTenantAdminStudentNoteDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertStudentNoteAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpGet("student-followups")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询学生跟进")]
    [ProducesResponseType<CatalogList<TenantAdminStudentFollowupItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminStudentFollowupItem>>> GetStudentFollowups(
        [FromQuery] TenantAdminStudentActivityQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(
            await tenantAdminService.GetStudentFollowupsAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("student-followups")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("新增或更新学生跟进")]
    [ProducesResponseType<ContentManagementResult<TenantAdminStudentFollowupItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminStudentFollowupItem>>> UpsertStudentFollowup(
        UpsertTenantAdminStudentFollowupDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertStudentFollowupAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpGet("members")]
    [Authorize(Policy = BackendPermissions.TenantStaffManage)]
    [EndpointSummary("查询租户成员")]
    [ProducesResponseType<CatalogList<TenantAdminMemberItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminMemberItem>>> GetMembers(
        [FromQuery] TenantAdminMemberQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetMembersAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("members")]
    [Authorize(Policy = BackendPermissions.TenantStaffManage)]
    [EndpointSummary("新增或更新租户成员")]
    [ProducesResponseType<ContentManagementResult<TenantAdminMemberItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminMemberItem>>> UpsertMember(
        UpsertTenantAdminMemberDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertMemberAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPost("members/disable")]
    [Authorize(Policy = BackendPermissions.TenantStaffManage)]
    [EndpointSummary("停用租户成员并撤销会话")]
    [ProducesResponseType<ContentManagementResult<TenantAdminMemberItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminMemberItem>>> DisableMember(
        DisableTenantAdminMemberDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.DisableMemberAsync(ResolveActor(), request.MembershipId, cancellationToken));
    }

    [HttpPost("members/{userId:guid}/password-reset")]
    [Authorize(Policy = BackendPermissions.TenantStaffManage)]
    [EndpointSummary("为租户成员设置一次性临时密码")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    public async Task<IActionResult> ResetMemberPassword(
        Guid userId,
        AdministrativePasswordResetDto request,
        CancellationToken cancellationToken)
    {
        var actor = ResolveActor();
        await authAdministrationService.ResetPasswordAsync(
            new AdministrativePasswordResetRequest(
                actor.UserId,
                userId,
                actor.TenantId,
                request.TemporaryPassword,
                request.Reason),
            cancellationToken);
        return NoContent();
    }

    [HttpGet("audit-logs")]
    [Authorize(Policy = BackendPermissions.TenantStaffManage)]
    [EndpointSummary("查询租户审计日志")]
    [ProducesResponseType<CatalogList<TenantAdminAuditLogItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminAuditLogItem>>> GetAuditLogs(
        [FromQuery] TenantAdminAuditLogQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetAuditLogsAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("branding")]
    [Authorize(Policy = BackendPermissions.TenantSettingsManage)]
    [EndpointSummary("更新租户品牌信息")]
    [ProducesResponseType<ContentManagementResult<TenantBrandingItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantBrandingItem>>> UpsertBranding(
        UpsertTenantBrandingDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertBrandingAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPut("settings")]
    [Authorize(Policy = BackendPermissions.TenantSettingsManage)]
    [EndpointSummary("更新租户公开设置与功能开关")]
    [ProducesResponseType<ContentManagementResult<TenantSettingsItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantSettingsItem>>> UpsertSettings(
        UpsertTenantSettingsDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertSettingsAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("theme-templates")]
    [Authorize(Policy = BackendPermissions.TenantSettingsManage)]
    [EndpointSummary("查询可用租户主题模板")]
    [ProducesResponseType<CatalogList<TenantThemeTemplateItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantThemeTemplateItem>>> GetThemeTemplates(
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetThemeTemplatesAsync(ResolveActor(), cancellationToken));
    }

    [HttpGet("theme")]
    [Authorize(Policy = BackendPermissions.TenantSettingsManage)]
    [EndpointSummary("查询租户当前主题与草稿")]
    [ProducesResponseType<ContentManagementResult<TenantThemeItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantThemeItem>>> GetTheme(
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetThemeAsync(ResolveActor(), cancellationToken));
    }

    [HttpPost("theme/preview")]
    [Authorize(Policy = BackendPermissions.TenantSettingsManage)]
    [EndpointSummary("生成租户主题草稿")]
    [ProducesResponseType<ContentManagementResult<TenantThemeItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantThemeItem>>> PreviewTheme(
        PreviewTenantThemeDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.PreviewThemeAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPost("theme/publish")]
    [Authorize(Policy = BackendPermissions.TenantSettingsManage)]
    [EndpointSummary("发布租户主题")]
    [ProducesResponseType<ContentManagementResult<TenantThemeItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantThemeItem>>> PublishTheme(
        PublishTenantThemeDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.PublishThemeAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("domains")]
    [Authorize(Policy = BackendPermissions.TenantSettingsManage)]
    [EndpointSummary("查询租户域名")]
    [ProducesResponseType<CatalogList<TenantDomainItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantDomainItem>>> GetDomains(CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetDomainsAsync(ResolveActor(), cancellationToken));
    }

    [HttpPost("domains")]
    [Authorize(Policy = BackendPermissions.TenantSettingsManage)]
    [EndpointSummary("添加租户域名")]
    [ProducesResponseType<ContentManagementResult<TenantDomainItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantDomainItem>>> CreateDomain(
        CreateTenantDomainDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.CreateDomainAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("auth-providers")]
    [Authorize(Policy = BackendPermissions.TenantProviderManage)]
    [EndpointSummary("查询租户登录 Provider 公开配置")]
    [ProducesResponseType<CatalogList<TenantIdentityProviderItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantIdentityProviderItem>>> GetAuthProviders(
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetAuthProvidersAsync(ResolveActor(), cancellationToken));
    }

    [HttpPut("auth-providers")]
    [Authorize(Policy = BackendPermissions.TenantProviderManage)]
    [EndpointSummary("新增或更新租户登录 Provider")]
    [ProducesResponseType<ContentManagementResult<TenantIdentityProviderItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantIdentityProviderItem>>> UpsertAuthProvider(
        UpsertTenantIdentityProviderDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertAuthProviderAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpGet("badges")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询租户勋章")]
    [ProducesResponseType<CatalogList<TenantAdminBadgeItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminBadgeItem>>> GetBadges(
        [FromQuery] TenantAdminBadgeQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetBadgesAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("badges")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("新增或更新租户勋章")]
    [ProducesResponseType<ContentManagementResult<TenantAdminBadgeItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminBadgeItem>>> UpsertBadge(
        UpsertTenantAdminBadgeDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertBadgeAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("badge-grants")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询勋章发放记录")]
    [ProducesResponseType<CatalogList<TenantAdminBadgeGrantItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminBadgeGrantItem>>> GetBadgeGrants(
        [FromQuery] TenantAdminBadgeGrantQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetBadgeGrantsAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPost("badge-grants")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("向租户成员发放勋章")]
    [ProducesResponseType<ContentManagementResult<TenantAdminBadgeGrantItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminBadgeGrantItem>>> GrantBadge(
        GrantTenantAdminBadgeDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GrantBadgeAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("notifications")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询用户站内通知")]
    [ProducesResponseType<CatalogList<TenantAdminNotificationItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminNotificationItem>>> GetNotifications(
        [FromQuery] TenantAdminNotificationQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetNotificationsAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPut("notifications")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("新增或更新用户站内通知")]
    [ProducesResponseType<ContentManagementResult<TenantAdminNotificationItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminNotificationItem>>> UpsertNotification(
        UpsertTenantAdminNotificationDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpsertNotificationAsync(ResolveActor(), request.ToCommand(),
            cancellationToken));
    }

    [HttpGet("feedbacks")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("查询用户反馈")]
    [ProducesResponseType<CatalogList<TenantAdminFeedbackItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<CatalogList<TenantAdminFeedbackItem>>> GetFeedbacks(
        [FromQuery] TenantAdminFeedbackQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.GetFeedbacksAsync(ResolveActor(), query.ToFilter(), cancellationToken));
    }

    [HttpPost("feedbacks/status")]
    [Authorize(Policy = BackendPermissions.TenantStudentManage)]
    [EndpointSummary("处理用户反馈")]
    [ProducesResponseType<ContentManagementResult<TenantAdminFeedbackItem>>(StatusCodes.Status200OK)]
    public async Task<ActionResult<ContentManagementResult<TenantAdminFeedbackItem>>> UpdateFeedback(
        UpdateTenantAdminFeedbackDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await tenantAdminService.UpdateFeedbackAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    private TenantAdminActor ResolveActor()
    {
        try
        {
            return TenantAdminActor.FromResolvedIdentity(currentTenant.TenantId, currentUser.UserId);
        }
        catch (InvalidOperationException exception)
        {
            throw new TenantAdminDirectException(exception.Message, "tenant_admin_access_denied");
        }
    }
}