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

namespace Tiku.Api.Controllers;

[ApiController]
[Tags("平台端-运维")]
[Route("api/platform/operations")]
[Authorize(Policy = BackendPermissions.PlatformOperationsView)]
public sealed class PlatformOperationsController(
    IBackgroundJobOperations backgroundJobService,
    ICurrentUser currentUser,
    IPlatformOperationsQueryService operationsQueries) : ControllerBase
{
    [HttpGet("health")]
    [EndpointSummary("查询受保护的依赖深度健康状态")]
    public async Task<ActionResult<object>> Health(CancellationToken cancellationToken)
    {
        var health = await operationsQueries.GetHealthAsync(cancellationToken);
        return Ok(new
        {
            status = health.Healthy ? "healthy" : "degraded",
            database = health.Database,
            redis = new { configured = health.RedisConfigured, ready = health.RedisReady },
            worker = new { ready = health.WorkerReady, lastHeartbeatAt = health.LastHeartbeatAt },
            clamAv = health.ClamAv,
            storage = new { provider = health.StorageProvider, configured = health.StorageConfigured },
            checkedAt = health.CheckedAt
        });
    }

    [HttpGet("workers")]
    [EndpointSummary("查询 Worker 与周期循环状态")]
    public async Task<ActionResult<object>> Workers(CancellationToken cancellationToken)
    {
        var items = await operationsQueries.GetWorkersAsync(cancellationToken);
        return Ok(new
        {
            staleAfterSeconds = 120,
            items = items.Select(item => new
            {
                item.WorkerId,
                item.Processor,
                item.StartedAt,
                item.LastHeartbeatAt,
                item.LastIterationStartedAt,
                item.LastIterationCompletedAt,
                item.LastSucceededAt,
                item.LastError,
                item.IsRunning,
                stale = item.Stale
            })
        });
    }

    [HttpGet("job-metrics")]
    [EndpointSummary("查询后台任务队列指标")]
    public async Task<ActionResult<object>> JobMetrics(CancellationToken cancellationToken)
    {
        var metrics = await operationsQueries.GetJobMetricsAsync(cancellationToken);
        return Ok(new
        {
            counts = metrics.Counts.Select(item => new { status = item.Status, count = item.Count }),
            oldestPendingAt = metrics.OldestPendingAt,
            queueAgeSeconds = metrics.QueueAgeSeconds,
            expiredLeases = metrics.ExpiredLeases,
            checkedAt = metrics.CheckedAt
        });
    }

    [HttpGet("governance-metrics")]
    [EndpointSummary("查询审批、配置与通知治理指标")]
    public async Task<ActionResult<object>> GovernanceMetrics(CancellationToken cancellationToken)
    {
        var metrics = await operationsQueries.GetGovernanceMetricsAsync(cancellationToken);
        return Ok(new
        {
            approvals = metrics.Approvals.Select(item => new { status = item.Status, count = item.Count }),
            expiredPending = metrics.ExpiredPending,
            configurationDrafts = metrics.ConfigurationDrafts,
            notifications = metrics.Notifications.Select(item => new { status = item.Status, count = item.Count }),
            checkedAt = metrics.CheckedAt
        });
    }

    [HttpGet("jobs")]
    [EndpointSummary("查询全平台后台任务")]
    public async Task<ActionResult<IReadOnlyCollection<BackgroundJobItem>>> Jobs(
        [FromQuery] Guid? tenantId,
        [FromQuery] string? jobType,
        [FromQuery] BackgroundJobStatus? status,
        [FromQuery] int? limit,
        CancellationToken cancellationToken)
    {
        return Ok(await backgroundJobService.ListPlatformAsync(
            tenantId, jobType, status, limit ?? 100, cancellationToken));
    }

    [HttpGet("jobs/{jobId:guid}")]
    [EndpointSummary("查询平台后台任务详情")]
    public async Task<ActionResult<BackgroundJobItem>> Job(Guid jobId, CancellationToken cancellationToken)
    {
        var item = await backgroundJobService.GetAsync(jobId, null, cancellationToken);
        return item is null ? NotFound() : Ok(item);
    }

    [HttpPost("jobs/{jobId:guid}/cancel")]
    [Authorize(Policy = BackendPermissions.PlatformOperationsManage)]
    [EndpointSummary("取消平台后台任务")]
    public async Task<ActionResult<BackgroundJobItem>> CancelJob(
        Guid jobId,
        CancelBackgroundJobDto request,
        CancellationToken cancellationToken)
    {
        return Ok(await backgroundJobService.RequestCancellationAsync(
            jobId, null, ResolveUserId(), request.Reason, cancellationToken));
    }

    [HttpPost("jobs/{jobId:guid}/retry")]
    [Authorize(Policy = BackendPermissions.PlatformOperationsManage)]
    [EndpointSummary("重试平台后台任务")]
    public async Task<ActionResult<BackgroundJobItem>> RetryJob(Guid jobId, CancellationToken cancellationToken)
    {
        return Ok(await backgroundJobService.RetryAsync(jobId, null, ResolveUserId(), cancellationToken));
    }

    private Guid ResolveUserId()
    {
        return currentUser.UserId ?? throw new InvalidOperationException("Current platform user was not resolved.");
    }
}