using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Tiku.Api.Contracts;
using Tiku.Api.OpenApi;
using Tiku.Application.PlatformAdmin;
using Tiku.Application.Security;
using Tiku.Domain.Platform;

namespace Tiku.Api.Controllers;

[ApiController]
[Tags("平台端-治理配置")]
[Route("api/platform/governance")]
[Authorize(Policy = TikuPolicies.PlatformBackofficeBootstrap)]
public sealed class PlatformGovernanceController(
    IPlatformGovernanceService governanceService,
    ICurrentAccessContext currentAccessContext) : ControllerBase
{
    [HttpGet("configuration/definitions")]
    [Authorize(Policy = BackendPermissions.PlatformConfigurationManage)]
    [EndpointSummary("查询类型化平台配置定义")]
    public async Task<IReadOnlyCollection<PlatformConfigurationDefinitionItem>> ConfigurationDefinitions(
        CancellationToken cancellationToken)
    {
        return await governanceService.GetConfigurationDefinitionsAsync(await ActorAsync(cancellationToken),
            cancellationToken);
    }

    [HttpGet("configuration/versions")]
    [Authorize(Policy = BackendPermissions.PlatformConfigurationManage)]
    [EndpointSummary("查询平台配置版本")]
    public async Task<IReadOnlyCollection<PlatformConfigurationVersionItem>> ConfigurationVersions(
        string definitionCode, string? environment, CancellationToken cancellationToken)
    {
        return await governanceService.GetConfigurationVersionsAsync(await ActorAsync(cancellationToken),
            definitionCode, environment, cancellationToken);
    }

    [HttpPost("configuration/drafts")]
    [Authorize(Policy = BackendPermissions.PlatformConfigurationManage)]
    [EndpointSummary("保存平台配置草稿")]
    public async Task<PlatformConfigurationVersionItem> SaveConfigurationDraft(
        SavePlatformConfigurationDraftDto request, CancellationToken cancellationToken)
    {
        return await governanceService.SaveConfigurationDraftAsync(await ActorAsync(cancellationToken),
            request.ToCommand(), cancellationToken);
    }

    [HttpPost("configuration/versions/{versionId:guid}/publish")]
    [Authorize(Policy = BackendPermissions.PlatformConfigurationManage)]
    [EndpointSummary("发布平台配置版本")]
    [PlatformOperationRisk("high")]
    public async Task<PlatformConfigurationVersionItem> PublishConfiguration(Guid versionId,
        CancellationToken cancellationToken)
    {
        return await governanceService.PublishConfigurationAsync(await ActorAsync(cancellationToken), versionId,
            cancellationToken);
    }

    [HttpPost("configuration/versions/{versionId:guid}/rollback")]
    [Authorize(Policy = BackendPermissions.PlatformConfigurationManage)]
    [EndpointSummary("回滚平台配置版本")]
    [PlatformOperationRisk("high")]
    public async Task<PlatformConfigurationVersionItem> RollbackConfiguration(Guid versionId,
        PlatformRollbackDto request, CancellationToken cancellationToken)
    {
        return await governanceService.RollbackConfigurationAsync(await ActorAsync(cancellationToken), versionId,
            request.Reason, cancellationToken);
    }

    [HttpGet("notifications/templates")]
    [Authorize(Policy = BackendPermissions.PlatformNotificationManage)]
    [EndpointSummary("查询平台通知模板")]
    public async Task<IReadOnlyCollection<PlatformNotificationTemplateItem>> NotificationTemplates(
        CancellationToken cancellationToken)
    {
        return await governanceService.GetNotificationTemplatesAsync(await ActorAsync(cancellationToken),
            cancellationToken);
    }

    [HttpPut("notifications/templates")]
    [Authorize(Policy = BackendPermissions.PlatformNotificationManage)]
    [EndpointSummary("新增或更新平台通知模板")]
    public async Task<PlatformNotificationTemplateItem> UpsertNotificationTemplate(
        UpsertPlatformNotificationTemplateDto request, CancellationToken cancellationToken)
    {
        return await governanceService.UpsertNotificationTemplateAsync(await ActorAsync(cancellationToken),
            request.ToCommand(), cancellationToken);
    }

    [HttpPost("notifications/send")]
    [Authorize(Policy = BackendPermissions.PlatformNotificationManage)]
    [EndpointSummary("按平台岗位发送通知")]
    public async Task<IReadOnlyCollection<PlatformNotificationDeliveryItem>> SendNotification(
        SendPlatformNotificationDto request, CancellationToken cancellationToken)
    {
        return await governanceService.SendNotificationAsync(await ActorAsync(cancellationToken), request.ToCommand(),
            cancellationToken);
    }

    [HttpGet("notifications/deliveries")]
    [Authorize(Policy = BackendPermissions.PlatformNotificationManage)]
    [EndpointSummary("分页查询平台通知投递")]
    public async Task<PagedResult<PlatformNotificationDeliveryItem>> NotificationDeliveries(
        int page = 1, int pageSize = 50, string? search = null, PlatformNotificationDeliveryStatus? status = null,
        CancellationToken cancellationToken = default)
    {
        return await governanceService.GetNotificationDeliveriesAsync(await ActorAsync(cancellationToken),
            new PagedQuery(page, pageSize, search), status, cancellationToken);
    }

    [HttpPost("notifications/deliveries/{deliveryId:guid}/retry")]
    [Authorize(Policy = BackendPermissions.PlatformNotificationManage)]
    [EndpointSummary("重试平台通知投递")]
    public async Task<PlatformNotificationDeliveryItem> RetryNotification(Guid deliveryId,
        CancellationToken cancellationToken)
    {
        return await governanceService.RetryNotificationAsync(await ActorAsync(cancellationToken), deliveryId,
            cancellationToken);
    }

    private async Task<PlatformApprovalActor> ActorAsync(CancellationToken cancellationToken)
    {
        var access = await currentAccessContext.GetAsync(cancellationToken);
        return access.UserId is { } userId && access.IsUserActive
            ? new PlatformApprovalActor(userId, access.PlatformPermissions)
            : throw new PlatformApprovalException("Platform actor was not resolved.", "platform_access_denied");
    }
}