using FluentValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Monitoring.Common;
using Monitoring.Controllers;
using Monitoring.Core.Domain.CheckListManagement;
using Monitoring.Extensions;
using Monitoring.Infrastructure.Data;
using Monitoring.Models;

namespace Monitoring.Features.CheckListManagement;

[Route("api/check-list-templates")]
[Authorize(Roles = $"{Roles.Manager},{Roles.Watcher}")]
public class CheckListTemplateController(DataContext dataContext) : BaseController
{
	[HttpPost("", Name = "CreateCheckListTemplate")]
	[Authorize(Roles = $"{Roles.Manager}")]
	[ProducesResponseType<CheckListTemplateModel>(StatusCodes.Status200OK)]
	[ProducesResponseType<string>(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> Create(
		CreateCheckListTemplateRequest request,
		CancellationToken cancellationToken
	)
	{
		var checkListTemplate = CheckListTemplate.Create(request.Type);
		foreach (var item in request.Items)
		{
			var checkListTemplateItem = CheckListTemplateItem.Create(
				checkListTemplate.Id,
				item.Index
			);
			checkListTemplate.Items.Add(checkListTemplateItem);

			foreach (var translation in item.Translations)
			{
				checkListTemplateItem.Translations.Add(
					CheckListTemplateItemTranslation.Create(
						checkListTemplateItem.Id,
						translation.LanguageCode,
						translation.Name,
						translation.Description
					)
				);
			}
		}

		dataContext.CheckListTemplates.Add(checkListTemplate);

		await dataContext.SaveChangesAsync(cancellationToken);

		return Ok(CheckListTemplateModel.FromEntity(checkListTemplate));
	}

	[HttpGet(Name = "GetCheckListTemplateList")]
	[ProducesResponseType<TableDataResponseModel<CheckListTemplateModel>>(StatusCodes.Status200OK)]
	public async Task<IActionResult> GetTable(
		[FromQuery] GetCheckListTemplateListRequest request,
		CancellationToken cancellationToken
	)
	{
		var query = dataContext.CheckListTemplates.AsQueryable();

		if (request.Type is not null)
		{
			query = query.Where(x => x.Type == request.Type);
		}

		return Ok(
			await query.GetTable(request, CheckListTemplateModel.Projection, cancellationToken)
		);
	}

	[HttpPut("{id:guid}", Name = "UpdateCheckListTemplate")]
	[Authorize(Roles = $"{Roles.Manager}")]
	[ProducesResponseType<CheckListTemplateModel>(StatusCodes.Status200OK)]
	[ProducesResponseType<string>(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> Update(
		Guid id,
		UpdateCheckListTemplateRequest request,
		CancellationToken cancellationToken
	)
	{
		var checkListTemplate = await dataContext
			.CheckListTemplates.Include(x => x.Items)
			.ThenInclude(x => x.Translations)
			.FirstOrDefaultAsync(x => x.Id == CheckListTemplateId.Create(id), cancellationToken);

		if (checkListTemplate is null)
		{
			return NotFound();
		}

		checkListTemplate.Update(request.Type);

		dataContext.RemoveRange(checkListTemplate.Items);
		checkListTemplate.Items.Clear();

		foreach (var item in request.Items)
		{
			var checkListTemplateItem = CheckListTemplateItem.Create(
				checkListTemplate.Id,
				item.Index
			);
			checkListTemplate.Items.Add(checkListTemplateItem);

			foreach (var translation in item.Translations)
			{
				checkListTemplateItem.Translations.Add(
					CheckListTemplateItemTranslation.Create(
						checkListTemplateItem.Id,
						translation.LanguageCode,
						translation.Name,
						translation.Description
					)
				);
			}
		}

		await dataContext.SaveChangesAsync(cancellationToken);

		return Ok(CheckListTemplateModel.FromEntity(checkListTemplate));
	}

	[HttpGet("{id:guid}", Name = "GetCheckListTemplateById")]
	[ProducesResponseType<CheckListTemplateModel>(StatusCodes.Status200OK)]
	public async Task<IActionResult> GetById(Guid id, CancellationToken cancellationToken)
	{
		var checkListTemplate = await dataContext
			.CheckListTemplates.Include(x => x.Items)
			.ThenInclude(x => x.Translations)
			.FirstOrDefaultAsync(x => x.Id == CheckListTemplateId.Create(id), cancellationToken);

		if (checkListTemplate is null)
		{
			return NotFound();
		}

		return Ok(CheckListTemplateModel.FromEntity(checkListTemplate));
	}
}

