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

namespace Tiku.Api.Controllers;

[ApiController]
[Tags("平台端-平台管理")]
[Authorize(Policy = BackendPermissions.PlatformDashboardView)]
[Produces("application/json")]
[Route("api/platform-admin")]
public sealed class PlatformAdminController(
    IPlatformAdminService platformAdminService,
    ICurrentUser currentUser) : ControllerBase
{
    [HttpGet("overview")]
    [EndpointSummary("查询平台经营概览")]
    [ProducesResponseType<PlatformOverview>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformOverview>> Overview(CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetOverviewAsync(ResolveActor(), cancellationToken));
    }

    [HttpGet("tenants")]
    [Authorize(Policy = BackendPermissions.PlatformTenantManage)]
    [EndpointSummary("查询平台租户列表")]
    [ProducesResponseType<PlatformTenantList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformTenantList>> Tenants(
        [FromQuery] PlatformAdminQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetTenantsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
    }

    [HttpPost("tenants")]
    [Authorize(Policy = BackendPermissions.PlatformTenantManage)]
    [EndpointSummary("创建平台租户")]
    [ProducesResponseType<PlatformTenantProvisioningResult>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformTenantProvisioningResult>> CreateTenant(
        CreatePlatformTenantDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.CreateTenantAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("tenants/detail")]
    [Authorize(Policy = BackendPermissions.PlatformTenantManage)]
    [EndpointSummary("查询平台租户详情")]
    [ProducesResponseType<PlatformTenantDetail>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformTenantDetail>> TenantDetail(
        [FromQuery] Guid tenantId,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetTenantDetailAsync(ResolveActor(), tenantId, cancellationToken));
    }

    [HttpPatch("tenants/status")]
    [Authorize(Policy = BackendPermissions.PlatformTenantManage)]
    [EndpointSummary("更新租户业务与账务状态")]
    [ProducesResponseType<PlatformTenantItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformTenantItem>> TenantStatus(
        UpdatePlatformTenantStatusDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.UpdateTenantStatusAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPut("tenants/billing-profile")]
    [Authorize(Policy = BackendPermissions.PlatformTenantManage)]
    [EndpointSummary("保存租户账务与开票资料")]
    [ProducesResponseType<TenantBillingProfileItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<TenantBillingProfileItem>> BillingProfile(
        UpsertPlatformTenantBillingProfileDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.UpsertTenantBillingProfileAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("domains")]
    [Authorize(Policy = BackendPermissions.PlatformTenantManage)]
    [EndpointSummary("查询租户域名状态")]
    [ProducesResponseType<PlatformDomainList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformDomainList>> Domains(
        [FromQuery] PlatformAdminQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetDomainsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
    }

    [HttpPost("domains/{domainId:guid}/recheck")]
    [Authorize(Policy = BackendPermissions.PlatformTenantManage)]
    [EndpointSummary("重新触发租户域名 DNS/TLS 验证")]
    [ProducesResponseType<PlatformDomainRecheckResult>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformDomainRecheckResult>> RecheckDomain(
        Guid domainId,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.RecheckDomainAsync(ResolveActor(), domainId, cancellationToken));
    }

    [HttpGet("staff")]
    [Authorize(Policy = BackendPermissions.PlatformStaffManage)]
    [EndpointSummary("查询平台员工列表")]
    [ProducesResponseType<PlatformStaffList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformStaffList>> Staff(
        [FromQuery] PlatformAdminQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetStaffAsync(ResolveActor(), query.ToQuery(), cancellationToken));
    }

    [HttpPut("staff")]
    [Authorize(Policy = BackendPermissions.PlatformStaffManage)]
    [EndpointSummary("创建或更新平台员工")]
    [ProducesResponseType<PlatformStaffItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformStaffItem>> UpsertStaff(
        UpsertPlatformStaffDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.UpsertStaffAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPatch("staff/status")]
    [Authorize(Policy = BackendPermissions.PlatformStaffManage)]
    [EndpointSummary("启用或禁用平台员工")]
    [ProducesResponseType<PlatformStaffItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformStaffItem>> StaffStatus(
        UpdatePlatformStaffStatusDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.UpdateStaffStatusAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("audit-logs")]
    [Authorize(Policy = BackendPermissions.PlatformAuditView)]
    [EndpointSummary("查询平台审计日志")]
    [ProducesResponseType<PlatformAuditLogList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformAuditLogList>> AuditLogs(
        [FromQuery] PlatformAdminQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetAuditLogsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
    }

    [HttpGet("audit-alerts")]
    [Authorize(Policy = BackendPermissions.PlatformAuditView)]
    [EndpointSummary("查询平台审计告警")]
    [ProducesResponseType<PlatformAuditAlertList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformAuditAlertList>> AuditAlerts(
        [FromQuery] PlatformAdminQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetAuditAlertsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
    }

    [HttpPost("audit-alerts/status")]
    [Authorize(Policy = BackendPermissions.PlatformAuditView)]
    [EndpointSummary("更新平台审计告警状态")]
    [ProducesResponseType<PlatformAuditAlert>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformAuditAlert>> AuditAlertStatus(
        UpdatePlatformAuditAlertStatusDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.UpdateAuditAlertStatusAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("saas/dunning/channels")]
    [Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
    [EndpointSummary("查询平台催缴通知渠道")]
    [ProducesResponseType<PlatformBillingDunningChannelList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformBillingDunningChannelList>> BillingDunningChannels(
        [FromQuery] PlatformAdminQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetBillingDunningChannelsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
    }

    [HttpPut("saas/dunning/channels")]
    [Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
    [EndpointSummary("创建或更新平台催缴通知渠道")]
    [ProducesResponseType<PlatformBillingDunningChannelItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformBillingDunningChannelItem>> UpsertBillingDunningChannel(
        UpsertPlatformBillingDunningChannelDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.UpsertBillingDunningChannelAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpPost("saas/dunning/channels/disable")]
    [Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
    [EndpointSummary("禁用平台催缴通知渠道")]
    [ProducesResponseType<PlatformBillingDunningChannelItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformBillingDunningChannelItem>> DisableBillingDunningChannel(
        DisablePlatformBillingDunningChannelDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.DisableBillingDunningChannelAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    [HttpGet("saas/dunning/events")]
    [Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
    [EndpointSummary("查询平台催缴通知事件")]
    [ProducesResponseType<PlatformBillingDunningEventList>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformBillingDunningEventList>> BillingDunningEvents(
        [FromQuery] PlatformAdminQueryDto query,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetBillingDunningEventsAsync(ResolveActor(), query.ToQuery(), cancellationToken));
    }

    [HttpGet("saas/dunning/events/detail")]
    [Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
    [EndpointSummary("查询平台催缴通知事件详情")]
    [ProducesResponseType<PlatformBillingDunningEventItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformBillingDunningEventItem>> BillingDunningEventDetail(
        [FromQuery] Guid eventId,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.GetBillingDunningEventDetailAsync(ResolveActor(), eventId, cancellationToken));
    }

    [HttpPost("saas/dunning/events/retry")]
    [Authorize(Policy = BackendPermissions.PlatformBillingNotification)]
    [EndpointSummary("重新标记平台催缴通知事件待发送")]
    [ProducesResponseType<PlatformBillingDunningEventItem>(StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformBillingDunningEventItem>> RetryBillingDunningEvent(
        RetryPlatformBillingDunningEventDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await platformAdminService.RetryBillingDunningEventAsync(ResolveActor(), request.ToCommand(), cancellationToken));
    }

    private PlatformAdminActor ResolveActor()
    {
        if (currentUser.UserId is not { } userId)
        {
            throw new PlatformAdminException("Platform admin actor was not resolved.", "platform_access_denied");
        }

        return new PlatformAdminActor(userId);
    }
}
