using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MiningService.API.Application.Commands;
using MiningService.API.Application.Queries;

namespace MiningService.API.Controllers;

/// <summary>
/// EN: Admin backoffice controller.
/// VI: Controller cho admin backoffice.
/// </summary>
[ApiController]
[Route("api/v1/admin")]
[Authorize(Roles = "Admin")]
public class AdminController : ControllerBase
{
    private readonly IMediator _mediator;

    public AdminController(IMediator mediator)
    {
        _mediator = mediator;
    }

    #region Configuration

    /// <summary>
    /// EN: Get all system configuration.
    /// VI: Lấy toàn bộ cấu hình hệ thống.
    /// </summary>
    [HttpGet("config")]
    [ProducesResponseType(typeof(SystemConfigDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetConfig(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetSystemConfigQuery(), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Update system configuration.
    /// VI: Cập nhật cấu hình hệ thống.
    /// </summary>
    [HttpPut("config")]
    [ProducesResponseType(typeof(UpdateConfigResult), StatusCodes.Status200OK)]
    public async Task<IActionResult> UpdateConfig([FromBody] UpdateSystemConfigCommand command, CancellationToken ct)
    {
        var result = await _mediator.Send(command, ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get mining configuration.
    /// VI: Lấy cấu hình đào.
    /// </summary>
    [HttpGet("config/mining")]
    [ProducesResponseType(typeof(MiningConfigDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetMiningConfig(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetSystemConfigQuery(), ct);
        return Ok(result.Mining);
    }

    /// <summary>
    /// EN: Update mining configuration.
    /// VI: Cập nhật cấu hình đào.
    /// </summary>
    [HttpPut("config/mining")]
    [ProducesResponseType(typeof(UpdateConfigResult), StatusCodes.Status200OK)]
    public async Task<IActionResult> UpdateMiningConfig([FromBody] UpdateMiningConfigCommand command, CancellationToken ct)
    {
        var result = await _mediator.Send(command, ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get streak configuration.
    /// VI: Lấy cấu hình streak.
    /// </summary>
    [HttpGet("config/streak")]
    [ProducesResponseType(typeof(StreakConfigDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetStreakConfig(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetSystemConfigQuery(), ct);
        return Ok(result.Streak);
    }

    /// <summary>
    /// EN: Update streak configuration.
    /// VI: Cập nhật cấu hình streak.
    /// </summary>
    [HttpPut("config/streak")]
    [ProducesResponseType(typeof(UpdateConfigResult), StatusCodes.Status200OK)]
    public async Task<IActionResult> UpdateStreakConfig([FromBody] UpdateStreakConfigCommand command, CancellationToken ct)
    {
        var result = await _mediator.Send(command, ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get referral configuration.
    /// VI: Lấy cấu hình giới thiệu.
    /// </summary>
    [HttpGet("config/referral")]
    [ProducesResponseType(typeof(ReferralConfigDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetReferralConfig(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetReferralConfigQuery(), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Update referral configuration.
    /// VI: Cập nhật cấu hình giới thiệu.
    /// </summary>
    [HttpPut("config/referral")]
    [ProducesResponseType(typeof(UpdateConfigResult), StatusCodes.Status200OK)]
    public async Task<IActionResult> UpdateReferralConfig([FromBody] UpdateReferralConfigCommand command, CancellationToken ct)
    {
        var result = await _mediator.Send(command, ct);
        return Ok(result);
    }

    #endregion

    #region Miner Management

    /// <summary>
    /// EN: List all miners (paginated).
    /// VI: Danh sách thợ đào (phân trang).
    /// </summary>
    [HttpGet("miners")]
    [ProducesResponseType(typeof(MinersListDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetMiners([FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] string? search = null, CancellationToken ct = default)
    {
        var result = await _mediator.Send(new GetMinersListQuery(page, pageSize, search), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get miner details.
    /// VI: Chi tiết thợ đào.
    /// </summary>
    [HttpGet("miners/{id}")]
    [ProducesResponseType(typeof(MinerDetailsDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetMinerDetails(Guid id, CancellationToken ct)
    {
        var result = await _mediator.Send(new GetMinerDetailsQuery(id), ct);
        if (result == null) return NotFound();
        return Ok(result);
    }

    /// <summary>
    /// EN: Suspend a miner account.
    /// VI: Tạm ngừng tài khoản thợ đào.
    /// </summary>
    [HttpPut("miners/{minerId}/suspend")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> SuspendMiner(Guid minerId, [FromBody] SuspendRequest request, CancellationToken ct)
    {
        await _mediator.Send(new SuspendMinerCommand(minerId, request.Reason), ct);
        return Ok(new { message = "Miner suspended successfully" });
    }

    /// <summary>
    /// EN: Ban a miner account.
    /// VI: Cấm tài khoản thợ đào.
    /// </summary>
    [HttpPut("miners/{minerId}/ban")]
    [ProducesResponseType(typeof(BanMinerResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> BanMiner(Guid minerId, [FromBody] BanRequest request, CancellationToken ct)
    {
        var result = await _mediator.Send(new BanMinerCommand(minerId, request.Reason), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Restore a suspended miner account.
    /// VI: Khôi phục tài khoản thợ đào bị tạm ngừng.
    /// </summary>
    [HttpPut("miners/{minerId}/restore")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> RestoreMiner(Guid minerId, CancellationToken ct)
    {
        await _mediator.Send(new RestoreMinerCommand(minerId), ct);
        return Ok(new { message = "Miner restored successfully" });
    }

    /// <summary>
    /// EN: Adjust miner points.
    /// VI: Điều chỉnh điểm thợ đào.
    /// </summary>
    [HttpPut("miners/{minerId}/adjust-points")]
    [ProducesResponseType(typeof(AdjustPointsResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> AdjustPoints(Guid minerId, [FromBody] AdjustPointsRequest request, CancellationToken ct)
    {
        var result = await _mediator.Send(new AdjustMinerPointsCommand(minerId, request.Amount, request.Reason), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Reset miner streak.
    /// VI: Reset streak thợ đào.
    /// </summary>
    [HttpPut("miners/{minerId}/reset-streak")]
    [ProducesResponseType(typeof(ResetStreakResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> ResetStreak(Guid minerId, [FromBody] ResetStreakRequest request, CancellationToken ct)
    {
        var result = await _mediator.Send(new ResetMinerStreakCommand(minerId, request.Reason), ct);
        return Ok(result);
    }

    #endregion

    #region Analytics

    /// <summary>
    /// EN: Get admin dashboard overview.
    /// VI: Lấy tổng quan dashboard admin.
    /// </summary>
    [HttpGet("analytics/overview")]
    [ProducesResponseType(typeof(AdminOverviewDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetOverview(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetAdminOverviewQuery(), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get miner analytics.
    /// VI: Lấy phân tích thợ đào.
    /// </summary>
    [HttpGet("analytics/miners")]
    [ProducesResponseType(typeof(MinerAnalyticsDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetMinerAnalytics(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetMinerAnalyticsQuery(), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get circle analytics.
    /// VI: Lấy phân tích vòng tròn.
    /// </summary>
    [HttpGet("analytics/circles")]
    [ProducesResponseType(typeof(CircleAnalyticsDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetCircleAnalytics(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetCircleAnalyticsQuery(), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get referral analytics.
    /// VI: Lấy phân tích giới thiệu.
    /// </summary>
    [HttpGet("analytics/referrals")]
    [ProducesResponseType(typeof(ReferralAnalyticsDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetReferralAnalytics(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetReferralAnalyticsQuery(), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get points analytics.
    /// VI: Lấy phân tích điểm số.
    /// </summary>
    [HttpGet("analytics/points")]
    [ProducesResponseType(typeof(PointsAnalyticsDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetPointsAnalytics(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetPointsAnalyticsQuery(), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get streak analytics.
    /// VI: Lấy phân tích streak.
    /// </summary>
    [HttpGet("analytics/streaks")]
    [ProducesResponseType(typeof(StreakAnalyticsDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetStreakAnalytics(CancellationToken ct)
    {
        var result = await _mediator.Send(new GetStreakAnalyticsQuery(), ct);
        return Ok(result);
    }

    /// <summary>
    /// EN: Get audit logs.
    /// VI: Lấy nhật ký kiểm tra.
    /// </summary>
    [HttpGet("audit-logs")]
    [ProducesResponseType(typeof(AuditLogsDto), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetAuditLogs([FromQuery] int page = 1, [FromQuery] int pageSize = 50, CancellationToken ct = default)
    {
        var result = await _mediator.Send(new GetAuditLogsQuery(page, pageSize), ct);
        return Ok(result);
    }

    #endregion
}

public record SuspendRequest(string Reason);
public record BanRequest(string Reason);
public record AdjustPointsRequest(decimal Amount, string Reason);
public record ResetStreakRequest(string Reason);
