using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Monitoring.Common;
using Monitoring.Controllers;
using Monitoring.Core.Domain.AssetManagement;
using Monitoring.Core.Domain.EventManagement;
using Monitoring.Extensions;
using Monitoring.Features.AlarmManagement.GetAlarmList;
using Monitoring.Infrastructure.Data;
using Monitoring.Models;

namespace Monitoring.Features.AlarmManagement;

[Route("api/alarms")]
[Authorize(Roles = Roles.Watcher)]
public class AlarmsController(DataContext dataContext) : BaseController
{
	[HttpGet(Name = "GetAlarmList")]
	[ProducesResponseType<TableDataResponseModel<AlarmModel>>(StatusCodes.Status200OK)]
	public async Task<IActionResult> GetList(
		[FromQuery] GetAlarmListRequest request,
		CancellationToken cancellationToken
	)
	{
		var query = dataContext
			.Alarms.Include(x => x.Event)
			.Include(x => x.Scope)
			.Where(x =>
				x.Event.Asset.Groups.Any(x => x.Accesses.Any(x => x.Member.UserId == UserId))
				&& x.Scope.StatusHistory.Count != 0
			)
			.GetAllowed(UserId);

		if (request.AssetId.HasValue)
		{
			var assetId = new AssetId(request.AssetId.Value);
			query = query.Where(x => x.Event.AssetId == assetId);
		}

		var events = await query
			.AsNoTracking()
			.OrderByDescending(x => x.Event.CreatedAt)
			.GetTable(request, AlarmModel.FromEntity, cancellationToken);

		return Ok(events);
	}

	[HttpGet("by-scope", Name = "GetAlarmListByScope")]
	[ProducesResponseType<List<AlarmModel>>(StatusCodes.Status200OK)]
	public async Task<IActionResult> GetListByScope(
		[FromQuery] GetAlarmListByScopeRequest request,
		CancellationToken cancellationToken
	)
	{
		var scopeId = new AlarmScopeId(request.ScopeId);
		var query = dataContext
			.Alarms.Include(x => x.Event)
			.Where(x =>
				x.Event.Asset.Groups.Any(x => x.Accesses.Any(x => x.Member.UserId == UserId))
				&& x.ScopeId == scopeId
			)
			.GetAllowed(UserId);

		var events = await query
			.AsNoTracking()
			.OrderByDescending(x => x.Event.CreatedAt)
			.Select(AlarmModel.FromEntity)
			.ToListAsync(cancellationToken);

		return Ok(events);
	}
}
